Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
//
// AnonymousPipeClientStream.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !BOOTSTRAP_BASIC
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
using Microsoft.Win32.SafeHandles;
namespace System.IO.Pipes
{
[MonoTODO ("Anonymous pipes are not working even on win32, due to some access authorization issue")]
[HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public sealed class AnonymousPipeClientStream : PipeStream
{
static SafePipeHandle ToSafePipeHandle (string pipeHandleAsString)
{
if (pipeHandleAsString == null)
throw new ArgumentNullException ("pipeHandleAsString");
// We use int64 for safety
return new SafePipeHandle (new IntPtr (long.Parse (pipeHandleAsString, NumberFormatInfo.InvariantInfo)), false);
}
//IAnonymousPipeClient impl;
public AnonymousPipeClientStream (string pipeHandleAsString)
: this (PipeDirection.In, pipeHandleAsString)
{
}
public AnonymousPipeClientStream (PipeDirection direction, string pipeHandleAsString)
: this (direction, ToSafePipeHandle (pipeHandleAsString))
{
}
public AnonymousPipeClientStream (PipeDirection direction,SafePipeHandle safePipeHandle)
: base (direction, DefaultBufferSize)
{
/*
if (IsWindows)
impl = new Win32AnonymousPipeClient (this, safePipeHandle);
else
impl = new UnixAnonymousPipeClient (this, safePipeHandle);
*/
InitializeHandle (safePipeHandle, false, false);
IsConnected = true;
}
~AnonymousPipeClientStream ()
{
// To be compatible with .net
}
public override PipeTransmissionMode ReadMode {
set {
if (value == PipeTransmissionMode.Message)
throw new NotSupportedException ();
}
}
public override PipeTransmissionMode TransmissionMode {
get { return PipeTransmissionMode.Byte; }
}
}
}
#endif

View File

@@ -0,0 +1,134 @@
//
// AnonymousPipeServerStream.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !BOOTSTRAP_BASIC
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
using Microsoft.Win32.SafeHandles;
namespace System.IO.Pipes
{
[MonoTODO ("Anonymous pipes are not working even on win32, due to some access authorization issue")]
[HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public sealed class AnonymousPipeServerStream : PipeStream
{
public AnonymousPipeServerStream ()
: this (PipeDirection.Out)
{
}
public AnonymousPipeServerStream (PipeDirection direction)
: this (direction, HandleInheritability.None)
{
}
public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability)
: this (direction, inheritability, DefaultBufferSize)
{
}
public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability, int bufferSize)
: this (direction, inheritability, bufferSize, null)
{
}
public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity pipeSecurity)
: base (direction, bufferSize)
{
if (direction == PipeDirection.InOut)
throw new NotSupportedException ("Anonymous pipe direction can only be either in or out.");
if (IsWindows)
impl = new Win32AnonymousPipeServer (this, direction, inheritability, bufferSize, pipeSecurity);
else
impl = new UnixAnonymousPipeServer (this, direction, inheritability, bufferSize);
InitializeHandle (impl.Handle, false, false);
IsConnected = true;
}
[MonoTODO]
public AnonymousPipeServerStream (PipeDirection direction, SafePipeHandle serverSafePipeHandle, SafePipeHandle clientSafePipeHandle)
: base (direction, DefaultBufferSize)
{
if (serverSafePipeHandle == null)
throw new ArgumentNullException ("serverSafePipeHandle");
if (clientSafePipeHandle == null)
throw new ArgumentNullException ("clientSafePipeHandle");
if (direction == PipeDirection.InOut)
throw new NotSupportedException ("Anonymous pipe direction can only be either in or out.");
if (IsWindows)
impl = new Win32AnonymousPipeServer (this, serverSafePipeHandle, clientSafePipeHandle);
else
impl = new UnixAnonymousPipeServer (this, serverSafePipeHandle, clientSafePipeHandle);
InitializeHandle (serverSafePipeHandle, true, false);
IsConnected = true;
ClientSafePipeHandle = clientSafePipeHandle;
}
IAnonymousPipeServer impl;
[MonoTODO]
public SafePipeHandle ClientSafePipeHandle { get; private set; }
public override PipeTransmissionMode ReadMode {
set {
if (value == PipeTransmissionMode.Message)
throw new NotSupportedException ();
}
}
public override PipeTransmissionMode TransmissionMode {
get { return PipeTransmissionMode.Byte; }
}
[MonoTODO]
public void DisposeLocalCopyOfClientHandle ()
{
impl.DisposeLocalCopyOfClientHandle ();
}
public string GetClientHandleAsString ()
{
// We use int64 for safety.
return impl.Handle.DangerousGetHandle ().ToInt64 ().ToString (NumberFormatInfo.InvariantInfo);
}
}
}
#endif

View File

@@ -0,0 +1,14 @@
2009-08-27 Atsushi Enomoto <atsushi@ximian.com>
* PipeStream.cs : add set_Stream.
* PipeUnix.cs : some impl. code (not really functional).
2009-08-18 Atsushi Enomoto <atsushi@ximian.com>
* AnonymousPipeClientStream.cs, AnonymousPipeServerStream.cs,
NamedPipeClientStream.cs, NamedPipeServerStream.cs
PipeAccessRights.cs, PipeAccessRule.cs, PipeAuditRule.cs,
PipeDirection.cs, PipeInterfaces.cs, PipeOptions.cs,
PipeSecurity.cs, PipeStream.cs, PipeStreamImpersonationWorker.cs,
PipeTransmissionMode.cs, PipeUnix.cs, PipeWin32.cs :
initial implementation, so far with win32 impl.

