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
;
39 namespace System
.IO
.Pipes
41 [PermissionSet (SecurityAction
.InheritanceDemand
, Name
= "FullTrust")]
42 [HostProtection (SecurityAction
.LinkDemand
, MayLeakOnAbort
= true)]
43 public abstract class PipeStream
: Stream
45 // FIXME: not precise.
46 internal const int DefaultBufferSize
= 0x400;
48 internal static bool IsWindows
{
49 get { return Win32Marshal.IsWindows; }
52 internal Exception
ThrowACLException ()
54 return new NotImplementedException ("ACL is not supported in Mono");
57 internal static PipeAccessRights
ToAccessRights (PipeDirection direction
)
60 case PipeDirection
.In
:
61 return PipeAccessRights
.ReadData
;
62 case PipeDirection
.Out
:
63 return PipeAccessRights
.WriteData
;
64 case PipeDirection
.InOut
:
65 return PipeAccessRights
.ReadData
| PipeAccessRights
.WriteData
;
67 throw new ArgumentOutOfRangeException ();
71 internal static PipeDirection
ToDirection (PipeAccessRights rights
)
73 bool r
= (rights
& PipeAccessRights
.ReadData
) != 0;
74 bool w
= (rights
& PipeAccessRights
.WriteData
) != 0;
77 return PipeDirection
.InOut
;
79 return PipeDirection
.In
;
82 return PipeDirection
.Out
;
84 throw new ArgumentOutOfRangeException ();
88 protected PipeStream (PipeDirection direction
, int bufferSize
)
89 : this (direction
, PipeTransmissionMode
.Byte
, bufferSize
)
93 protected PipeStream (PipeDirection direction
, PipeTransmissionMode transmissionMode
, int outBufferSize
)
95 this.direction
= direction
;
96 this.transmission_mode
= transmissionMode
;
97 read_trans_mode
= transmissionMode
;
98 if (outBufferSize
<= 0)
99 throw new ArgumentOutOfRangeException ("bufferSize must be greater than 0");
100 buffer_size
= outBufferSize
;
103 PipeDirection direction
;
104 PipeTransmissionMode transmission_mode
, read_trans_mode
;
106 SafePipeHandle handle
;
109 public override bool CanRead
{
110 get { return (direction & PipeDirection.In) != 0; }
113 public override bool CanSeek
{
114 get { return false; }
117 public override bool CanWrite
{
118 get { return (direction & PipeDirection.Out) != 0; }
121 public virtual int InBufferSize
{
122 get { return buffer_size; }
125 public bool IsAsync { get; private set; }
127 public bool IsConnected { get; protected set; }
129 internal Stream Stream
{
132 throw new InvalidOperationException ("Pipe is not connected");
134 stream
= new FileStream (handle
.DangerousGetHandle (), CanRead
? (CanWrite
? FileAccess
.ReadWrite
: FileAccess
.Read
) : FileAccess
.Write
, true, buffer_size
, IsAsync
);
137 set { stream = value; }
140 protected bool IsHandleExposed { get; private set; }
143 public bool IsMessageComplete { get; private set; }
146 public virtual int OutBufferSize
{
147 get { return buffer_size; }
150 public virtual PipeTransmissionMode ReadMode
{
152 CheckPipePropertyOperations ();
153 return read_trans_mode
;
156 CheckPipePropertyOperations ();
157 read_trans_mode
= value;
161 public SafePipeHandle SafePipeHandle
{
163 CheckPipePropertyOperations ();
168 public virtual PipeTransmissionMode TransmissionMode
{
170 CheckPipePropertyOperations ();
171 return transmission_mode
;
175 // initialize/dispose/state check
178 protected internal virtual void CheckPipePropertyOperations ()
183 protected internal void CheckReadOperations ()
186 throw new InvalidOperationException ("Pipe is not connected");
188 throw new NotSupportedException ("The pipe stream does not support read operations");
192 protected internal void CheckWriteOperations ()
195 throw new InvalidOperationException ("Pipe us not connected");
197 throw new NotSupportedException ("The pipe stream does not support write operations");
200 protected void InitializeHandle (SafePipeHandle handle
, bool isExposed
, bool isAsync
)
202 this.handle
= handle
;
203 this.IsHandleExposed
= isExposed
;
204 this.IsAsync
= isAsync
;
207 protected override void Dispose (bool disposing
)
209 if (handle
!= null && disposing
)
215 public override long Length
{
216 get { throw new NotSupportedException (); }
219 public override long Position
{
221 set { throw new NotSupportedException (); }
224 public override void SetLength (long value)
226 throw new NotSupportedException ();
229 public override long Seek (long offset
, SeekOrigin origin
)
231 throw new NotSupportedException ();
234 [MonoNotSupported ("ACL is not supported in Mono")]
235 public PipeSecurity
GetAccessControl ()
237 throw ThrowACLException ();
240 [MonoNotSupported ("ACL is not supported in Mono")]
241 public void SetAccessControl (PipeSecurity pipeSecurity
)
243 throw ThrowACLException ();
248 public void WaitForPipeDrain ()
253 public override int Read (byte [] buffer
, int offset
, int count
)
255 CheckReadOperations ();
257 return Stream
.Read (buffer
, offset
, count
);
261 public override int ReadByte ()
263 CheckReadOperations ();
265 return Stream
.ReadByte ();
269 public override void Write (byte [] buffer
, int offset
, int count
)
271 CheckWriteOperations ();
273 Stream
.Write (buffer
, offset
, count
);
277 public override void WriteByte (byte value)
279 CheckWriteOperations ();
281 Stream
.WriteByte (value);
285 public override void Flush ()
287 CheckWriteOperations ();
294 Func
<byte [],int,int,int> read_delegate
;
296 [HostProtection (SecurityAction
.LinkDemand
, ExternalThreading
= true)]
297 public override IAsyncResult
BeginRead (byte [] buffer
, int offset
, int count
, AsyncCallback callback
, object state
)
299 if (read_delegate
== null)
300 read_delegate
= new Func
<byte[],int,int,int> (Read
);
301 return read_delegate
.BeginInvoke (buffer
, offset
, count
, callback
, state
);
304 Action
<byte[],int,int> write_delegate
;
306 [HostProtection (SecurityAction
.LinkDemand
, ExternalThreading
= true)]
307 public override IAsyncResult
BeginWrite (byte[] buffer
, int offset
, int count
, AsyncCallback callback
, object state
)
309 if (write_delegate
== null)
310 write_delegate
= new Action
<byte[],int,int> (Write
);
311 return write_delegate
.BeginInvoke (buffer
, offset
, count
, callback
, state
);
314 public override int EndRead (IAsyncResult asyncResult
)
316 return read_delegate
.EndInvoke (asyncResult
);
319 public override void EndWrite (IAsyncResult asyncResult
)
321 write_delegate
.EndInvoke (asyncResult
);