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");
60 internal static PipeAccessRights ToAccessRights (PipeDirection direction)
63 case PipeDirection.In:
64 return PipeAccessRights.ReadData;
65 case PipeDirection.Out:
66 return PipeAccessRights.WriteData;
67 case PipeDirection.InOut:
68 return PipeAccessRights.ReadData | PipeAccessRights.WriteData;
70 throw new ArgumentOutOfRangeException ();
74 internal static PipeDirection ToDirection (PipeAccessRights rights)
76 bool r = (rights & PipeAccessRights.ReadData) != 0;
77 bool w = (rights & PipeAccessRights.WriteData) != 0;
80 return PipeDirection.InOut;
82 return PipeDirection.In;
85 return PipeDirection.Out;
87 throw new ArgumentOutOfRangeException ();
91 protected PipeStream (PipeDirection direction, int bufferSize)
92 : this (direction, PipeTransmissionMode.Byte, bufferSize)
96 protected PipeStream (PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
98 this.direction = direction;
99 this.transmission_mode = transmissionMode;
100 read_trans_mode = transmissionMode;
101 if (outBufferSize <= 0)
102 throw new ArgumentOutOfRangeException ("bufferSize must be greater than 0");
103 buffer_size = outBufferSize;
106 PipeDirection direction;
107 PipeTransmissionMode transmission_mode, read_trans_mode;
109 SafePipeHandle handle;
112 public override bool CanRead {
113 get { return (direction & PipeDirection.In) != 0; }
116 public override bool CanSeek {
117 get { return false; }
120 public override bool CanWrite {
121 get { return (direction & PipeDirection.Out) != 0; }
124 public virtual int InBufferSize {
125 get { return buffer_size; }
128 public bool IsAsync { get; private set; }
130 public bool IsConnected { get; protected set; }
132 internal Stream Stream {
135 throw new InvalidOperationException ("Pipe is not connected");
137 stream = new FileStream (handle.DangerousGetHandle (),
138 CanRead ? (CanWrite ? FileAccess.ReadWrite : FileAccess.Read)
139 : FileAccess.Write, true, buffer_size, IsAsync);
142 set { stream = value; }
145 protected bool IsHandleExposed { get; private set; }
148 public bool IsMessageComplete { get; private set; }
151 public virtual int OutBufferSize {
152 get { return buffer_size; }
155 public virtual PipeTransmissionMode ReadMode {
157 CheckPipePropertyOperations ();
158 return read_trans_mode;
161 CheckPipePropertyOperations ();
162 read_trans_mode = value;
166 public SafePipeHandle SafePipeHandle {
168 CheckPipePropertyOperations ();
173 public virtual PipeTransmissionMode TransmissionMode {
175 CheckPipePropertyOperations ();
176 return transmission_mode;
180 // initialize/dispose/state check
183 protected internal virtual void CheckPipePropertyOperations ()
188 protected internal void CheckReadOperations ()
191 throw new InvalidOperationException ("Pipe is not connected");
193 throw new NotSupportedException ("The pipe stream does not support read operations");
197 protected internal void CheckWriteOperations ()
200 throw new InvalidOperationException ("Pipe is not connected");
202 throw new NotSupportedException ("The pipe stream does not support write operations");
205 protected void InitializeHandle (SafePipeHandle handle, bool isExposed, bool isAsync)
207 this.handle = handle;
208 this.IsHandleExposed = isExposed;
209 this.IsAsync = isAsync;
212 protected override void Dispose (bool disposing)
214 if (handle != null && disposing)
220 public override long Length {
221 get { throw new NotSupportedException (); }
224 public override long Position {
226 set { throw new NotSupportedException (); }
229 public override void SetLength (long value)
231 throw new NotSupportedException ();
234 public override long Seek (long offset, SeekOrigin origin)
236 throw new NotSupportedException ();
239 public PipeSecurity GetAccessControl ()
242 throw new PlatformNotSupportedException ();
244 return new PipeSecurity (SafePipeHandle,
245 AccessControlSections.Owner |
246 AccessControlSections.Group |
247 AccessControlSections.Access);
251 public void SetAccessControl (PipeSecurity pipeSecurity)
254 throw new PlatformNotSupportedException ();
256 if (pipeSecurity == null)
257 throw new ArgumentNullException ("pipeSecurity");
259 pipeSecurity.Persist (SafePipeHandle);
265 public void WaitForPipeDrain ()
270 public override int Read ([In] byte [] buffer, int offset, int count)
272 CheckReadOperations ();
274 return Stream.Read (buffer, offset, count);
278 public override int ReadByte ()
280 CheckReadOperations ();
282 return Stream.ReadByte ();
286 public override void Write (byte [] buffer, int offset, int count)
288 CheckWriteOperations ();
290 Stream.Write (buffer, offset, count);
294 public override void WriteByte (byte value)
296 CheckWriteOperations ();
298 Stream.WriteByte (value);
302 public override void Flush ()
304 CheckWriteOperations ();
311 Func<byte [],int,int,int> read_delegate;
313 [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
314 public override IAsyncResult BeginRead (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
316 if (read_delegate == null)
317 read_delegate = new Func<byte[],int,int,int> (Read);
318 return read_delegate.BeginInvoke (buffer, offset, count, callback, state);
321 Action<byte[],int,int> write_delegate;
323 [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
324 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback callback, object state)
326 if (write_delegate == null)
327 write_delegate = new Action<byte[],int,int> (Write);
328 return write_delegate.BeginInvoke (buffer, offset, count, callback, state);
331 public override int EndRead (IAsyncResult asyncResult)
333 return read_delegate.EndInvoke (asyncResult);
336 public override void EndWrite (IAsyncResult asyncResult)
338 write_delegate.EndInvoke (asyncResult);