View File

@@ -0,0 +1,128 @@
//
// NamedPipeClientStream.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !BOOTSTRAP_BASIC
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
namespace System.IO.Pipes
{
[MonoTODO ("working only on win32 right now")]
[HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public sealed class NamedPipeClientStream : PipeStream
{
public NamedPipeClientStream (string pipeName)
: this (".", pipeName)
{
}
public NamedPipeClientStream (string serverName, string pipeName)
: this (serverName, pipeName, PipeDirection.InOut)
{
}
public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction)
: this (serverName, pipeName, direction, PipeOptions.None)
{
}
public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options)
: this (serverName, pipeName, direction, options, TokenImpersonationLevel.None)
{
}
public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel)
: this (serverName, pipeName, direction, options, impersonationLevel, HandleInheritability.None)
{
}
public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability)
: this (serverName, pipeName, ToAccessRights (direction), options, impersonationLevel, inheritability)
{
}
public NamedPipeClientStream (PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
: base (direction, DefaultBufferSize)
{
if (IsWindows)
impl = new Win32NamedPipeClient (this, safePipeHandle);
else
impl = new UnixNamedPipeClient (this, safePipeHandle);
IsConnected = isConnected;
InitializeHandle (safePipeHandle, true, isAsync);
}
public NamedPipeClientStream (string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability)
: base (ToDirection (desiredAccessRights), DefaultBufferSize)
{
if (impersonationLevel != TokenImpersonationLevel.None ||
inheritability != HandleInheritability.None)
throw ThrowACLException ();
if (IsWindows)
impl = new Win32NamedPipeClient (this, serverName, pipeName, desiredAccessRights, options, inheritability);
else
impl = new UnixNamedPipeClient (this, serverName, pipeName, desiredAccessRights, options, inheritability);
}
INamedPipeClient impl;
public void Connect ()
{
impl.Connect ();
InitializeHandle (impl.Handle, false, impl.IsAsync);
IsConnected = true;
}
public void Connect (int timeout)
{
impl.Connect (timeout);
InitializeHandle (impl.Handle, false, impl.IsAsync);
IsConnected = true;
}
public int NumberOfServerInstances {
get {
CheckPipePropertyOperations ();
return impl.NumberOfServerInstances;
}
}
}
}
#endif

View File

@@ -0,0 +1,162 @@
//
// NamedPipeServerStream.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !BOOTSTRAP_BASIC
using Microsoft.Win32.SafeHandles;
using System;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
namespace System.IO.Pipes
{
[MonoTODO ("working only on win32 right now")]
[HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public sealed class NamedPipeServerStream : PipeStream
{
public const int MaxAllowedServerInstances = -1;
public NamedPipeServerStream (string pipeName)
: this (pipeName, PipeDirection.InOut)
{
}
public NamedPipeServerStream (string pipeName, PipeDirection direction)
: this (pipeName, direction, 1)
{
}
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances)
: this (pipeName, direction, maxNumberOfServerInstances, PipeTransmissionMode.Byte)
{
}
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode)
: this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, PipeOptions.None)
{
}
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options)
: this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, DefaultBufferSize, DefaultBufferSize)
{
}
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize)
: this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, null)
{
}
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity)
: this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, HandleInheritability.None)
{
}
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability)
: this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, inheritability, PipeAccessRights.ReadData | PipeAccessRights.WriteData)
{
}
[MonoTODO]
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights)
: base (direction, transmissionMode, outBufferSize)
{
var rights = ToAccessRights (direction) | additionalAccessRights;
// FIXME: reject some rights declarations (for ACL).
if (IsWindows)
impl = new Win32NamedPipeServer (this, pipeName, maxNumberOfServerInstances, transmissionMode,
rights, options, inBufferSize, outBufferSize,
pipeSecurity, inheritability);
else
impl = new UnixNamedPipeServer (this, pipeName, maxNumberOfServerInstances, transmissionMode,
rights, options, inBufferSize, outBufferSize, inheritability);
InitializeHandle (impl.Handle, false, (options & PipeOptions.Asynchronous) != PipeOptions.None);
}
public NamedPipeServerStream (PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
: base (direction, DefaultBufferSize)
{
if (IsWindows)
impl = new Win32NamedPipeServer (this, safePipeHandle);
else
impl = new UnixNamedPipeServer (this, safePipeHandle);
IsConnected = isConnected;
InitializeHandle (safePipeHandle, true, isAsync);
}
INamedPipeServer impl;
public void Disconnect ()
{
impl.Disconnect ();
}
[MonoTODO]
[SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal)]
public void RunAsClient (PipeStreamImpersonationWorker impersonationWorker)
{
throw new NotImplementedException ();
}
public void WaitForConnection ()
{
impl.WaitForConnection ();
IsConnected = true;
}
[MonoTODO]
[SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal)]
public string GetImpersonationUserName ()
{
throw new NotImplementedException ();
}
// async operations
Action wait_connect_delegate;
[HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
public IAsyncResult BeginWaitForConnection (AsyncCallback callback, object state)
{
if (wait_connect_delegate == null)
wait_connect_delegate = new Action (WaitForConnection);
return wait_connect_delegate.BeginInvoke (callback, state);
}
public void EndWaitForConnection (IAsyncResult asyncResult)
{
wait_connect_delegate.EndInvoke (asyncResult);
}
}
}
#endif

