mscorlib(4.0.0.0) API with additions
PipeStream.cs
1 using Microsoft.Win32;
2 using Microsoft.Win32.SafeHandles;
4 using System.Security;
7 using System.Threading;
8 
9 namespace System.IO.Pipes
10 {
12  [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
13  [HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
14  public abstract class PipeStream : Stream
15  {
16  private static readonly bool _canUseAsync;
17 
18  [SecurityCritical]
19  private static readonly IOCompletionCallback IOCallback;
20 
21  private SafePipeHandle m_handle;
22 
23  private bool m_canRead;
24 
25  private bool m_canWrite;
26 
27  private bool m_isAsync;
28 
29  private bool m_isMessageComplete;
30 
31  private bool m_isFromExistingHandle;
32 
33  private bool m_isHandleExposed;
34 
35  private PipeTransmissionMode m_readMode;
36 
37  private PipeTransmissionMode m_transmissionMode;
38 
39  private PipeDirection m_pipeDirection;
40 
41  private int m_outBufferSize;
42 
43  private PipeState m_state;
44 
48  public bool IsConnected
49  {
50  get
51  {
52  return State == PipeState.Connected;
53  }
54  protected set
55  {
56  m_state = (value ? PipeState.Connected : PipeState.Disconnected);
57  }
58  }
59 
63  public bool IsAsync => m_isAsync;
64 
70  public bool IsMessageComplete
71  {
72  [SecurityCritical]
73  get
74  {
75  if (m_state == PipeState.WaitingToConnect)
76  {
77  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeNotYetConnected"));
78  }
79  if (m_state == PipeState.Disconnected)
80  {
81  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeDisconnected"));
82  }
83  if (m_handle == null)
84  {
85  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeHandleNotSet"));
86  }
87  if (m_state == PipeState.Closed)
88  {
89  System.IO.__Error.PipeNotOpen();
90  }
91  if (m_handle.IsClosed)
92  {
93  System.IO.__Error.PipeNotOpen();
94  }
95  if (m_readMode != PipeTransmissionMode.Message)
96  {
97  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeReadModeNotMessage"));
98  }
99  return m_isMessageComplete;
100  }
101  }
102 
109  {
110  [SecurityCritical]
111  get
112  {
114  if (m_isFromExistingHandle)
115  {
116  if (!Microsoft.Win32.UnsafeNativeMethods.GetNamedPipeInfo(m_handle, out int lpFlags, Microsoft.Win32.UnsafeNativeMethods.NULL, Microsoft.Win32.UnsafeNativeMethods.NULL, Microsoft.Win32.UnsafeNativeMethods.NULL))
117  {
118  WinIOError(Marshal.GetLastWin32Error());
119  }
120  if ((lpFlags & 4) != 0)
121  {
122  return PipeTransmissionMode.Message;
123  }
124  return PipeTransmissionMode.Byte;
125  }
126  return m_transmissionMode;
127  }
128  }
129 
135  public virtual int InBufferSize
136  {
137  [SecurityCritical]
138  get
139  {
141  if (!CanRead)
142  {
143  throw new NotSupportedException(System.SR.GetString("NotSupported_UnreadableStream"));
144  }
145  if (!Microsoft.Win32.UnsafeNativeMethods.GetNamedPipeInfo(m_handle, Microsoft.Win32.UnsafeNativeMethods.NULL, Microsoft.Win32.UnsafeNativeMethods.NULL, out int lpInBufferSize, Microsoft.Win32.UnsafeNativeMethods.NULL))
146  {
147  WinIOError(Marshal.GetLastWin32Error());
148  }
149  return lpInBufferSize;
150  }
151  }
152 
158  public virtual int OutBufferSize
159  {
160  [SecurityCritical]
161  get
162  {
164  if (!CanWrite)
165  {
166  throw new NotSupportedException(System.SR.GetString("NotSupported_UnwritableStream"));
167  }
168  if (m_pipeDirection == PipeDirection.Out)
169  {
170  return m_outBufferSize;
171  }
172  if (!Microsoft.Win32.UnsafeNativeMethods.GetNamedPipeInfo(m_handle, Microsoft.Win32.UnsafeNativeMethods.NULL, out int lpOutBufferSize, Microsoft.Win32.UnsafeNativeMethods.NULL, Microsoft.Win32.UnsafeNativeMethods.NULL))
173  {
174  WinIOError(Marshal.GetLastWin32Error());
175  }
176  return lpOutBufferSize;
177  }
178  }
179 
186  public unsafe virtual PipeTransmissionMode ReadMode
187  {
188  [SecurityCritical]
189  get
190  {
192  if (m_isFromExistingHandle || IsHandleExposed)
193  {
194  UpdateReadMode();
195  }
196  return m_readMode;
197  }
198  [SecurityCritical]
199  set
200  {
202  if (value < PipeTransmissionMode.Byte || value > PipeTransmissionMode.Message)
203  {
204  throw new ArgumentOutOfRangeException("value", System.SR.GetString("ArgumentOutOfRange_TransmissionModeByteOrMsg"));
205  }
206  int num = (int)value << 1;
207  if (!Microsoft.Win32.UnsafeNativeMethods.SetNamedPipeHandleState(m_handle, &num, Microsoft.Win32.UnsafeNativeMethods.NULL, Microsoft.Win32.UnsafeNativeMethods.NULL))
208  {
209  WinIOError(Marshal.GetLastWin32Error());
210  }
211  else
212  {
213  m_readMode = value;
214  }
215  }
216  }
217 
223  {
224  [SecurityCritical]
225  get
226  {
227  if (m_handle == null)
228  {
229  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeHandleNotSet"));
230  }
231  if (m_handle.IsClosed)
232  {
233  System.IO.__Error.PipeNotOpen();
234  }
235  m_isHandleExposed = true;
236  return m_handle;
237  }
238  }
239 
240  internal SafePipeHandle InternalHandle
241  {
242  [SecurityCritical]
243  get
244  {
245  return m_handle;
246  }
247  }
248 
252  protected bool IsHandleExposed => m_isHandleExposed;
253 
257  public override bool CanRead => m_canRead;
258 
262  public override bool CanWrite => m_canWrite;
263 
267  public override bool CanSeek => false;
268 
272  public override long Length
273  {
274  get
275  {
276  System.IO.__Error.SeekNotSupported();
277  return 0L;
278  }
279  }
280 
284  public override long Position
285  {
286  get
287  {
288  System.IO.__Error.SeekNotSupported();
289  return 0L;
290  }
291  set
292  {
293  System.IO.__Error.SeekNotSupported();
294  }
295  }
296 
297  internal PipeState State
298  {
299  get
300  {
301  return m_state;
302  }
303  set
304  {
305  m_state = value;
306  }
307  }
308 
309  [SecurityCritical]
310  static unsafe PipeStream()
311  {
312  _canUseAsync = (Environment.OSVersion.Platform == PlatformID.Win32NT);
313  IOCallback = AsyncPSCallback;
314  }
315 
322  protected PipeStream(PipeDirection direction, int bufferSize)
323  {
324  if (direction < PipeDirection.In || direction > PipeDirection.InOut)
325  {
326  throw new ArgumentOutOfRangeException("direction", System.SR.GetString("ArgumentOutOfRange_DirectionModeInOutOrInOut"));
327  }
328  if (bufferSize < 0)
329  {
330  throw new ArgumentOutOfRangeException("bufferSize", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
331  }
332  Init(direction, PipeTransmissionMode.Byte, bufferSize);
333  }
334 
343  protected PipeStream(PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
344  {
345  if (direction < PipeDirection.In || direction > PipeDirection.InOut)
346  {
347  throw new ArgumentOutOfRangeException("direction", System.SR.GetString("ArgumentOutOfRange_DirectionModeInOutOrInOut"));
348  }
349  if (transmissionMode < PipeTransmissionMode.Byte || transmissionMode > PipeTransmissionMode.Message)
350  {
351  throw new ArgumentOutOfRangeException("transmissionMode", System.SR.GetString("ArgumentOutOfRange_TransmissionModeByteOrMsg"));
352  }
353  if (outBufferSize < 0)
354  {
355  throw new ArgumentOutOfRangeException("outBufferSize", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
356  }
357  Init(direction, transmissionMode, outBufferSize);
358  }
359 
360  private void Init(PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
361  {
362  m_readMode = transmissionMode;
363  m_transmissionMode = transmissionMode;
364  m_pipeDirection = direction;
365  if ((m_pipeDirection & PipeDirection.In) != 0)
366  {
367  m_canRead = true;
368  }
369  if ((m_pipeDirection & PipeDirection.Out) != 0)
370  {
371  m_canWrite = true;
372  }
373  m_outBufferSize = outBufferSize;
374  m_isMessageComplete = true;
375  m_state = PipeState.WaitingToConnect;
376  }
377 
385  [SecurityCritical]
386  protected void InitializeHandle(SafePipeHandle handle, bool isExposed, bool isAsync)
387  {
388  isAsync &= _canUseAsync;
389  if (isAsync)
390  {
391  bool flag = false;
392  new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
393  try
394  {
395  flag = ThreadPool.BindHandle(handle);
396  }
397  finally
398  {
400  }
401  if (!flag)
402  {
403  throw new IOException(System.SR.GetString("IO_IO_BindHandleFailed"));
404  }
405  }
406  m_handle = handle;
407  m_isAsync = isAsync;
408  m_isHandleExposed = isExposed;
409  m_isFromExistingHandle = isExposed;
410  }
411 
428  [SecurityCritical]
429  public override int Read([In] [Out] byte[] buffer, int offset, int count)
430  {
431  if (buffer == null)
432  {
433  throw new ArgumentNullException("buffer", System.SR.GetString("ArgumentNull_Buffer"));
434  }
435  if (offset < 0)
436  {
437  throw new ArgumentOutOfRangeException("offset", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
438  }
439  if (count < 0)
440  {
441  throw new ArgumentOutOfRangeException("count", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
442  }
443  if (buffer.Length - offset < count)
444  {
445  throw new ArgumentException(System.SR.GetString("Argument_InvalidOffLen"));
446  }
447  if (!CanRead)
448  {
449  System.IO.__Error.ReadNotSupported();
450  }
452  return ReadCore(buffer, offset, count);
453  }
454 
455  [SecurityCritical]
456  private int ReadCore(byte[] buffer, int offset, int count)
457  {
458  if (m_isAsync)
459  {
460  IAsyncResult asyncResult = BeginReadCore(buffer, offset, count, null, null);
461  return EndRead(asyncResult);
462  }
463  int hr = 0;
464  int num = ReadFileNative(m_handle, buffer, offset, count, null, out hr);
465  if (num == -1)
466  {
467  if (hr == 109 || hr == 233)
468  {
469  State = PipeState.Broken;
470  num = 0;
471  }
472  else
473  {
474  System.IO.__Error.WinIOError(hr, string.Empty);
475  }
476  }
477  m_isMessageComplete = (hr != 234);
478  return num;
479  }
480 
499  [SecurityCritical]
500  [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
501  public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
502  {
503  if (buffer == null)
504  {
505  throw new ArgumentNullException("buffer", System.SR.GetString("ArgumentNull_Buffer"));
506  }
507  if (offset < 0)
508  {
509  throw new ArgumentOutOfRangeException("offset", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
510  }
511  if (count < 0)
512  {
513  throw new ArgumentOutOfRangeException("count", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
514  }
515  if (buffer.Length - offset < count)
516  {
517  throw new ArgumentException(System.SR.GetString("Argument_InvalidOffLen"));
518  }
519  if (!CanRead)
520  {
521  System.IO.__Error.ReadNotSupported();
522  }
524  if (!m_isAsync)
525  {
526  if (m_state == PipeState.Broken)
527  {
528  PipeStreamAsyncResult pipeStreamAsyncResult = new PipeStreamAsyncResult();
529  pipeStreamAsyncResult._handle = m_handle;
530  pipeStreamAsyncResult._userCallback = callback;
531  pipeStreamAsyncResult._userStateObject = state;
532  pipeStreamAsyncResult._isWrite = false;
533  pipeStreamAsyncResult.CallUserCallback();
534  return pipeStreamAsyncResult;
535  }
536  return base.BeginRead(buffer, offset, count, callback, state);
537  }
538  return BeginReadCore(buffer, offset, count, callback, state);
539  }
540 
541  [SecurityCritical]
542  private unsafe PipeStreamAsyncResult BeginReadCore(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
543  {
544  PipeStreamAsyncResult pipeStreamAsyncResult = new PipeStreamAsyncResult();
545  pipeStreamAsyncResult._handle = m_handle;
546  pipeStreamAsyncResult._userCallback = callback;
547  pipeStreamAsyncResult._userStateObject = state;
548  pipeStreamAsyncResult._isWrite = false;
549  if (buffer.Length == 0)
550  {
551  pipeStreamAsyncResult.CallUserCallback();
552  }
553  else
554  {
555  ManualResetEvent manualResetEvent = pipeStreamAsyncResult._waitHandle = new ManualResetEvent(initialState: false);
556  Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, pipeStreamAsyncResult);
557  NativeOverlapped* ptr = pipeStreamAsyncResult._overlapped = overlapped.Pack(IOCallback, buffer);
558  int hr = 0;
559  int num = ReadFileNative(m_handle, buffer, offset, count, ptr, out hr);
560  if (num == -1)
561  {
562  switch (hr)
563  {
564  case 109:
565  case 233:
566  State = PipeState.Broken;
567  ptr->InternalLow = IntPtr.Zero;
568  pipeStreamAsyncResult.CallUserCallback();
569  break;
570  default:
571  System.IO.__Error.WinIOError(hr, string.Empty);
572  break;
573  case 997:
574  break;
575  }
576  }
577  }
578  return pipeStreamAsyncResult;
579  }
580 
589  [SecurityCritical]
590  public unsafe override int EndRead(IAsyncResult asyncResult)
591  {
592  if (asyncResult == null)
593  {
594  throw new ArgumentNullException("asyncResult");
595  }
596  if (!m_isAsync)
597  {
598  return base.EndRead(asyncResult);
599  }
600  PipeStreamAsyncResult pipeStreamAsyncResult = asyncResult as PipeStreamAsyncResult;
601  if (pipeStreamAsyncResult == null || pipeStreamAsyncResult._isWrite)
602  {
603  System.IO.__Error.WrongAsyncResult();
604  }
605  if (1 == Interlocked.CompareExchange(ref pipeStreamAsyncResult._EndXxxCalled, 1, 0))
606  {
607  System.IO.__Error.EndReadCalledTwice();
608  }
609  WaitHandle waitHandle = pipeStreamAsyncResult._waitHandle;
610  if (waitHandle != null)
611  {
612  try
613  {
614  waitHandle.WaitOne();
615  }
616  finally
617  {
618  waitHandle.Close();
619  }
620  }
621  NativeOverlapped* overlapped = pipeStreamAsyncResult._overlapped;
622  if (overlapped != null)
623  {
624  Overlapped.Free(overlapped);
625  }
626  if (pipeStreamAsyncResult._errorCode != 0)
627  {
628  WinIOError(pipeStreamAsyncResult._errorCode);
629  }
630  m_isMessageComplete = (m_state == PipeState.Broken || pipeStreamAsyncResult._isMessageComplete);
631  return pipeStreamAsyncResult._numBytes;
632  }
633 
648  [SecurityCritical]
649  public override void Write(byte[] buffer, int offset, int count)
650  {
651  if (buffer == null)
652  {
653  throw new ArgumentNullException("buffer", System.SR.GetString("ArgumentNull_Buffer"));
654  }
655  if (offset < 0)
656  {
657  throw new ArgumentOutOfRangeException("offset", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
658  }
659  if (count < 0)
660  {
661  throw new ArgumentOutOfRangeException("count", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
662  }
663  if (buffer.Length - offset < count)
664  {
665  throw new ArgumentException(System.SR.GetString("Argument_InvalidOffLen"));
666  }
667  if (!CanWrite)
668  {
669  System.IO.__Error.WriteNotSupported();
670  }
672  WriteCore(buffer, offset, count);
673  }
674 
675  [SecurityCritical]
676  private void WriteCore(byte[] buffer, int offset, int count)
677  {
678  if (m_isAsync)
679  {
680  IAsyncResult asyncResult = BeginWriteCore(buffer, offset, count, null, null);
681  EndWrite(asyncResult);
682  return;
683  }
684  int hr = 0;
685  int num = WriteFileNative(m_handle, buffer, offset, count, null, out hr);
686  if (num == -1)
687  {
688  WinIOError(hr);
689  }
690  }
691 
710  [SecurityCritical]
711  [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
712  public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
713  {
714  if (buffer == null)
715  {
716  throw new ArgumentNullException("buffer", System.SR.GetString("ArgumentNull_Buffer"));
717  }
718  if (offset < 0)
719  {
720  throw new ArgumentOutOfRangeException("offset", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
721  }
722  if (count < 0)
723  {
724  throw new ArgumentOutOfRangeException("count", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
725  }
726  if (buffer.Length - offset < count)
727  {
728  throw new ArgumentException(System.SR.GetString("Argument_InvalidOffLen"));
729  }
730  if (!CanWrite)
731  {
732  System.IO.__Error.WriteNotSupported();
733  }
735  if (!m_isAsync)
736  {
737  return base.BeginWrite(buffer, offset, count, callback, state);
738  }
739  return BeginWriteCore(buffer, offset, count, callback, state);
740  }
741 
742  [SecurityCritical]
743  private unsafe PipeStreamAsyncResult BeginWriteCore(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
744  {
745  PipeStreamAsyncResult pipeStreamAsyncResult = new PipeStreamAsyncResult();
746  pipeStreamAsyncResult._userCallback = callback;
747  pipeStreamAsyncResult._userStateObject = state;
748  pipeStreamAsyncResult._isWrite = true;
749  pipeStreamAsyncResult._handle = m_handle;
750  if (buffer.Length == 0)
751  {
752  pipeStreamAsyncResult.CallUserCallback();
753  }
754  else
755  {
756  ManualResetEvent manualResetEvent = pipeStreamAsyncResult._waitHandle = new ManualResetEvent(initialState: false);
757  Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, pipeStreamAsyncResult);
758  NativeOverlapped* ptr = pipeStreamAsyncResult._overlapped = overlapped.Pack(IOCallback, buffer);
759  int hr = 0;
760  int num = WriteFileNative(m_handle, buffer, offset, count, ptr, out hr);
761  if (num == -1 && hr != 997)
762  {
763  if (ptr != null)
764  {
765  Overlapped.Free(ptr);
766  }
767  WinIOError(hr);
768  }
769  }
770  return pipeStreamAsyncResult;
771  }
772 
780  [SecurityCritical]
781  public unsafe override void EndWrite(IAsyncResult asyncResult)
782  {
783  if (asyncResult == null)
784  {
785  throw new ArgumentNullException("asyncResult");
786  }
787  if (!m_isAsync)
788  {
789  base.EndWrite(asyncResult);
790  return;
791  }
792  PipeStreamAsyncResult pipeStreamAsyncResult = asyncResult as PipeStreamAsyncResult;
793  if (pipeStreamAsyncResult == null || !pipeStreamAsyncResult._isWrite)
794  {
795  System.IO.__Error.WrongAsyncResult();
796  }
797  if (1 == Interlocked.CompareExchange(ref pipeStreamAsyncResult._EndXxxCalled, 1, 0))
798  {
799  System.IO.__Error.EndWriteCalledTwice();
800  }
801  WaitHandle waitHandle = pipeStreamAsyncResult._waitHandle;
802  if (waitHandle != null)
803  {
804  try
805  {
806  waitHandle.WaitOne();
807  }
808  finally
809  {
810  waitHandle.Close();
811  }
812  }
813  NativeOverlapped* overlapped = pipeStreamAsyncResult._overlapped;
814  if (overlapped != null)
815  {
816  Overlapped.Free(overlapped);
817  }
818  if (pipeStreamAsyncResult._errorCode != 0)
819  {
820  WinIOError(pipeStreamAsyncResult._errorCode);
821  }
822  }
823 
824  [SecurityCritical]
825  private unsafe int ReadFileNative(SafePipeHandle handle, byte[] buffer, int offset, int count, NativeOverlapped* overlapped, out int hr)
826  {
827  if (buffer.Length == 0)
828  {
829  hr = 0;
830  return 0;
831  }
832  int num = 0;
833  int numBytesRead = 0;
834  fixed (byte* ptr = buffer)
835  {
836  num = ((!m_isAsync) ? Microsoft.Win32.UnsafeNativeMethods.ReadFile(handle, ptr + offset, count, out numBytesRead, IntPtr.Zero) : Microsoft.Win32.UnsafeNativeMethods.ReadFile(handle, ptr + offset, count, IntPtr.Zero, overlapped));
837  }
838  if (num == 0)
839  {
840  hr = Marshal.GetLastWin32Error();
841  if (hr == 234)
842  {
843  return numBytesRead;
844  }
845  return -1;
846  }
847  hr = 0;
848  return numBytesRead;
849  }
850 
851  [SecurityCritical]
852  private unsafe int WriteFileNative(SafePipeHandle handle, byte[] buffer, int offset, int count, NativeOverlapped* overlapped, out int hr)
853  {
854  if (buffer.Length == 0)
855  {
856  hr = 0;
857  return 0;
858  }
859  int numBytesWritten = 0;
860  int num = 0;
861  fixed (byte* ptr = buffer)
862  {
863  num = ((!m_isAsync) ? Microsoft.Win32.UnsafeNativeMethods.WriteFile(handle, ptr + offset, count, out numBytesWritten, IntPtr.Zero) : Microsoft.Win32.UnsafeNativeMethods.WriteFile(handle, ptr + offset, count, IntPtr.Zero, overlapped));
864  }
865  if (num == 0)
866  {
867  hr = Marshal.GetLastWin32Error();
868  return -1;
869  }
870  hr = 0;
871  return numBytesWritten;
872  }
873 
880  [SecurityCritical]
881  public override int ReadByte()
882  {
884  if (!CanRead)
885  {
886  System.IO.__Error.ReadNotSupported();
887  }
888  byte[] array = new byte[1];
889  if (ReadCore(array, 0, 1) == 0)
890  {
891  return -1;
892  }
893  return array[0];
894  }
895 
902  [SecurityCritical]
903  public override void WriteByte(byte value)
904  {
906  if (!CanWrite)
907  {
908  System.IO.__Error.WriteNotSupported();
909  }
910  WriteCore(new byte[1]
911  {
912  value
913  }, 0, 1);
914  }
915 
920  [SecurityCritical]
921  public override void Flush()
922  {
924  if (!CanWrite)
925  {
926  System.IO.__Error.WriteNotSupported();
927  }
928  }
929 
934  [SecurityCritical]
935  public void WaitForPipeDrain()
936  {
938  if (!CanWrite)
939  {
940  System.IO.__Error.WriteNotSupported();
941  }
942  if (!Microsoft.Win32.UnsafeNativeMethods.FlushFileBuffers(m_handle))
943  {
944  WinIOError(Marshal.GetLastWin32Error());
945  }
946  }
947 
951  [SecurityCritical]
952  protected override void Dispose(bool disposing)
953  {
954  try
955  {
956  if (m_handle != null && !m_handle.IsClosed)
957  {
958  m_handle.Dispose();
959  }
960  }
961  finally
962  {
963  base.Dispose(disposing);
964  }
965  m_state = PipeState.Closed;
966  }
967 
968  [SecurityCritical]
969  private void UpdateReadMode()
970  {
971  if (!Microsoft.Win32.UnsafeNativeMethods.GetNamedPipeHandleState(SafePipeHandle, out int lpState, Microsoft.Win32.UnsafeNativeMethods.NULL, Microsoft.Win32.UnsafeNativeMethods.NULL, Microsoft.Win32.UnsafeNativeMethods.NULL, Microsoft.Win32.UnsafeNativeMethods.NULL, 0))
972  {
973  WinIOError(Marshal.GetLastWin32Error());
974  }
975  if ((lpState & 2) != 0)
976  {
977  m_readMode = PipeTransmissionMode.Message;
978  }
979  else
980  {
981  m_readMode = PipeTransmissionMode.Byte;
982  }
983  }
984 
991  [SecurityCritical]
993  {
994  if (m_state == PipeState.Closed)
995  {
996  System.IO.__Error.PipeNotOpen();
997  }
998  if (m_handle == null)
999  {
1000  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeHandleNotSet"));
1001  }
1002  if (m_handle.IsClosed)
1003  {
1004  System.IO.__Error.PipeNotOpen();
1005  }
1006  return new PipeSecurity(m_handle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
1007  }
1008 
1017  [SecurityCritical]
1018  public void SetAccessControl(PipeSecurity pipeSecurity)
1019  {
1020  if (pipeSecurity == null)
1021  {
1022  throw new ArgumentNullException("pipeSecurity");
1023  }
1025  pipeSecurity.Persist(m_handle);
1026  }
1027 
1030  public override void SetLength(long value)
1031  {
1032  System.IO.__Error.SeekNotSupported();
1033  }
1034 
1039  public override long Seek(long offset, SeekOrigin origin)
1040  {
1041  System.IO.__Error.SeekNotSupported();
1042  return 0L;
1043  }
1044 
1046  [SecurityCritical]
1047  protected internal virtual void CheckPipePropertyOperations()
1048  {
1049  if (m_handle == null)
1050  {
1051  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeHandleNotSet"));
1052  }
1053  if (m_state == PipeState.Closed)
1054  {
1055  System.IO.__Error.PipeNotOpen();
1056  }
1057  if (m_handle.IsClosed)
1058  {
1059  System.IO.__Error.PipeNotOpen();
1060  }
1061  }
1062 
1064  [SecurityCritical]
1065  protected internal void CheckReadOperations()
1066  {
1067  if (m_state == PipeState.WaitingToConnect)
1068  {
1069  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeNotYetConnected"));
1070  }
1071  if (m_state == PipeState.Disconnected)
1072  {
1073  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeDisconnected"));
1074  }
1075  if (m_handle == null)
1076  {
1077  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeHandleNotSet"));
1078  }
1079  if (m_state == PipeState.Closed)
1080  {
1081  System.IO.__Error.PipeNotOpen();
1082  }
1083  if (m_handle.IsClosed)
1084  {
1085  System.IO.__Error.PipeNotOpen();
1086  }
1087  }
1088 
1090  [SecurityCritical]
1091  protected internal void CheckWriteOperations()
1092  {
1093  if (m_state == PipeState.WaitingToConnect)
1094  {
1095  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeNotYetConnected"));
1096  }
1097  if (m_state == PipeState.Disconnected)
1098  {
1099  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeDisconnected"));
1100  }
1101  if (m_handle == null)
1102  {
1103  throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeHandleNotSet"));
1104  }
1105  if (m_state == PipeState.Broken)
1106  {
1107  throw new IOException(System.SR.GetString("IO_IO_PipeBroken"));
1108  }
1109  if (m_state == PipeState.Closed)
1110  {
1111  System.IO.__Error.PipeNotOpen();
1112  }
1113  if (m_handle.IsClosed)
1114  {
1115  System.IO.__Error.PipeNotOpen();
1116  }
1117  }
1118 
1119  [SecurityCritical]
1120  internal void WinIOError(int errorCode)
1121  {
1122  switch (errorCode)
1123  {
1124  case 109:
1125  case 232:
1126  case 233:
1127  m_state = PipeState.Broken;
1128  throw new IOException(System.SR.GetString("IO_IO_PipeBroken"), Microsoft.Win32.UnsafeNativeMethods.MakeHRFromErrorCode(errorCode));
1129  case 38:
1130  System.IO.__Error.EndOfFile();
1131  return;
1132  case 6:
1133  m_handle.SetHandleAsInvalid();
1134  m_state = PipeState.Broken;
1135  break;
1136  }
1137  System.IO.__Error.WinIOError(errorCode, string.Empty);
1138  }
1139 
1140  [SecurityCritical]
1141  internal unsafe static Microsoft.Win32.UnsafeNativeMethods.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability, PipeSecurity pipeSecurity, out object pinningHandle)
1142  {
1143  pinningHandle = null;
1144  Microsoft.Win32.UnsafeNativeMethods.SECURITY_ATTRIBUTES sECURITY_ATTRIBUTES = null;
1145  if ((inheritability & HandleInheritability.Inheritable) != 0 || pipeSecurity != null)
1146  {
1147  sECURITY_ATTRIBUTES = new Microsoft.Win32.UnsafeNativeMethods.SECURITY_ATTRIBUTES();
1148  sECURITY_ATTRIBUTES.nLength = Marshal.SizeOf((object)sECURITY_ATTRIBUTES);
1149  if ((inheritability & HandleInheritability.Inheritable) != 0)
1150  {
1151  sECURITY_ATTRIBUTES.bInheritHandle = 1;
1152  }
1153  if (pipeSecurity != null)
1154  {
1155  byte[] securityDescriptorBinaryForm = pipeSecurity.GetSecurityDescriptorBinaryForm();
1156  pinningHandle = GCHandle.Alloc(securityDescriptorBinaryForm, GCHandleType.Pinned);
1157  byte[] array = securityDescriptorBinaryForm;
1158  fixed (byte* pSecurityDescriptor = array)
1159  {
1160  sECURITY_ATTRIBUTES.pSecurityDescriptor = pSecurityDescriptor;
1161  }
1162  }
1163  }
1164  return sECURITY_ATTRIBUTES;
1165  }
1166 
1167  [SecurityCritical]
1168  internal static Microsoft.Win32.UnsafeNativeMethods.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability)
1169  {
1170  Microsoft.Win32.UnsafeNativeMethods.SECURITY_ATTRIBUTES sECURITY_ATTRIBUTES = null;
1171  if ((inheritability & HandleInheritability.Inheritable) != 0)
1172  {
1173  sECURITY_ATTRIBUTES = new Microsoft.Win32.UnsafeNativeMethods.SECURITY_ATTRIBUTES();
1174  sECURITY_ATTRIBUTES.nLength = Marshal.SizeOf((object)sECURITY_ATTRIBUTES);
1175  sECURITY_ATTRIBUTES.bInheritHandle = 1;
1176  }
1177  return sECURITY_ATTRIBUTES;
1178  }
1179 
1180  [SecurityCritical]
1181  private unsafe static void AsyncPSCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped)
1182  {
1183  Overlapped overlapped = Overlapped.Unpack(pOverlapped);
1184  PipeStreamAsyncResult pipeStreamAsyncResult = (PipeStreamAsyncResult)overlapped.AsyncResult;
1185  pipeStreamAsyncResult._numBytes = (int)numBytes;
1186  if (!pipeStreamAsyncResult._isWrite && (errorCode == 109 || errorCode == 233 || errorCode == 232))
1187  {
1188  errorCode = 0u;
1189  numBytes = 0u;
1190  }
1191  if (errorCode == 234)
1192  {
1193  errorCode = 0u;
1194  pipeStreamAsyncResult._isMessageComplete = false;
1195  }
1196  else
1197  {
1198  pipeStreamAsyncResult._isMessageComplete = true;
1199  }
1200  pipeStreamAsyncResult._errorCode = (int)errorCode;
1201  pipeStreamAsyncResult._completedSynchronously = false;
1202  pipeStreamAsyncResult._isComplete = true;
1203  ManualResetEvent waitHandle = pipeStreamAsyncResult._waitHandle;
1204  if (waitHandle != null && !waitHandle.Set())
1205  {
1206  System.IO.__Error.WinIOError();
1207  }
1208  pipeStreamAsyncResult._userCallback?.Invoke(pipeStreamAsyncResult);
1209  }
1210  }
1211 }
override void WriteByte(byte value)
Writes a byte to the current stream.
Definition: PipeStream.cs:903
PlatformID
Identifies the operating system, or platform, supported by an assembly.
Definition: PlatformID.cs:8
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
unsafe override int EndRead(IAsyncResult asyncResult)
Ends a pending asynchronous read request.
Definition: PipeStream.cs:590
Describes a set of security permissions applied to code. This class cannot be inherited.
override bool CanRead
Gets a value indicating whether the current stream supports read operations.
Definition: PipeStream.cs:257
override int Read([In] [Out] byte[] buffer, int offset, int count)
Reads a block of bytes from a stream and writes the data to a specified buffer.
Definition: PipeStream.cs:429
void SetAccessControl(PipeSecurity pipeSecurity)
Applies the access control list (ACL) entries specified by a T:System.IO.Pipes.PipeSecurity object to...
Definition: PipeStream.cs:1018
Encapsulates operating system–specific objects that wait for exclusive access to shared resources.
Definition: WaitHandle.cs:15
unsafe NativeOverlapped * Pack(IOCompletionCallback iocb)
Packs the current instance into a T:System.Threading.NativeOverlapped structure, specifying the deleg...
Definition: Overlapped.cs:137
PipeSecurity GetAccessControl()
Gets a T:System.IO.Pipes.PipeSecurity object that encapsulates the access control list (ACL) entries ...
Definition: PipeStream.cs:992
virtual PipeTransmissionMode TransmissionMode
Gets the pipe transmission mode supported by the current pipe.
Definition: PipeStream.cs:109
bool Set()
Sets the state of the event to signaled, allowing one or more waiting threads to proceed.
static unsafe Overlapped Unpack(NativeOverlapped *nativeOverlappedPtr)
Unpacks the specified unmanaged T:System.Threading.NativeOverlapped structure into a managed T:System...
Definition: Overlapped.cs:188
Definition: __Canon.cs:3
IntPtr InternalLow
Specifies a system-dependent status. Reserved for operating system use.
override void Flush()
Clears the buffer for the current stream and causes any buffered data to be written to the underlying...
Definition: PipeStream.cs:921
The exception that is thrown when the value of an argument is outside the allowable range of values a...
static int SizeOf(object structure)
Returns the unmanaged size of an object in bytes.
Definition: Marshal.cs:159
delegate void AsyncCallback(IAsyncResult ar)
References a method to be called when a corresponding asynchronous operation completes.
Provides a managed representation of a Win32 OVERLAPPED structure, including methods to transfer info...
Definition: Overlapped.cs:8
override void Write(byte[] buffer, int offset, int count)
Writes a block of bytes to the current stream using data from a buffer.
Definition: PipeStream.cs:649
bool IsHandleExposed
Gets a value indicating whether a handle to a T:System.IO.Pipes.PipeStream object is exposed.
Definition: PipeStream.cs:252
void InitializeHandle(SafePipeHandle handle, bool isExposed, bool isAsync)
Initializes a T:System.IO.Pipes.PipeStream object from the specified T:Microsoft.Win32....
Definition: PipeStream.cs:386
static unsafe void Free(NativeOverlapped *nativeOverlappedPtr)
Frees the unmanaged memory associated with a native overlapped structure allocated by the Overload:Sy...
Definition: Overlapped.cs:203
HandleInheritability
Specifies whether the underlying handle is inheritable by child processes.
unsafe delegate void IOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pOVERLAP)
Receives the error code, number of bytes, and overlapped value type when an I/O operation completes o...
PipeTransmissionMode
Specifies the transmission mode of the pipe.
virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
Blocks the current thread until the current T:System.Threading.WaitHandle receives a signal,...
Definition: WaitHandle.cs:162
override long Seek(long offset, SeekOrigin origin)
Sets the current position of the current stream to the specified value.
Definition: PipeStream.cs:1039
override bool CanSeek
Gets a value indicating whether the current stream supports seek operations.
Definition: PipeStream.cs:267
SeekOrigin
Specifies the position in a stream to use for seeking.
Definition: SeekOrigin.cs:9
internal void Persist(SafeHandle handle)
Saves the specified sections of the security descriptor that is associated with the current T:System....
bool IsAsync
Gets a value indicating whether a T:System.IO.Pipes.PipeStream object was opened asynchronously or sy...
Definition: PipeStream.cs:63
SecurityAction
Specifies the security actions that can be performed using declarative security.
internal void CheckWriteOperations()
Verifies that the pipe is in a connected state for write operations.
Definition: PipeStream.cs:1091
virtual int InBufferSize
Gets the size, in bytes, of the inbound buffer for a pipe.
Definition: PipeStream.cs:136
Represents the status of an asynchronous operation.
Definition: IAsyncResult.cs:9
Exposes a T:System.IO.Stream object around a pipe, which supports both anonymous and named pipes.
Definition: PipeStream.cs:14
Represents a collection that can contain many different types of permissions.
Specifies that the pipe direction is out.
static int CompareExchange(ref int location1, int value, int comparand)
Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.
override long Position
Gets or sets the current position of the current stream.
Definition: PipeStream.cs:285
PipeStream(PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
Initializes a new instance of the T:System.IO.Pipes.PipeStream class using the specified T:System....
Definition: PipeStream.cs:343
unsafe override void EndWrite(IAsyncResult asyncResult)
Ends a pending asynchronous write request.
Definition: PipeStream.cs:781
The exception that is thrown when an I/O error occurs.
Definition: IOException.cs:10
override long Length
Gets the length of a stream, in bytes.
Definition: PipeStream.cs:273
Defines the underlying structure of all code access permissions.
A platform-specific type that is used to represent a pointer or a handle.
Definition: IntPtr.cs:14
Notifies one or more waiting threads that an event has occurred. This class cannot be inherited.
IAsyncResult AsyncResult
Gets or sets the object that provides status information on the I/O operation.
Definition: Overlapped.cs:17
Definition: SR.cs:7
static GCHandle Alloc(object value)
Allocates a F:System.Runtime.InteropServices.GCHandleType.Normal handle for the specified object.
Definition: GCHandle.cs:98
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Definition: Marshal.cs:15
GCHandleType
Represents the types of handles the T:System.Runtime.InteropServices.GCHandle class can allocate.
Definition: GCHandleType.cs:7
internal void CheckReadOperations()
Verifies that the pipe is in a connected state for read operations.
Definition: PipeStream.cs:1065
Provides a way to access a managed object from unmanaged memory.
Definition: GCHandle.cs:10
virtual unsafe PipeTransmissionMode ReadMode
Gets or sets the reading mode for a T:System.IO.Pipes.PipeStream object.
Definition: PipeStream.cs:187
override void SetLength(long value)
Sets the length of the current stream to the specified value.
Definition: PipeStream.cs:1030
virtual void Close()
Releases all resources held by the current T:System.Threading.WaitHandle.
Definition: WaitHandle.cs:714
static void RevertAssert()
Causes any previous M:System.Security.CodeAccessPermission.Assert for the current frame to be removed...
PipeStream(PipeDirection direction, int bufferSize)
Initializes a new instance of the T:System.IO.Pipes.PipeStream class using the specified T:System....
Definition: PipeStream.cs:322
The exception that is thrown when one of the arguments provided to a method is not valid.
override bool CanWrite
Gets a value indicating whether the current stream supports write operations.
Definition: PipeStream.cs:262
Specifies that the pipe direction is in.
bool? IsConnected
Gets or sets a value indicating whether a T:System.IO.Pipes.PipeStream object is connected.
Definition: PipeStream.cs:49
static bool BindHandle(IntPtr osHandle)
Binds an operating system handle to the T:System.Threading.ThreadPool.
Definition: ThreadPool.cs:551
override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
Begins an asynchronous read operation.
Definition: PipeStream.cs:501
override int ReadByte()
Reads a byte from a pipe.
Definition: PipeStream.cs:881
virtual internal void CheckPipePropertyOperations()
Verifies that the pipe is in a proper state for getting or setting properties.
Definition: PipeStream.cs:1047
Represents the access control and audit security for a pipe.
Definition: PipeSecurity.cs:12
static readonly IntPtr Zero
A read-only field that represents a pointer or handle that has been initialized to zero.
Definition: IntPtr.cs:20
override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
Begins an asynchronous write operation.
Definition: PipeStream.cs:712
PipeDirection
Specifies the direction of the pipe.
Definition: PipeDirection.cs:5
The exception that is thrown when a method call is invalid for the object's current state.
bool IsMessageComplete
Gets a value indicating whether there is more data in the message returned from the most recent read ...
Definition: PipeStream.cs:71
void WaitForPipeDrain()
Waits for the other end of the pipe to read all sent bytes.
Definition: PipeStream.cs:935
void Assert()
Declares that the calling code can access the resource protected by a permission demand through the c...
The exception that is thrown when an invoked method is not supported, or when there is an attempt to ...
static int GetLastWin32Error()
Returns the error code returned by the last unmanaged function that was called using platform invoke ...
SecurityPermissionFlag
Specifies access flags for the security permission object.
AccessControlSections
Specifies which sections of a security descriptor to save or load.
Provides atomic operations for variables that are shared by multiple threads.
Definition: Interlocked.cs:10
override void Dispose(bool disposing)
Releases the unmanaged resources used by the T:System.IO.Pipes.PipeStream class and optionally releas...
Definition: PipeStream.cs:952
SafePipeHandle SafePipeHandle
Gets the safe handle for the local end of the pipe that the current T:System.IO.Pipes....
Definition: PipeStream.cs:223
virtual int OutBufferSize
Gets the size, in bytes, of the outbound buffer for a pipe.
Definition: PipeStream.cs:159
Provides an explicit layout that is visible from unmanaged code and that will have the same layout as...
Provides a pool of threads that can be used to execute tasks, post work items, process asynchronous I...
Definition: ThreadPool.cs:14
Provides a generic view of a sequence of bytes. This is an abstract class.To browse the ....
Definition: Stream.cs:16