Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Remoting / Channels / IPC / IpcPort.cs / 1305376 / IpcPort.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //============================================================================ // File: IpcPort.cs // Author: [....]@Microsoft.Com // Summary: Implements an abstraction over Named pipes // //========================================================================= using System; using System.Collections; using System.IO; using System.Text; using System.Threading; using System.Security.AccessControl; using System.Security.Principal; using System.Runtime.InteropServices; using System.Globalization; namespace System.Runtime.Remoting.Channels.Ipc { internal class IpcPort : IDisposable { private PipeHandle _handle; private string _portName; private bool _cacheable; private const string prefix = @"\\.\pipe\"; // To make sure we are on the same machine private const string networkSidSddlForm = @"S-1-5-2"; // This is the wellknown sid for network sid private const string authenticatedUserSidSddlForm = @"S-1-5-11"; // This is the wellknown sid for authenticated user sid private static CommonSecurityDescriptor s_securityDescriptor = CreateSecurityDescriptor(null); private IpcPort(string portName, PipeHandle handle) { _portName = portName; _handle = handle; _cacheable = true; #pragma warning disable 618 // Bind the current handle to the threadpool for IOCompletion ThreadPool.BindHandle(_handle.Handle); #pragma warning restore 618 } internal string Name { get { return _portName; } } internal bool Cacheable{ get { return _cacheable;} set { _cacheable = value;} } internal static CommonSecurityDescriptor CreateSecurityDescriptor(SecurityIdentifier userSid) { SecurityIdentifier sid = new SecurityIdentifier(networkSidSddlForm); DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, 1); // Deny all access to NetworkSid dacl.AddAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.None, PropagationFlags.None); if (userSid != null) dacl.AddAccess(AccessControlType.Allow, userSid, -1, InheritanceFlags.None, PropagationFlags.None); // Add access to the current user creating the pipe dacl.AddAccess(AccessControlType.Allow, WindowsIdentity.GetCurrent().User, -1, InheritanceFlags.None, PropagationFlags.None); // Initialize and return the CommonSecurityDescriptor return new CommonSecurityDescriptor(false, false, ControlFlags.OwnerDefaulted | ControlFlags.GroupDefaulted | ControlFlags.DiscretionaryAclPresent, null, null, null, dacl);; } internal static IpcPort Create(String portName, CommonSecurityDescriptor securityDescriptor, bool exclusive) { if (Environment.OSVersion.Platform != PlatformID.Win32NT) { throw new NotSupportedException(CoreChannel.GetResourceString("Remoting_Ipc_Win9x")); } PipeHandle handle = null; // Add the prefix to the portName string pipeName = prefix + portName; SECURITY_ATTRIBUTES attr = new SECURITY_ATTRIBUTES(); attr.nLength = (int)Marshal.SizeOf(attr); byte[] sd = null; // If no securityDescriptor was set by the user use the default if (securityDescriptor == null) { securityDescriptor = s_securityDescriptor; } sd = new byte[securityDescriptor.BinaryLength]; // Get the binary form of the descriptor securityDescriptor.GetBinaryForm(sd, 0); GCHandle pinningHandle = GCHandle.Alloc(sd, GCHandleType.Pinned); // get the address of the security descriptor attr.lpSecurityDescriptor = Marshal.UnsafeAddrOfPinnedArrayElement(sd, 0); // Create the named pipe with the appropriate name handle = NativePipe.CreateNamedPipe(pipeName, NativePipe.PIPE_ACCESS_DUPLEX | NativePipe.FILE_FLAG_OVERLAPPED | (exclusive ? NativePipe.FILE_FLAG_FIRST_PIPE_INSTANCE : 0x0), // Or exclusive flag NativePipe.PIPE_TYPE_BYTE | NativePipe.PIPE_READMODE_BYTE | NativePipe.PIPE_WAIT, NativePipe.PIPE_UNLIMITED_INSTANCES, 8192, 8192, NativePipe.NMPWAIT_WAIT_FOREVER, attr); pinningHandle.Free(); if (handle.Handle.ToInt32() == NativePipe.INVALID_HANDLE_VALUE){ int error = Marshal.GetLastWin32Error(); throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_CreateIpcFailed"), GetMessage(error))); } return new IpcPort(portName, handle); } public bool WaitForConnect() { // Wait for clients to connect bool status = NativePipe.ConnectNamedPipe(_handle, null); return status ? true : (Marshal.GetLastWin32Error() == NativePipe.ERROR_PIPE_CONNECTED); } internal static IpcPort Connect(String portName, bool secure, TokenImpersonationLevel impersonationLevel, int timeout) { string pipeName = prefix + portName; uint impersonation = NativePipe.SECURITY_SQOS_PRESENT; // convert the impersonation Level to the correct flag if (secure) { switch (impersonationLevel) { case TokenImpersonationLevel.None: impersonation = NativePipe.SECURITY_SQOS_PRESENT; break; case TokenImpersonationLevel.Identification: impersonation = NativePipe.SECURITY_SQOS_PRESENT | NativePipe.SECURITY_IDENTIFICATION; break; case TokenImpersonationLevel.Impersonation: impersonation = NativePipe.SECURITY_SQOS_PRESENT | NativePipe.SECURITY_IMPERSONATION; break; case TokenImpersonationLevel.Delegation: impersonation = NativePipe.SECURITY_SQOS_PRESENT | NativePipe.SECURITY_DELEGATION; break; } } while (true) { // Invoke CreateFile with the pipeName to open a client side connection PipeHandle handle = NativePipe.CreateFile(pipeName, NativePipe.GENERIC_READ | NativePipe.GENERIC_WRITE , NativePipe.FILE_SHARE_READ | NativePipe.FILE_SHARE_WRITE, IntPtr.Zero, NativePipe.OPEN_EXISTING, NativePipe.FILE_ATTRIBUTE_NORMAL | NativePipe.FILE_FLAG_OVERLAPPED | impersonation, IntPtr.Zero); if(handle.Handle.ToInt32() != NativePipe.INVALID_HANDLE_VALUE) return new IpcPort(portName, handle); int error = Marshal.GetLastWin32Error(); if(error != NativePipe.ERROR_PIPE_BUSY) { throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ConnectIpcFailed"), GetMessage(error))); } if(!NativePipe.WaitNamedPipe(pipeName, timeout)) { throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_Busy"), GetMessage(error))); } } } // Gets an error message for a Win32 error code. internal static String GetMessage(int errorCode) { StringBuilder sb = new StringBuilder(512); int result = NativePipe.FormatMessage(NativePipe.FORMAT_MESSAGE_IGNORE_INSERTS | NativePipe.FORMAT_MESSAGE_FROM_SYSTEM | NativePipe.FORMAT_MESSAGE_ARGUMENT_ARRAY, NativePipe.NULL, errorCode, 0, sb, sb.Capacity, NativePipe.NULL); if (result != 0) { // result is the # of characters copied to the StringBuilder on NT, // but on Win9x, it appears to be the number of MBCS bytes. // Just give up and return the String as-is... String s = sb.ToString(); return s; } else { return String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_UnknownError_Num"), errorCode.ToString(CultureInfo.InvariantCulture)); } } internal void ImpersonateClient() { bool status = NativePipe.ImpersonateNamedPipeClient(_handle); if (!status) { int error = Marshal.GetLastWin32Error(); throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ImpersonationFailed"), GetMessage(error))); } } internal unsafe int Read(byte[] data, int offset, int length) { bool status = false; int numBytesRead = 0; fixed(byte* p = data) { status = NativePipe.ReadFile(_handle, p + offset, length, ref numBytesRead, IntPtr.Zero); } if (!status) { int error = Marshal.GetLastWin32Error(); throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ReadFailure"), GetMessage(error))); } else return numBytesRead; } internal unsafe IAsyncResult BeginRead(byte[] data, int offset, int size, AsyncCallback callback, object state) { PipeAsyncResult asyncResult = new PipeAsyncResult(callback); // Create a managed overlapped class // We will set the file offsets later Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, asyncResult); // Pack the Overlapped class, and store it in the async result NativeOverlapped* intOverlapped; intOverlapped = overlapped.UnsafePack(IOCallback, data); asyncResult._overlapped = intOverlapped; bool status; // pin the buffer and read data with overlapped fixed(byte* p = data) { status = NativePipe.ReadFile(_handle, p + offset, size, IntPtr.Zero, intOverlapped); } if (!status) { int error = Marshal.GetLastWin32Error(); // For pipes, when they hit EOF, they will come here. if (error == NativePipe.ERROR_BROKEN_PIPE) { // Not an error, but EOF. AsyncFSCallback will NOT be // called. Call the user callback here. asyncResult.CallUserCallback(); // EndRead will free the Overlapped struct correctly. } else if (error != NativePipe.ERROR_IO_PENDING) throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ReadFailure"), GetMessage(error))); } return asyncResult; } private unsafe static readonly IOCompletionCallback IOCallback = new IOCompletionCallback(IpcPort.AsyncFSCallback); unsafe private static void AsyncFSCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped) { // Unpack overlapped Overlapped overlapped = Overlapped.Unpack(pOverlapped); // Free the overlapped struct in EndRead/EndWrite. // Extract async result from overlapped PipeAsyncResult asyncResult = (PipeAsyncResult)overlapped.AsyncResult; asyncResult._numBytes = (int)numBytes; // Handle reading from & writing to closed pipes. While I'm not sure // this is entirely necessary anymore, maybe it's possible for // an async read on a pipe to be issued and then the pipe is closed, // returning this error. This may very well be necessary. if (errorCode == NativePipe.ERROR_BROKEN_PIPE) errorCode = 0; asyncResult._errorCode = (int)errorCode; // Call the user-provided callback. It can and often should // call EndRead or EndWrite. There's no reason to use an async // delegate here - we're already on a threadpool thread. // IAsyncResult's completedSynchronously property must return // false here, saying the user callback was called on another thread. AsyncCallback userCallback = asyncResult._userCallback; userCallback(asyncResult); } internal unsafe int EndRead(IAsyncResult iar) { PipeAsyncResult ar = iar as PipeAsyncResult; // Free memory & GC handles. NativeOverlapped* overlappedPtr = ar._overlapped; if (overlappedPtr != null) Overlapped.Free(overlappedPtr); // Now check for any error during the read. if (ar._errorCode != 0) throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ReadFailure"), GetMessage(ar._errorCode))); return ar._numBytes; } internal unsafe void Write(byte[] data, int offset, int size) { int numBytesWritten = 0; bool status = false; // pin the buffer and write data fixed(byte* p = data) { status = NativePipe.WriteFile(_handle, p + offset, size, ref numBytesWritten, IntPtr.Zero); } if (!status) { int error = Marshal.GetLastWin32Error(); throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_WriteFailure"), GetMessage(error))); } } private bool isDisposed = false; ~IpcPort(){ Dispose(); } public void Dispose() { InternalRemotingServices.RemotingAssert(_handle.Handle != IntPtr.Zero, "Handle should be valid"); if (!isDisposed){ _handle.Close(); isDisposed = true; GC.SuppressFinalize(this); } } public bool IsDisposed { get { return isDisposed; } } } internal unsafe class PipeAsyncResult: IAsyncResult { internal NativeOverlapped* _overlapped; internal AsyncCallback _userCallback; internal int _numBytes; internal int _errorCode; internal PipeAsyncResult(AsyncCallback callback) { _userCallback = callback; } public bool IsCompleted { get { throw new NotSupportedException();} } public WaitHandle AsyncWaitHandle { get { throw new NotSupportedException();} } public Object AsyncState { get { throw new NotSupportedException();} } public bool CompletedSynchronously { get { return false;} } internal void CallUserCallback() { // Call user's callback on a threadpool thread. // Set completedSynchronously to false, since it's on another // thread, not the main thread. ThreadPool.QueueUserWorkItem(new WaitCallback(CallUserCallbackWorker)); } private void CallUserCallbackWorker(Object callbackState) { // This needs to call the user callback, then set _isComplete to // true and set the event if it exists. This is similar to the // logic in AsyncFSCallback. _userCallback(this); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //============================================================================ // File: IpcPort.cs // Author: [....]@Microsoft.Com // Summary: Implements an abstraction over Named pipes // //========================================================================= using System; using System.Collections; using System.IO; using System.Text; using System.Threading; using System.Security.AccessControl; using System.Security.Principal; using System.Runtime.InteropServices; using System.Globalization; namespace System.Runtime.Remoting.Channels.Ipc { internal class IpcPort : IDisposable { private PipeHandle _handle; private string _portName; private bool _cacheable; private const string prefix = @"\\.\pipe\"; // To make sure we are on the same machine private const string networkSidSddlForm = @"S-1-5-2"; // This is the wellknown sid for network sid private const string authenticatedUserSidSddlForm = @"S-1-5-11"; // This is the wellknown sid for authenticated user sid private static CommonSecurityDescriptor s_securityDescriptor = CreateSecurityDescriptor(null); private IpcPort(string portName, PipeHandle handle) { _portName = portName; _handle = handle; _cacheable = true; #pragma warning disable 618 // Bind the current handle to the threadpool for IOCompletion ThreadPool.BindHandle(_handle.Handle); #pragma warning restore 618 } internal string Name { get { return _portName; } } internal bool Cacheable{ get { return _cacheable;} set { _cacheable = value;} } internal static CommonSecurityDescriptor CreateSecurityDescriptor(SecurityIdentifier userSid) { SecurityIdentifier sid = new SecurityIdentifier(networkSidSddlForm); DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, 1); // Deny all access to NetworkSid dacl.AddAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.None, PropagationFlags.None); if (userSid != null) dacl.AddAccess(AccessControlType.Allow, userSid, -1, InheritanceFlags.None, PropagationFlags.None); // Add access to the current user creating the pipe dacl.AddAccess(AccessControlType.Allow, WindowsIdentity.GetCurrent().User, -1, InheritanceFlags.None, PropagationFlags.None); // Initialize and return the CommonSecurityDescriptor return new CommonSecurityDescriptor(false, false, ControlFlags.OwnerDefaulted | ControlFlags.GroupDefaulted | ControlFlags.DiscretionaryAclPresent, null, null, null, dacl);; } internal static IpcPort Create(String portName, CommonSecurityDescriptor securityDescriptor, bool exclusive) { if (Environment.OSVersion.Platform != PlatformID.Win32NT) { throw new NotSupportedException(CoreChannel.GetResourceString("Remoting_Ipc_Win9x")); } PipeHandle handle = null; // Add the prefix to the portName string pipeName = prefix + portName; SECURITY_ATTRIBUTES attr = new SECURITY_ATTRIBUTES(); attr.nLength = (int)Marshal.SizeOf(attr); byte[] sd = null; // If no securityDescriptor was set by the user use the default if (securityDescriptor == null) { securityDescriptor = s_securityDescriptor; } sd = new byte[securityDescriptor.BinaryLength]; // Get the binary form of the descriptor securityDescriptor.GetBinaryForm(sd, 0); GCHandle pinningHandle = GCHandle.Alloc(sd, GCHandleType.Pinned); // get the address of the security descriptor attr.lpSecurityDescriptor = Marshal.UnsafeAddrOfPinnedArrayElement(sd, 0); // Create the named pipe with the appropriate name handle = NativePipe.CreateNamedPipe(pipeName, NativePipe.PIPE_ACCESS_DUPLEX | NativePipe.FILE_FLAG_OVERLAPPED | (exclusive ? NativePipe.FILE_FLAG_FIRST_PIPE_INSTANCE : 0x0), // Or exclusive flag NativePipe.PIPE_TYPE_BYTE | NativePipe.PIPE_READMODE_BYTE | NativePipe.PIPE_WAIT, NativePipe.PIPE_UNLIMITED_INSTANCES, 8192, 8192, NativePipe.NMPWAIT_WAIT_FOREVER, attr); pinningHandle.Free(); if (handle.Handle.ToInt32() == NativePipe.INVALID_HANDLE_VALUE){ int error = Marshal.GetLastWin32Error(); throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_CreateIpcFailed"), GetMessage(error))); } return new IpcPort(portName, handle); } public bool WaitForConnect() { // Wait for clients to connect bool status = NativePipe.ConnectNamedPipe(_handle, null); return status ? true : (Marshal.GetLastWin32Error() == NativePipe.ERROR_PIPE_CONNECTED); } internal static IpcPort Connect(String portName, bool secure, TokenImpersonationLevel impersonationLevel, int timeout) { string pipeName = prefix + portName; uint impersonation = NativePipe.SECURITY_SQOS_PRESENT; // convert the impersonation Level to the correct flag if (secure) { switch (impersonationLevel) { case TokenImpersonationLevel.None: impersonation = NativePipe.SECURITY_SQOS_PRESENT; break; case TokenImpersonationLevel.Identification: impersonation = NativePipe.SECURITY_SQOS_PRESENT | NativePipe.SECURITY_IDENTIFICATION; break; case TokenImpersonationLevel.Impersonation: impersonation = NativePipe.SECURITY_SQOS_PRESENT | NativePipe.SECURITY_IMPERSONATION; break; case TokenImpersonationLevel.Delegation: impersonation = NativePipe.SECURITY_SQOS_PRESENT | NativePipe.SECURITY_DELEGATION; break; } } while (true) { // Invoke CreateFile with the pipeName to open a client side connection PipeHandle handle = NativePipe.CreateFile(pipeName, NativePipe.GENERIC_READ | NativePipe.GENERIC_WRITE , NativePipe.FILE_SHARE_READ | NativePipe.FILE_SHARE_WRITE, IntPtr.Zero, NativePipe.OPEN_EXISTING, NativePipe.FILE_ATTRIBUTE_NORMAL | NativePipe.FILE_FLAG_OVERLAPPED | impersonation, IntPtr.Zero); if(handle.Handle.ToInt32() != NativePipe.INVALID_HANDLE_VALUE) return new IpcPort(portName, handle); int error = Marshal.GetLastWin32Error(); if(error != NativePipe.ERROR_PIPE_BUSY) { throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ConnectIpcFailed"), GetMessage(error))); } if(!NativePipe.WaitNamedPipe(pipeName, timeout)) { throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_Busy"), GetMessage(error))); } } } // Gets an error message for a Win32 error code. internal static String GetMessage(int errorCode) { StringBuilder sb = new StringBuilder(512); int result = NativePipe.FormatMessage(NativePipe.FORMAT_MESSAGE_IGNORE_INSERTS | NativePipe.FORMAT_MESSAGE_FROM_SYSTEM | NativePipe.FORMAT_MESSAGE_ARGUMENT_ARRAY, NativePipe.NULL, errorCode, 0, sb, sb.Capacity, NativePipe.NULL); if (result != 0) { // result is the # of characters copied to the StringBuilder on NT, // but on Win9x, it appears to be the number of MBCS bytes. // Just give up and return the String as-is... String s = sb.ToString(); return s; } else { return String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_UnknownError_Num"), errorCode.ToString(CultureInfo.InvariantCulture)); } } internal void ImpersonateClient() { bool status = NativePipe.ImpersonateNamedPipeClient(_handle); if (!status) { int error = Marshal.GetLastWin32Error(); throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ImpersonationFailed"), GetMessage(error))); } } internal unsafe int Read(byte[] data, int offset, int length) { bool status = false; int numBytesRead = 0; fixed(byte* p = data) { status = NativePipe.ReadFile(_handle, p + offset, length, ref numBytesRead, IntPtr.Zero); } if (!status) { int error = Marshal.GetLastWin32Error(); throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ReadFailure"), GetMessage(error))); } else return numBytesRead; } internal unsafe IAsyncResult BeginRead(byte[] data, int offset, int size, AsyncCallback callback, object state) { PipeAsyncResult asyncResult = new PipeAsyncResult(callback); // Create a managed overlapped class // We will set the file offsets later Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, asyncResult); // Pack the Overlapped class, and store it in the async result NativeOverlapped* intOverlapped; intOverlapped = overlapped.UnsafePack(IOCallback, data); asyncResult._overlapped = intOverlapped; bool status; // pin the buffer and read data with overlapped fixed(byte* p = data) { status = NativePipe.ReadFile(_handle, p + offset, size, IntPtr.Zero, intOverlapped); } if (!status) { int error = Marshal.GetLastWin32Error(); // For pipes, when they hit EOF, they will come here. if (error == NativePipe.ERROR_BROKEN_PIPE) { // Not an error, but EOF. AsyncFSCallback will NOT be // called. Call the user callback here. asyncResult.CallUserCallback(); // EndRead will free the Overlapped struct correctly. } else if (error != NativePipe.ERROR_IO_PENDING) throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ReadFailure"), GetMessage(error))); } return asyncResult; } private unsafe static readonly IOCompletionCallback IOCallback = new IOCompletionCallback(IpcPort.AsyncFSCallback); unsafe private static void AsyncFSCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped) { // Unpack overlapped Overlapped overlapped = Overlapped.Unpack(pOverlapped); // Free the overlapped struct in EndRead/EndWrite. // Extract async result from overlapped PipeAsyncResult asyncResult = (PipeAsyncResult)overlapped.AsyncResult; asyncResult._numBytes = (int)numBytes; // Handle reading from & writing to closed pipes. While I'm not sure // this is entirely necessary anymore, maybe it's possible for // an async read on a pipe to be issued and then the pipe is closed, // returning this error. This may very well be necessary. if (errorCode == NativePipe.ERROR_BROKEN_PIPE) errorCode = 0; asyncResult._errorCode = (int)errorCode; // Call the user-provided callback. It can and often should // call EndRead or EndWrite. There's no reason to use an async // delegate here - we're already on a threadpool thread. // IAsyncResult's completedSynchronously property must return // false here, saying the user callback was called on another thread. AsyncCallback userCallback = asyncResult._userCallback; userCallback(asyncResult); } internal unsafe int EndRead(IAsyncResult iar) { PipeAsyncResult ar = iar as PipeAsyncResult; // Free memory & GC handles. NativeOverlapped* overlappedPtr = ar._overlapped; if (overlappedPtr != null) Overlapped.Free(overlappedPtr); // Now check for any error during the read. if (ar._errorCode != 0) throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ReadFailure"), GetMessage(ar._errorCode))); return ar._numBytes; } internal unsafe void Write(byte[] data, int offset, int size) { int numBytesWritten = 0; bool status = false; // pin the buffer and write data fixed(byte* p = data) { status = NativePipe.WriteFile(_handle, p + offset, size, ref numBytesWritten, IntPtr.Zero); } if (!status) { int error = Marshal.GetLastWin32Error(); throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_WriteFailure"), GetMessage(error))); } } private bool isDisposed = false; ~IpcPort(){ Dispose(); } public void Dispose() { InternalRemotingServices.RemotingAssert(_handle.Handle != IntPtr.Zero, "Handle should be valid"); if (!isDisposed){ _handle.Close(); isDisposed = true; GC.SuppressFinalize(this); } } public bool IsDisposed { get { return isDisposed; } } } internal unsafe class PipeAsyncResult: IAsyncResult { internal NativeOverlapped* _overlapped; internal AsyncCallback _userCallback; internal int _numBytes; internal int _errorCode; internal PipeAsyncResult(AsyncCallback callback) { _userCallback = callback; } public bool IsCompleted { get { throw new NotSupportedException();} } public WaitHandle AsyncWaitHandle { get { throw new NotSupportedException();} } public Object AsyncState { get { throw new NotSupportedException();} } public bool CompletedSynchronously { get { return false;} } internal void CallUserCallback() { // Call user's callback on a threadpool thread. // Set completedSynchronously to false, since it's on another // thread, not the main thread. ThreadPool.QueueUserWorkItem(new WaitCallback(CallUserCallbackWorker)); } private void CallUserCallbackWorker(Object callbackState) { // This needs to call the user callback, then set _isComplete to // true and set the event if it exists. This is similar to the // logic in AsyncFSCallback. _userCallback(this); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- GenericTypeParameterBuilder.cs
- XPathAxisIterator.cs
- Root.cs
- WindowsTooltip.cs
- Win32.cs
- VarInfo.cs
- MsmqTransportBindingElement.cs
- VarInfo.cs
- ImageAttributes.cs
- EntityStoreSchemaGenerator.cs
- ListBoxDesigner.cs
- AppLevelCompilationSectionCache.cs
- DragEventArgs.cs
- Matrix.cs
- Application.cs
- InternalControlCollection.cs
- LoadRetryHandler.cs
- NameValueCollection.cs
- HyperLink.cs
- Section.cs
- ClientRuntimeConfig.cs
- VirtualPathProvider.cs
- Cursor.cs
- PropertyIdentifier.cs
- MethodBody.cs
- GacUtil.cs
- SecurityRuntime.cs
- HttpListenerContext.cs
- SystemBrushes.cs
- Icon.cs
- SplineQuaternionKeyFrame.cs
- brushes.cs
- HeaderedContentControl.cs
- autovalidator.cs
- ReflectionServiceProvider.cs
- ConnectionManagementElementCollection.cs
- BatchParser.cs
- ConfigurationManagerHelperFactory.cs
- HtmlEmptyTagControlBuilder.cs
- DetailsViewUpdateEventArgs.cs
- DragDropHelper.cs
- WindowsListViewScroll.cs
- CodeLabeledStatement.cs
- RuntimeArgumentHandle.cs
- CfgParser.cs
- _AuthenticationState.cs
- HiddenField.cs
- Journal.cs
- ClientWindowsAuthenticationMembershipProvider.cs
- QilChoice.cs
- PropertyKey.cs
- IODescriptionAttribute.cs
- TransactionContext.cs
- ImpersonationOption.cs
- DateTimeSerializationSection.cs
- SoapWriter.cs
- AppModelKnownContentFactory.cs
- Logging.cs
- VectorKeyFrameCollection.cs
- AutomationFocusChangedEventArgs.cs
- PublisherMembershipCondition.cs
- webproxy.cs
- LocalBuilder.cs
- VScrollProperties.cs
- Table.cs
- ClientApiGenerator.cs
- InputBindingCollection.cs
- CacheVirtualItemsEvent.cs
- ScaleTransform3D.cs
- IncomingWebResponseContext.cs
- ModelVisual3D.cs
- DocumentOrderQuery.cs
- CookielessHelper.cs
- WebHttpBindingElement.cs
- Funcletizer.cs
- AnnouncementInnerClient11.cs
- EventManager.cs
- StylusPointPropertyInfoDefaults.cs
- XsltSettings.cs
- ContainerUtilities.cs
- CookieHandler.cs
- KnownTypesProvider.cs
- OleDbErrorCollection.cs
- WebColorConverter.cs
- _CookieModule.cs
- Window.cs
- RepeaterItemCollection.cs
- PackUriHelper.cs
- WindowsListViewItem.cs
- SmiContextFactory.cs
- RuleDefinitions.cs
- TextSearch.cs
- AnimationTimeline.cs
- ColumnCollection.cs
- ElementMarkupObject.cs
- AspNetSynchronizationContext.cs
- ImageButton.cs
- MethodExpression.cs
- ExpressionBindingsDialog.cs
- StylusPointProperties.cs