5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2009 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using Microsoft.Win32.SafeHandles;
35 using System.Security.AccessControl;
36 using System.Security.Permissions;
37 using System.Security.Principal;
38 using System.Runtime.InteropServices;
40 namespace System.IO.Pipes
42 [PermissionSet (SecurityAction.InheritanceDemand, Name = "FullTrust")]
43 [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
44 public abstract class PipeStream : Stream
46 // FIXME: not precise.
47 internal const int DefaultBufferSize = 0x400;
50 internal static bool IsWindows {
51 get { return Win32Marshal.IsWindows; }
55 internal Exception ThrowACLException ()
57 return new NotImplementedException ("ACL is not supported in Mono");
61 internal static PipeAccessRights ToAccessRights (PipeDirection direction)
64 case PipeDirection.In:
65 return PipeAccessRights.ReadData;
66 case PipeDirection.Out:
67 return PipeAccessRights.WriteData;
68 case PipeDirection.InOut:
69 return PipeAccessRights.ReadData | PipeAccessRights.WriteData;
71 throw new ArgumentOutOfRangeException ();
75 internal static PipeDirection ToDirection (PipeAccessRights rights)
77 bool r = (rights & PipeAccessRights.ReadData) != 0;
78 bool w = (rights & PipeAccessRights.WriteData) != 0;
81 return PipeDirection.InOut;
83 return PipeDirection.In;
86 return PipeDirection.Out;
88 throw new ArgumentOutOfRangeException ();
93 protected PipeStream (PipeDirection direction, int bufferSize)
94 : this (direction, PipeTransmissionMode.Byte, bufferSize)
98 protected PipeStream (PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
100 this.direction = direction;
101 this.transmission_mode = transmissionMode;
102 read_trans_mode = transmissionMode;
103 if (outBufferSize <= 0)
104 throw new ArgumentOutOfRangeException ("bufferSize must be greater than 0");
105 buffer_size = outBufferSize;
108 PipeDirection direction;
109 PipeTransmissionMode transmission_mode, read_trans_mode;
111 SafePipeHandle handle;
114 public override bool CanRead {
115 get { return (direction & PipeDirection.In) != 0; }
118 public override bool CanSeek {
119 get { return false; }
122 public override bool CanWrite {
123 get { return (direction & PipeDirection.Out) != 0; }
126 public virtual int InBufferSize {
127 get { return buffer_size; }
130 public bool IsAsync { get; private set; }
132 public bool IsConnected { get; protected set; }
134 internal Stream Stream {
137 throw new InvalidOperationException ("Pipe is not connected");
139 stream = new FileStream (handle.DangerousGetHandle (),
140 CanRead ? (CanWrite ? FileAccess.ReadWrite : FileAccess.Read)
141 : FileAccess.Write, true, buffer_size, IsAsync);
144 set { stream = value; }
148 protected bool IsHandleExposed { get; private set; }
152 public bool IsMessageComplete { get; private set; }
155 public virtual int OutBufferSize {
156 get { return buffer_size; }
159 public virtual PipeTransmissionMode ReadMode {
161 CheckPipePropertyOperations ();
162 return read_trans_mode;
165 CheckPipePropertyOperations ();
166 read_trans_mode = value;
170 public SafePipeHandle SafePipeHandle {
172 CheckPipePropertyOperations ();
177 public virtual PipeTransmissionMode TransmissionMode {
179 CheckPipePropertyOperations ();
180 return transmission_mode;
184 // initialize/dispose/state check
186 internal static void CheckPipePropertyOperations ()
190 static void CheckReadOperations ()
194 static void CheckWriteOperations ()
199 protected internal virtual void CheckPipePropertyOperations ()
204 protected internal void CheckReadOperations ()
207 throw new InvalidOperationException ("Pipe is not connected");
209 throw new NotSupportedException ("The pipe stream does not support read operations");
213 protected internal void CheckWriteOperations ()
216 throw new InvalidOperationException ("Pipe is not connected");
218 throw new NotSupportedException ("The pipe stream does not support write operations");
221 protected void InitializeHandle (SafePipeHandle handle, bool isExposed, bool isAsync)
223 this.handle = handle;
224 this.IsHandleExposed = isExposed;
225 this.IsAsync = isAsync;
229 protected override void Dispose (bool disposing)
231 if (handle != null && disposing)
237 public override long Length {
238 get { throw new NotSupportedException (); }
241 public override long Position {
243 set { throw new NotSupportedException (); }
246 public override void SetLength (long value)
248 throw new NotSupportedException ();
251 public override long Seek (long offset, SeekOrigin origin)
253 throw new NotSupportedException ();
257 public PipeSecurity GetAccessControl ()
259 return new PipeSecurity (SafePipeHandle,
260 AccessControlSections.Owner |
261 AccessControlSections.Group |
262 AccessControlSections.Access);
265 public void SetAccessControl (PipeSecurity pipeSecurity)
267 if (pipeSecurity == null)
268 throw new ArgumentNullException ("pipeSecurity");
270 pipeSecurity.Persist (SafePipeHandle);
276 public void WaitForPipeDrain ()
281 public override int Read ([In] byte [] buffer, int offset, int count)
283 CheckReadOperations ();
285 return Stream.Read (buffer, offset, count);
289 public override int ReadByte ()
291 CheckReadOperations ();
293 return Stream.ReadByte ();
297 public override void Write (byte [] buffer, int offset, int count)
299 CheckWriteOperations ();
301 Stream.Write (buffer, offset, count);
305 public override void WriteByte (byte value)
307 CheckWriteOperations ();
309 Stream.WriteByte (value);
313 public override void Flush ()
315 CheckWriteOperations ();
323 Func<byte [],int,int,int> read_delegate;
325 [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
326 public override IAsyncResult BeginRead (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
328 if (read_delegate == null)
329 read_delegate = new Func<byte[],int,int,int> (Read);
330 return read_delegate.BeginInvoke (buffer, offset, count, callback, state);
333 Action<byte[],int,int> write_delegate;
335 [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
336 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback callback, object state)
338 if (write_delegate == null)
339 write_delegate = new Action<byte[],int,int> (Write);
340 return write_delegate.BeginInvoke (buffer, offset, count, callback, state);
343 public override int EndRead (IAsyncResult asyncResult)
345 return read_delegate.EndInvoke (asyncResult);
348 public override void EndWrite (IAsyncResult asyncResult)
350 write_delegate.EndInvoke (asyncResult);