View File

@@ -0,0 +1,55 @@
//
// PipeAccessRights.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright 2011 Xamarin Inc (http://www.xamarin.com).
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
namespace System.IO.Pipes
{
[Flags]
public enum PipeAccessRights
{
ReadData = 1,
WriteData = 1 << 1,
CreateNewInstance = 1 << 2,
ReadExtendedAttributes = 1 << 3,
WriteExtendedAttributes = 1 << 4,
ReadAttributes = 1 << 7,
WriteAttributes = 1 << 8,
Delete = 1 << 16,
ReadPermissions = 1 << 17,
ChangePermissions = 1 << 18,
TakeOwnership = 1 << 19,
Synchronize = 1 << 20,
AccessSystemSecurity = 1 << 24,
Read = ReadData | ReadAttributes | ReadExtendedAttributes | ReadPermissions,
Write = WriteData | WriteAttributes | WriteExtendedAttributes,
ReadWrite = Read | Write,
FullControl = ReadWrite | CreateNewInstance | Delete | ChangePermissions | TakeOwnership | Synchronize
}
}

View File

@@ -0,0 +1,55 @@
//
// PipeAccessRule.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
namespace System.IO.Pipes
{
[HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public sealed class PipeAccessRule : AccessRule
{
public PipeAccessRule (IdentityReference identity, PipeAccessRights rights, AccessControlType type)
: base (identity, (int)rights, false, InheritanceFlags.None, PropagationFlags.None, type)
{
}
public PipeAccessRule (string identity, PipeAccessRights rights, AccessControlType type)
: this (new NTAccount (identity), rights, type)
{
}
public PipeAccessRights PipeAccessRights {
get { return (PipeAccessRights)AccessMask; }
}
}
}

View File

@@ -0,0 +1,55 @@
//
// PipeAuditRule.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
namespace System.IO.Pipes
{
[HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public sealed class PipeAuditRule : AuditRule
{
public PipeAuditRule (IdentityReference identity, PipeAccessRights rights, AuditFlags flags)
: base (identity, (int)rights, false, InheritanceFlags.None, PropagationFlags.None, flags)
{
}
public PipeAuditRule (string identity, PipeAccessRights rights, AuditFlags flags)
: this (new NTAccount (identity), rights, flags)
{
}
public PipeAccessRights PipeAccessRights {
get { return (PipeAccessRights)AccessMask; }
}
}
}

View File

@@ -0,0 +1,10 @@
namespace System.IO.Pipes
{
[Serializable]
public enum PipeDirection
{
In = 1,
Out = 2,
InOut = 3
}
}

View File

@@ -0,0 +1,36 @@
using Microsoft.Win32.SafeHandles;
namespace System.IO.Pipes
{
// Common interfaces
interface IPipe
{
SafePipeHandle Handle { get; }
void WaitForPipeDrain ();
}
interface IAnonymousPipeClient : IPipe
{
}
interface IAnonymousPipeServer : IPipe
{
SafePipeHandle ClientHandle { get; }
void DisposeLocalCopyOfClientHandle ();
}
interface INamedPipeClient : IPipe
{
void Connect ();
void Connect (int timeout);
int NumberOfServerInstances { get; }
bool IsAsync { get; }
}
interface INamedPipeServer : IPipe
{
void Disconnect ();
void WaitForConnection ();
}
}

View File

@@ -0,0 +1,38 @@
//
// PipeAccessRights.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright 2011 Xamarin Inc (http://www.xamarin.com).
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
namespace System.IO.Pipes
{
[Flags]
public enum PipeOptions
{
None = 0,
WriteThrough = int.MinValue,
Asynchronous = 1 << 30
}
}

View File

@@ -0,0 +1,163 @@
//
// PipeSecurity.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
// James Bellinger <jfb@zer7.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
// Copyright (C) 2012 James Bellinger
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
namespace System.IO.Pipes
{
[HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public class PipeSecurity : NativeObjectSecurity
{
public PipeSecurity ()
: base (false, ResourceType.FileObject)
{
}
internal PipeSecurity (SafeHandle handle, AccessControlSections includeSections)
: base (false, ResourceType.FileObject, handle, includeSections)
{
}
public override Type AccessRightType {
get { return typeof (PipeAccessRights); }
}
public override Type AccessRuleType {
get { return typeof (PipeAccessRule); }
}
public override Type AuditRuleType {
get { return typeof (PipeAuditRule); }
}
public override AccessRule AccessRuleFactory (IdentityReference identityReference,
int accessMask, bool isInherited,
InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags,
AccessControlType type)
{
return new PipeAccessRule (identityReference, (PipeAccessRights)accessMask, type);
}
public void AddAccessRule (PipeAccessRule rule)
{
AddAccessRule ((AccessRule)rule);
}
public void AddAuditRule (PipeAuditRule rule)
{
AddAuditRule ((AuditRule) rule);
}
public override sealed AuditRule AuditRuleFactory (IdentityReference identityReference,
int accessMask, bool isInherited,
InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags,
AuditFlags flags)
{
return new PipeAuditRule (identityReference, (PipeAccessRights)accessMask, flags);
}
[SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
protected internal void Persist (SafeHandle handle)
{
WriteLock();
try {
Persist (handle, AccessControlSectionsModified, null);
} finally {
WriteUnlock ();
}
}
[SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
protected internal void Persist (string name)
{
WriteLock();
try {
Persist (name, AccessControlSectionsModified, null);
} finally {
WriteUnlock ();
}
}
#if BOOTSTRAP_BASIC
AccessControlSections AccessControlSectionsModified {
get {
return (AccessRulesModified ? AccessControlSections.Access : 0) |
(AuditRulesModified ? AccessControlSections.Audit : 0) |
(OwnerModified ? AccessControlSections.Owner : 0) |
(GroupModified ? AccessControlSections.Group : 0);
}
}
#endif
public bool RemoveAccessRule (PipeAccessRule rule)
{
return RemoveAccessRule ((AccessRule)rule);
}
public void RemoveAccessRuleSpecific (PipeAccessRule rule)
{
RemoveAccessRuleSpecific ((AccessRule)rule);
}
public bool RemoveAuditRule (PipeAuditRule rule)
{
return RemoveAuditRule ((AuditRule)rule);
}
public void RemoveAuditRuleAll (PipeAuditRule rule)
{
RemoveAuditRuleAll ((AuditRule)rule);
}
public void RemoveAuditRuleSpecific (PipeAuditRule rule)
{
RemoveAuditRuleSpecific ((AuditRule)rule);
}
public void ResetAccessRule (PipeAccessRule rule)
{
ResetAccessRule ((AccessRule)rule);
}
public void SetAccessRule (PipeAccessRule rule)
{
SetAccessRule ((AccessRule)rule);
}
public void SetAuditRule (PipeAuditRule rule)
{
SetAuditRule ((AuditRule)rule);
}
}
}

View File

@@ -0,0 +1,333 @@
//
// PipeStream.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !BOOTSTRAP_BASIC
using Microsoft.Win32.SafeHandles;
using System;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
using System.Runtime.InteropServices;
namespace System.IO.Pipes
{
[PermissionSet (SecurityAction.InheritanceDemand, Name = "FullTrust")]
[HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public abstract class PipeStream : Stream
{
// FIXME: not precise.
internal const int DefaultBufferSize = 0x400;
internal static bool IsWindows {
get { return Win32Marshal.IsWindows; }
}
internal Exception ThrowACLException ()
{
return new NotImplementedException ("ACL is not supported in Mono");
}
internal static PipeAccessRights ToAccessRights (PipeDirection direction)
{
switch (direction) {
case PipeDirection.In:
return PipeAccessRights.ReadData;
case PipeDirection.Out:
return PipeAccessRights.WriteData;
case PipeDirection.InOut:
return PipeAccessRights.ReadData | PipeAccessRights.WriteData;
default:
throw new ArgumentOutOfRangeException ();
}
}
internal static PipeDirection ToDirection (PipeAccessRights rights)
{
bool r = (rights & PipeAccessRights.ReadData) != 0;
bool w = (rights & PipeAccessRights.WriteData) != 0;
if (r) {
if (w)
return PipeDirection.InOut;
else
return PipeDirection.In;
} else {
if (w)
return PipeDirection.Out;
else
throw new ArgumentOutOfRangeException ();
}
}
protected PipeStream (PipeDirection direction, int bufferSize)
: this (direction, PipeTransmissionMode.Byte, bufferSize)
{
}
protected PipeStream (PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
{
this.direction = direction;
this.transmission_mode = transmissionMode;
read_trans_mode = transmissionMode;
if (outBufferSize <= 0)
throw new ArgumentOutOfRangeException ("bufferSize must be greater than 0");
buffer_size = outBufferSize;
}
PipeDirection direction;
PipeTransmissionMode transmission_mode, read_trans_mode;
int buffer_size;
SafePipeHandle handle;
Stream stream;
public override bool CanRead {
get { return (direction & PipeDirection.In) != 0; }
}
public override bool CanSeek {
get { return false; }
}
public override bool CanWrite {
get { return (direction & PipeDirection.Out) != 0; }
}
public virtual int InBufferSize {
get { return buffer_size; }
}
public bool IsAsync { get; private set; }
public bool IsConnected { get; protected set; }
internal Stream Stream {
get {
if (!IsConnected)
throw new InvalidOperationException ("Pipe is not connected");
if (stream == null)
stream = new FileStream (handle.DangerousGetHandle (),
CanRead ? (CanWrite ? FileAccess.ReadWrite : FileAccess.Read)
: FileAccess.Write, true, buffer_size, IsAsync);
return stream;
}
set { stream = value; }
}
protected bool IsHandleExposed { get; private set; }
[MonoTODO]
public bool IsMessageComplete { get; private set; }
[MonoTODO]
public virtual int OutBufferSize {
get { return buffer_size; }
}
public virtual PipeTransmissionMode ReadMode {
get {
CheckPipePropertyOperations ();
return read_trans_mode;
}
set {
CheckPipePropertyOperations ();
read_trans_mode = value;
}
}
public SafePipeHandle SafePipeHandle {
get {
CheckPipePropertyOperations ();
return handle;
}
}
public virtual PipeTransmissionMode TransmissionMode {
get {
CheckPipePropertyOperations ();
return transmission_mode;
}
}
// initialize/dispose/state check
[MonoTODO]
protected internal virtual void CheckPipePropertyOperations ()
{
}
[MonoTODO]
protected internal void CheckReadOperations ()
{
if (!IsConnected)
throw new InvalidOperationException ("Pipe is not connected");
if (!CanRead)
throw new NotSupportedException ("The pipe stream does not support read operations");
}
[MonoTODO]
protected internal void CheckWriteOperations ()
{
if (!IsConnected)
throw new InvalidOperationException ("Pipe is not connected");
if (!CanWrite)
throw new NotSupportedException ("The pipe stream does not support write operations");
}
protected void InitializeHandle (SafePipeHandle handle, bool isExposed, bool isAsync)
{
this.handle = handle;
this.IsHandleExposed = isExposed;
this.IsAsync = isAsync;
}
protected override void Dispose (bool disposing)
{
if (handle != null && disposing)
handle.Dispose ();
}
// not supported
public override long Length {
get { throw new NotSupportedException (); }
}
public override long Position {
get { return 0; }
set { throw new NotSupportedException (); }
}
public override void SetLength (long value)
{
throw new NotSupportedException ();
}
public override long Seek (long offset, SeekOrigin origin)
{
throw new NotSupportedException ();
}
public PipeSecurity GetAccessControl ()
{
return new PipeSecurity (SafePipeHandle,
AccessControlSections.Owner |
AccessControlSections.Group |
AccessControlSections.Access);
}
public void SetAccessControl (PipeSecurity pipeSecurity)
{
if (pipeSecurity == null)
throw new ArgumentNullException ("pipeSecurity");
pipeSecurity.Persist (SafePipeHandle);
}
// pipe I/O
public void WaitForPipeDrain ()
{
}
[MonoTODO]
public override int Read ([In] byte [] buffer, int offset, int count)
{
CheckReadOperations ();
return Stream.Read (buffer, offset, count);
}
[MonoTODO]
public override int ReadByte ()
{
CheckReadOperations ();
return Stream.ReadByte ();
}
[MonoTODO]
public override void Write (byte [] buffer, int offset, int count)
{
CheckWriteOperations ();
Stream.Write (buffer, offset, count);
}
[MonoTODO]
public override void WriteByte (byte value)
{
CheckWriteOperations ();
Stream.WriteByte (value);
}
[MonoTODO]
public override void Flush ()
{
CheckWriteOperations ();
Stream.Flush ();
}
// async
Func<byte [],int,int,int> read_delegate;
[HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
public override IAsyncResult BeginRead (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
{
if (read_delegate == null)
read_delegate = new Func<byte[],int,int,int> (Read);
return read_delegate.BeginInvoke (buffer, offset, count, callback, state);
}
Action<byte[],int,int> write_delegate;
[HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
if (write_delegate == null)
write_delegate = new Action<byte[],int,int> (Write);
return write_delegate.BeginInvoke (buffer, offset, count, callback, state);
}
public override int EndRead (IAsyncResult asyncResult)
{
return read_delegate.EndInvoke (asyncResult);
}
public override void EndWrite (IAsyncResult asyncResult)
{
write_delegate.EndInvoke (asyncResult);
}
}
}
#endif

View File

@@ -0,0 +1,4 @@
namespace System.IO.Pipes
{
public delegate void PipeStreamImpersonationWorker ();
}

View File

@@ -0,0 +1,9 @@
namespace System.IO.Pipes
{
[Serializable]
public enum PipeTransmissionMode
{
Byte,
Message
}
}

View File

@@ -0,0 +1,299 @@
//
// PipeUnix.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !BOOTSTRAP_BASIC
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Threading;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using Mono.Unix.Native;
namespace System.IO.Pipes
{
abstract class UnixAnonymousPipe : IPipe
{
protected UnixAnonymousPipe ()
{
}
public abstract SafePipeHandle Handle { get; }
public void WaitForPipeDrain ()
{
throw new NotImplementedException ();
}
}
class UnixAnonymousPipeClient : UnixAnonymousPipe, IAnonymousPipeClient
{
// AnonymousPipeClientStream owner;
public UnixAnonymousPipeClient (AnonymousPipeClientStream owner, SafePipeHandle handle)
{
// this.owner = owner;
this.handle = handle;
}
SafePipeHandle handle;
public override SafePipeHandle Handle {
get { return handle; }
}
}
class UnixAnonymousPipeServer : UnixAnonymousPipe, IAnonymousPipeServer
{
// AnonymousPipeServerStream owner;
public UnixAnonymousPipeServer (AnonymousPipeServerStream owner, PipeDirection direction, HandleInheritability inheritability, int bufferSize)
{
// this.owner = owner;
throw new NotImplementedException ();
}
public UnixAnonymousPipeServer (AnonymousPipeServerStream owner, SafePipeHandle serverHandle, SafePipeHandle clientHandle)
{
// this.owner = owner;
this.server_handle = serverHandle;
this.client_handle = clientHandle;
throw new NotImplementedException ();
}
SafePipeHandle server_handle, client_handle;
public override SafePipeHandle Handle {
get { return server_handle; }
}
public SafePipeHandle ClientHandle {
get { return client_handle; }
}
public void DisposeLocalCopyOfClientHandle ()
{
throw new NotImplementedException ();
}
}
abstract class UnixNamedPipe : IPipe
{
public abstract SafePipeHandle Handle { get; }
public void WaitForPipeDrain ()
{
throw new NotImplementedException ();
}
public void EnsureTargetFile (string name)
{
if (!File.Exists (name)) {
var error = Syscall.mknod (name, FilePermissions.S_IFIFO | FilePermissions.ALLPERMS, 0);
if (error != 0)
throw new IOException (String.Format ("Error on creating named pipe: error code {0}", error));
}
}
protected void ValidateOptions (PipeOptions options, PipeTransmissionMode mode)
{
if ((options & PipeOptions.WriteThrough) != 0)
throw new NotImplementedException ("WriteThrough is not supported");
if ((mode & PipeTransmissionMode.Message) != 0)
throw new NotImplementedException ("Message transmission mode is not supported");
if ((options & PipeOptions.Asynchronous) != 0) // FIXME: use O_NONBLOCK?
throw new NotImplementedException ("Asynchronous pipe mode is not supported");
}
protected string RightsToAccess (PipeAccessRights rights)
{
string access = null;
if ((rights & PipeAccessRights.ReadData) != 0) {
if ((rights & PipeAccessRights.WriteData) != 0)
access = "r+";
else
access = "r";
}
else if ((rights & PipeAccessRights.WriteData) != 0)
access = "w";
else
throw new InvalidOperationException ("The pipe must be opened to either read or write");
return access;
}
protected FileAccess RightsToFileAccess (PipeAccessRights rights)
{
if ((rights & PipeAccessRights.ReadData) != 0) {
if ((rights & PipeAccessRights.WriteData) != 0)
return FileAccess.ReadWrite;
else
return FileAccess.Read;
}
else if ((rights & PipeAccessRights.WriteData) != 0)
return FileAccess.Write;
else
throw new InvalidOperationException ("The pipe must be opened to either read or write");
}
}
class UnixNamedPipeClient : UnixNamedPipe, INamedPipeClient
{
// .ctor with existing handle
public UnixNamedPipeClient (NamedPipeClientStream owner, SafePipeHandle safePipeHandle)
{
this.owner = owner;
this.handle = safePipeHandle;
// FIXME: dunno how is_async could be filled.
}
// .ctor without handle - create new
public UnixNamedPipeClient (NamedPipeClientStream owner, string serverName, string pipeName,
PipeAccessRights desiredAccessRights, PipeOptions options, HandleInheritability inheritability)
{
this.owner = owner;
if (serverName != "." && !Dns.GetHostEntry (serverName).AddressList.Contains (IPAddress.Loopback))
throw new NotImplementedException ("Unix fifo does not support remote server connection");
var name = Path.Combine ("/var/tmp/", pipeName);
EnsureTargetFile (name);
RightsToAccess (desiredAccessRights);
ValidateOptions (options, owner.TransmissionMode);
// FIXME: handle inheritability
opener = delegate {
var fs = new FileStream (name, FileMode.Open, RightsToFileAccess (desiredAccessRights), FileShare.ReadWrite);
owner.Stream = fs;
handle = new SafePipeHandle (fs.Handle, false);
};
}
NamedPipeClientStream owner;
SafePipeHandle handle;
Action opener;
public override SafePipeHandle Handle {
get { return handle; }
}
public void Connect ()
{
if (owner.IsConnected)
throw new InvalidOperationException ("The named pipe is already connected");
opener ();
}
public void Connect (int timeout)
{
AutoResetEvent waitHandle = new AutoResetEvent (false);
opener.BeginInvoke (delegate (IAsyncResult result) {
opener.EndInvoke (result);
waitHandle.Set ();
}, null);
if (!waitHandle.WaitOne (TimeSpan.FromMilliseconds (timeout)))
throw new TimeoutException ();
}
public bool IsAsync {
get { return false; }
}
public int NumberOfServerInstances {
get { throw new NotImplementedException (); }
}
}
class UnixNamedPipeServer : UnixNamedPipe, INamedPipeServer
{
//NamedPipeServerStream owner;
// .ctor with existing handle
public UnixNamedPipeServer (NamedPipeServerStream owner, SafePipeHandle safePipeHandle)
{
this.handle = safePipeHandle;
//this.owner = owner;
}
// .ctor without handle - create new
public UnixNamedPipeServer (NamedPipeServerStream owner, string pipeName, int maxNumberOfServerInstances,
PipeTransmissionMode transmissionMode, PipeAccessRights rights, PipeOptions options,
int inBufferSize, int outBufferSize, HandleInheritability inheritability)
{
string name = Path.Combine ("/var/tmp/", pipeName);
EnsureTargetFile (name);
RightsToAccess (rights);
ValidateOptions (options, owner.TransmissionMode);
// FIXME: maxNumberOfServerInstances, modes, sizes, handle inheritability
var fs = new FileStream (name, FileMode.Open, RightsToFileAccess (rights), FileShare.ReadWrite);
handle = new SafePipeHandle (fs.Handle, false);
owner.Stream = fs;
should_close_handle = true;
}
SafePipeHandle handle;
bool should_close_handle;
public override SafePipeHandle Handle {
get { return handle; }
}
public void Disconnect ()
{
if (should_close_handle)
Syscall.fclose (handle.DangerousGetHandle ());
}
public void WaitForConnection ()
{
// FIXME: what can I do here?
}
}
}
#endif

View File

@@ -0,0 +1,386 @@
//
// PipeWin32.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !BOOTSTRAP_BASIC
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
namespace System.IO.Pipes
{
static class Win32PipeError
{
public static Exception GetException ()
{
return GetException (Marshal.GetLastWin32Error ());
}
public static Exception GetException (int errorCode)
{
switch (errorCode) {
case 5: return new UnauthorizedAccessException ();
default: return new Win32Exception (errorCode);
}
}
}
abstract class Win32AnonymousPipe : IPipe
{
protected Win32AnonymousPipe ()
{
}
public abstract SafePipeHandle Handle { get; }
public void WaitForPipeDrain ()
{
throw new NotImplementedException ();
}
}
class Win32AnonymousPipeClient : Win32AnonymousPipe, IAnonymousPipeClient
{
// AnonymousPipeClientStream owner;
public Win32AnonymousPipeClient (AnonymousPipeClientStream owner, SafePipeHandle handle)
{
// this.owner = owner;
this.handle = handle;
}
SafePipeHandle handle;
public override SafePipeHandle Handle {
get { return handle; }
}
}
class Win32AnonymousPipeServer : Win32AnonymousPipe, IAnonymousPipeServer
{
// AnonymousPipeServerStream owner;
public unsafe Win32AnonymousPipeServer (AnonymousPipeServerStream owner, PipeDirection direction,
HandleInheritability inheritability, int bufferSize,
PipeSecurity pipeSecurity)
{
IntPtr r, w;
byte[] securityDescriptor = null;
if (pipeSecurity != null)
securityDescriptor = pipeSecurity.GetSecurityDescriptorBinaryForm ();
fixed (byte* securityDescriptorPtr = securityDescriptor) {
SecurityAttributes att = new SecurityAttributes (inheritability, (IntPtr)securityDescriptorPtr);
if (!Win32Marshal.CreatePipe (out r, out w, ref att, bufferSize))
throw Win32PipeError.GetException ();
}
var rh = new SafePipeHandle (r, true);
var wh = new SafePipeHandle (w, true);
if (direction == PipeDirection.Out) {
server_handle = wh;
client_handle = rh;
} else {
server_handle = rh;
client_handle = wh;
}
}
public Win32AnonymousPipeServer (AnonymousPipeServerStream owner, SafePipeHandle serverHandle, SafePipeHandle clientHandle)
{
// this.owner = owner;
this.server_handle = serverHandle;
this.client_handle = clientHandle;
}
SafePipeHandle server_handle, client_handle;
public override SafePipeHandle Handle {
get { return server_handle; }
}
public SafePipeHandle ClientHandle {
get { return client_handle; }
}
public void DisposeLocalCopyOfClientHandle ()
{
throw new NotImplementedException ();
}
}
abstract class Win32NamedPipe : IPipe
{
string name_cache;
public string Name {
get {
if (name_cache != null)
return name_cache;
int s, c, m, t;
byte [] un = new byte [200];
while (true) {
if (!Win32Marshal.GetNamedPipeHandleState (Handle, out s, out c, out m, out t, un, un.Length))
throw Win32PipeError.GetException ();
if (un [un.Length - 1] == 0)
break;
un = new byte [un.Length * 10];
}
name_cache = Encoding.Default.GetString (un);
return name_cache;
}
}
public abstract SafePipeHandle Handle { get; }
public void WaitForPipeDrain ()
{
throw new NotImplementedException ();
}
}
class Win32NamedPipeClient : Win32NamedPipe, INamedPipeClient
{
NamedPipeClientStream owner;
// .ctor with existing handle
public Win32NamedPipeClient (NamedPipeClientStream owner, SafePipeHandle safePipeHandle)
{
this.handle = safePipeHandle;
this.owner = owner;
// FIXME: retrieve is_async from state?
}
// .ctor without handle - create new
public Win32NamedPipeClient (NamedPipeClientStream owner, string serverName, string pipeName,
PipeAccessRights desiredAccessRights, PipeOptions options,
HandleInheritability inheritability)
{
name = String.Format ("\\\\{0}\\pipe\\{1}", serverName, pipeName);
var att = new SecurityAttributes (inheritability, IntPtr.Zero);
is_async = (options & PipeOptions.Asynchronous) != PipeOptions.None;
opener = delegate {
var ret = Win32Marshal.CreateFile (name, desiredAccessRights, 0, ref att, 3, 0, IntPtr.Zero);
if (ret == new IntPtr (-1L))
throw Win32PipeError.GetException ();
return new SafePipeHandle (ret, true);
};
this.owner = owner;
}
Func<SafePipeHandle> opener;
bool is_async;
string name;
SafePipeHandle handle;
public override SafePipeHandle Handle {
get { return handle; }
}
public bool IsAsync {
get { return is_async; }
}
public void Connect ()
{
if (owner.IsConnected)
throw new InvalidOperationException ("The named pipe is already connected");
handle = opener ();
}
public void Connect (int timeout)
{
if (owner.IsConnected)
throw new InvalidOperationException ("The named pipe is already connected");
if (!Win32Marshal.WaitNamedPipe (name, timeout))
throw Win32PipeError.GetException ();
Connect ();
}
public int NumberOfServerInstances {
get {
int s, c, m, t;
byte [] un = null;
if (!Win32Marshal.GetNamedPipeHandleState (Handle, out s, out c, out m, out t, un, 0))
throw Win32PipeError.GetException ();
return c;
}
}
}
class Win32NamedPipeServer : Win32NamedPipe, INamedPipeServer
{
//NamedPipeServerStream owner;
// .ctor with existing handle
public Win32NamedPipeServer (NamedPipeServerStream owner, SafePipeHandle safePipeHandle)
{
handle = safePipeHandle;
//this.owner = owner;
}
// .ctor without handle - create new
public unsafe Win32NamedPipeServer (NamedPipeServerStream owner, string pipeName, int maxNumberOfServerInstances,
PipeTransmissionMode transmissionMode, PipeAccessRights rights,
PipeOptions options, int inBufferSize, int outBufferSize,
PipeSecurity pipeSecurity, HandleInheritability inheritability)
{
string name = String.Format ("\\\\.\\pipe\\{0}", pipeName);
uint openMode;
openMode = (uint)rights | (uint)options; // Enum values match Win32 flags exactly.
int pipeMode = 0;
if ((owner.TransmissionMode & PipeTransmissionMode.Message) != 0)
pipeMode |= 4;
//if ((readTransmissionMode & PipeTransmissionMode.Message) != 0)
// pipeMode |= 2;
if ((options & PipeOptions.Asynchronous) != 0)
pipeMode |= 1;
byte[] securityDescriptor = null;
if (pipeSecurity != null)
securityDescriptor = pipeSecurity.GetSecurityDescriptorBinaryForm ();
fixed (byte* securityDescriptorPtr = securityDescriptor) {
// FIXME: is nDefaultTimeout = 0 ok?
var att = new SecurityAttributes (inheritability, (IntPtr)securityDescriptorPtr);
var ret = Win32Marshal.CreateNamedPipe (name, openMode, pipeMode, maxNumberOfServerInstances,
outBufferSize, inBufferSize, 0, ref att, IntPtr.Zero);
if (ret == new IntPtr (-1L))
throw Win32PipeError.GetException ();
handle = new SafePipeHandle (ret, true);
}
}
SafePipeHandle handle;
public override SafePipeHandle Handle {
get { return handle; }
}
public void Disconnect ()
{
Win32Marshal.DisconnectNamedPipe (Handle);
}
public void WaitForConnection ()
{
if (!Win32Marshal.ConnectNamedPipe (Handle, IntPtr.Zero))
throw Win32PipeError.GetException ();
}
}
[StructLayout (LayoutKind.Sequential)]
struct SecurityAttributes
{
public readonly int Length;
public readonly IntPtr SecurityDescriptor;
public readonly bool Inheritable;
public SecurityAttributes (HandleInheritability inheritability, IntPtr securityDescriptor)
{
Length = Marshal.SizeOf (typeof (SecurityAttributes));
SecurityDescriptor = securityDescriptor;
Inheritable = inheritability == HandleInheritability.Inheritable;
}
}
static class Win32Marshal
{
internal static bool IsWindows {
get {
switch (Environment.OSVersion.Platform) {
case PlatformID.Win32S:
case PlatformID.Win32Windows:
case PlatformID.Win32NT:
case PlatformID.WinCE:
return true;
default:
return false;
}
}
}
// http://msdn.microsoft.com/en-us/library/aa365152%28VS.85%29.aspx
[DllImport ("kernel32", SetLastError=true)]
internal static extern bool CreatePipe (out IntPtr readHandle, out IntPtr writeHandle,
ref SecurityAttributes pipeAtts, int size);
// http://msdn.microsoft.com/en-us/library/aa365150%28VS.85%29.aspx
[DllImport ("kernel32", SetLastError=true)]
internal static extern IntPtr CreateNamedPipe (string name, uint openMode, int pipeMode, int maxInstances,
int outBufferSize, int inBufferSize, int defaultTimeout,
ref SecurityAttributes securityAttributes, IntPtr atts);
// http://msdn.microsoft.com/en-us/library/aa365146%28VS.85%29.aspx
[DllImport ("kernel32", SetLastError=true)]
internal static extern bool ConnectNamedPipe (SafePipeHandle handle, IntPtr overlapped);
// http://msdn.microsoft.com/en-us/library/aa365166%28VS.85%29.aspx
[DllImport ("kernel32", SetLastError=true)]
internal static extern bool DisconnectNamedPipe (SafePipeHandle handle);
// http://msdn.microsoft.com/en-us/library/aa365443%28VS.85%29.aspx
[DllImport ("kernel32", SetLastError=true)]
internal static extern bool GetNamedPipeHandleState (SafePipeHandle handle,
out int state, out int curInstances,
out int maxCollectionCount, out int collectDateTimeout,
byte [] userName, int maxUserNameSize);
// http://msdn.microsoft.com/en-us/library/aa365800%28VS.85%29.aspx
[DllImport ("kernel32", SetLastError=true)]
internal static extern bool WaitNamedPipe (string name, int timeout);
// http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx
[DllImport ("kernel32", SetLastError=true)]
internal static extern IntPtr CreateFile (string name, PipeAccessRights desiredAccess, FileShare fileShare,
ref SecurityAttributes atts, int creationDisposition, int flags, IntPtr templateHandle);
}
}
#endif