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
- OleDbDataReader.cs
- AuthenticationServiceManager.cs
- TripleDES.cs
- ObjectDataSourceChooseMethodsPanel.cs
- XmlnsDictionary.cs
- XmlnsCompatibleWithAttribute.cs
- DbgUtil.cs
- BaseProcessor.cs
- AnnotationResourceChangedEventArgs.cs
- objectquery_tresulttype.cs
- GradientStop.cs
- OrderedDictionaryStateHelper.cs
- OptionalColumn.cs
- Material.cs
- SiteMapNodeCollection.cs
- CommentEmitter.cs
- RtfToXamlLexer.cs
- TableRow.cs
- FontStretches.cs
- XPathChildIterator.cs
- View.cs
- RemoveStoryboard.cs
- CroppedBitmap.cs
- ValidationEventArgs.cs
- DragDeltaEventArgs.cs
- RowVisual.cs
- VisualBasicExpressionConverter.cs
- UnsafeNativeMethods.cs
- AuthenticationException.cs
- ReadingWritingEntityEventArgs.cs
- OdbcDataReader.cs
- Interfaces.cs
- CompModSwitches.cs
- MembershipSection.cs
- ProfileModule.cs
- MenuItemBindingCollection.cs
- ConsumerConnectionPoint.cs
- MethodMessage.cs
- EntitySqlQueryCacheKey.cs
- DataGridViewCellValueEventArgs.cs
- Currency.cs
- CircleHotSpot.cs
- ObjectStateEntry.cs
- QilBinary.cs
- SQLDecimalStorage.cs
- ParsedRoute.cs
- JumpItem.cs
- SecurityCookieModeValidator.cs
- TcpTransportElement.cs
- AuthorizationContext.cs
- SecurityHeaderElementInferenceEngine.cs
- XPathItem.cs
- SslStream.cs
- ServiceObjectContainer.cs
- GifBitmapEncoder.cs
- SourceElementsCollection.cs
- _OSSOCK.cs
- VirtualStackFrame.cs
- SmtpFailedRecipientException.cs
- EntityViewGenerator.cs
- CompilationRelaxations.cs
- PropertyDescriptorGridEntry.cs
- BufferedStream2.cs
- NativeMethods.cs
- SettingsContext.cs
- ProfileSettings.cs
- InternalCache.cs
- HierarchicalDataBoundControlAdapter.cs
- SettingsPropertyValueCollection.cs
- SingleStorage.cs
- GeometryValueSerializer.cs
- FormsAuthenticationConfiguration.cs
- SymbolMethod.cs
- PackWebRequest.cs
- InvokeBase.cs
- OracleInfoMessageEventArgs.cs
- ServiceManager.cs
- X509IssuerSerialKeyIdentifierClause.cs
- PersonalizableAttribute.cs
- ServiceProviders.cs
- InstanceDataCollectionCollection.cs
- DatePickerDateValidationErrorEventArgs.cs
- SerializationException.cs
- SystemParameters.cs
- XmlTypeAttribute.cs
- SqlVisitor.cs
- DataTableMapping.cs
- SqlMultiplexer.cs
- TextProperties.cs
- DataGridView.cs
- WizardPanelChangingEventArgs.cs
- PtsPage.cs
- File.cs
- StringPropertyBuilder.cs
- HttpApplicationFactory.cs
- WindowsFormsHost.cs
- Operator.cs
- StringBuilder.cs
- PriorityChain.cs
- DataGridDefaultColumnWidthTypeConverter.cs