Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Remoting / Channels / IPC / IpcServerChannel.cs / 1305376 / IpcServerChannel.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //============================================================================ // File: IpcServerChannel.cs // Author: [....]@Microsoft.Com // Summary: Implements a channel that receives method calls over LPC. // //========================================================================= using System; using System.Collections; using System.IO; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Messaging; using System.Security.Principal; using System.Security.AccessControl; using System.Threading; using System.Runtime.InteropServices; using System.Globalization; using System.Security.Permissions; namespace System.Runtime.Remoting.Channels.Ipc { public class IpcServerChannel : IChannelReceiver, ISecurableChannel { private int _channelPriority = 20; // priority of channel (default=20) private String _channelName = "ipc server"; // channel name private String _portName = null; private ChannelDataStore _channelData = null; // channel data private IpcPort _port = null; private bool _bSuppressChannelData = false; // should we hand out null for our channel data private bool _secure = false; // default is no authentication private bool _impersonate = false; // default is no impersonation private string _authorizedGroup = null; // default is authenticated users + deny Network sid private CommonSecurityDescriptor _securityDescriptor = null; private bool authSet = false; private bool _bExclusiveAddressUse = true; private IServerChannelSinkProvider _sinkProvider = null; private IpcServerTransportSink _transportSink = null; private Thread _listenerThread; private bool _bListening = false; private Exception _startListeningException = null; // if an exception happens on the listener thread when attempting // to start listening, that will get set here. private AutoResetEvent _waitForStartListening = new AutoResetEvent(false); public IpcServerChannel(string portName) { if (portName == null) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_NoPortNameSpecified")); _portName = portName; SetupChannel(); } // IpcServerChannel public IpcServerChannel(String name, string portName) { if (portName == null) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_NoPortNameSpecified")); _channelName = name; _portName = portName; SetupChannel(); } // IpcServerChannel public IpcServerChannel(String name, string portName, IServerChannelSinkProvider sinkProvider) { if (portName == null) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_NoPortNameSpecified")); _channelName = name; _portName = portName; _sinkProvider = sinkProvider; SetupChannel(); } // IpcServerChannel public IpcServerChannel(IDictionary properties, IServerChannelSinkProvider sinkProvider) : this(properties, sinkProvider, null) { } public IpcServerChannel(IDictionary properties, IServerChannelSinkProvider sinkProvider, CommonSecurityDescriptor securityDescriptor) { if (properties != null) { foreach (DictionaryEntry entry in properties) { switch ((String)entry.Key) { case "name": _channelName = (String)entry.Value; break; case "portName": _portName = (String)entry.Value; break; case "priority": _channelPriority = Convert.ToInt32(entry.Value, CultureInfo.InvariantCulture); break; case "secure": _secure = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "impersonate": _impersonate = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); authSet = true; break; case "suppressChannelData": _bSuppressChannelData = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "authorizedGroup": _authorizedGroup = (String)entry.Value; break; case "exclusiveAddressUse": _bExclusiveAddressUse = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; default: break; } } } if (_portName == null) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_NoPortNameSpecified")); _sinkProvider = sinkProvider; _securityDescriptor = securityDescriptor; SetupChannel(); } // IpcServerChannel // // ISecurableChannel implementation // public bool IsSecured { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _secure; } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] set { _secure = value; if (_transportSink != null) _transportSink.IsSecured = value; } } private void SetupChannel() { // set channel data // (These get changed inside of StartListening(), in the case where the listen // port is 0, because we can't determine the port number until after the // IpcListener starts.) if (authSet && !_secure) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_AuthenticationConfig")); _channelData = new ChannelDataStore(null); _channelData.ChannelUris = new String[1]; _channelData.ChannelUris[0] = GetChannelUri(); // set default provider (soap formatter) if no provider has been set if (_sinkProvider == null) _sinkProvider = CreateDefaultServerProviderChain(); CoreChannel.CollectChannelDataFromServerSinkProviders(_channelData, _sinkProvider); // construct sink chain IServerChannelSink sink = ChannelServices.CreateServerChannelSinkChain(_sinkProvider, this); _transportSink = new IpcServerTransportSink(sink, _secure, _impersonate); // Start a thread to listen for incoming requests ThreadStart t = new ThreadStart(this.Listen); _listenerThread = new Thread(t); _listenerThread.IsBackground = true; // Wait for thread to spin up StartListening(null); } // SetupChannel private IServerChannelSinkProvider CreateDefaultServerProviderChain() { IServerChannelSinkProvider chain = new BinaryServerFormatterSinkProvider(); IServerChannelSinkProvider sink = chain; sink.Next = new SoapServerFormatterSinkProvider(); return chain; } // CreateDefaultServerProviderChain // // IChannel implementation // public int ChannelPriority { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _channelPriority; } } public String ChannelName { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _channelName; } } // returns channelURI and places object uri into out parameter [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public String Parse(String url, out String objectURI) { return IpcChannelHelper.ParseURL(url, out objectURI); } // Parse // // end of IChannel implementation // // // IChannelReceiver implementation // public Object ChannelData { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { if (_bSuppressChannelData || !_bListening) { return null; } else { return _channelData; } } } // ChannelData public String GetChannelUri() { return "ipc://" + _portName; } // GetChannelUri [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public virtual String[] GetUrlsForUri(String objectUri) { if (objectUri == null) throw new ArgumentNullException("objectUri"); String[] retVal = new String[1]; if (!objectUri.StartsWith("/", StringComparison.Ordinal)) objectUri = "/" + objectUri; retVal[0] = GetChannelUri() + objectUri; return retVal; } // GetURLsforURI [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void StartListening(Object data) { InternalRemotingServices.RemotingTrace("IpcChannel.StartListening"); if (_listenerThread.IsAlive == false) { _listenerThread.Start(); _waitForStartListening.WaitOne(); // listener thread will signal this after starting IpcListener if (_startListeningException != null) { // An exception happened when we tried to start listening (such as "socket already in use) Exception e = _startListeningException; _startListeningException = null; throw e; } _bListening = true; } } // StartListening [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void StopListening(Object data) { InternalRemotingServices.RemotingTrace("IpcChannel.StopListening"); _bListening = false; _port.Dispose(); } // StopListening // // end of IChannelReceiver implementation // // Thread for listening void Listen() { bool bOkToListen = true; InternalRemotingServices.RemotingTrace( "Waiting to Accept a Connection on Port: " + _portName); // // Wait for an incoming client connection // IntPtr handle = IntPtr.Zero; bool connected = false; CommonSecurityDescriptor descriptor = _securityDescriptor; // Connect with exlusive flag the first time if (bOkToListen) { try{ // If the descriptor is not explicitly set through code use the _authorizedGroup config if (descriptor == null && _authorizedGroup != null) { NTAccount ntAccount = new NTAccount(_authorizedGroup); descriptor = IpcPort.CreateSecurityDescriptor((SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier))); } _port = IpcPort.Create(_portName, descriptor, _bExclusiveAddressUse); } catch (Exception e) { _startListeningException = e; } finally { _waitForStartListening.Set(); // allow main thread to continue now that we have tried to start the socket } if (_port != null){ connected = _port.WaitForConnect(); bOkToListen = _bListening; } } while (bOkToListen && _startListeningException == null) { InternalRemotingServices.RemotingTrace("IpcChannel::Listen"); // For DevDiv#220882, we need to create new IpcPort before handling the current message // to avoid race condition in case the message is handled and finished before // the new IpcPort is created. The client will intermittently fail with Port not found. IpcPort port = IpcPort.Create(_portName, descriptor, false); if (connected) { // Initialize the server handler and perform an async read IpcServerHandler serverHandler = new IpcServerHandler(_port, CoreChannel.RequestQueue, new PipeStream(_port)); serverHandler.DataArrivedCallback = new WaitCallback(_transportSink.ServiceRequest); serverHandler.BeginReadMessage(); } _port = port; connected = _port.WaitForConnect(); bOkToListen = _bListening; } } } // class IpcServerChannel internal class IpcServerTransportSink : IServerChannelSink { //private const int _defaultChunkSize = 4096; private const int s_MaxSize = (2 << 24); // Max size of the payload // sink state private IServerChannelSink _nextSink; // AuthenticationMode bool _secure; bool _impersonate; public IpcServerTransportSink(IServerChannelSink nextSink, bool secure, bool impersonate) { _nextSink = nextSink; _secure = secure; _impersonate = impersonate; } // IpcServerTransportSink internal bool IsSecured { get { return _secure; } set { _secure = value; } } internal void ServiceRequest(Object state) { IpcServerHandler ipcServerHandler = (IpcServerHandler)state; // Read the headers from the stream, using the header size in the message ITransportHeaders headers = ipcServerHandler.ReadHeaders(); // Get the request Stream Stream requestStream = ipcServerHandler.GetRequestStream(); // customErrors should be disabled, since we are on the same machine headers["__CustomErrorsEnabled"] = false; // process request ServerChannelSinkStack sinkStack = new ServerChannelSinkStack(); sinkStack.Push(this, ipcServerHandler); IMessage responseMessage = null; ITransportHeaders responseHeaders = null; Stream responseStream = null; WindowsIdentity identity = null; IPrincipal oldPrincipal = null; bool impersonated = false; bool principalChanged = false; ServerProcessing processing = ServerProcessing.Complete; try{ if (_secure) { IpcPort port = ipcServerHandler.Port; port.ImpersonateClient(); oldPrincipal = Thread.CurrentPrincipal; principalChanged = true; impersonated = true; identity = WindowsIdentity.GetCurrent(); // If the authentication mode is to identify callers only revert the impersonation immediately if (!_impersonate) { NativePipe.RevertToSelf(); Thread.CurrentPrincipal = new GenericPrincipal(identity, null); impersonated = false; } else { if (identity.ImpersonationLevel == TokenImpersonationLevel.Impersonation || identity.ImpersonationLevel == TokenImpersonationLevel.Delegation) { // Set the current principal Thread.CurrentPrincipal = new WindowsPrincipal(identity); } else throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_TokenImpersonationFailure")); } } processing = _nextSink.ProcessMessage(sinkStack, null, headers, requestStream, out responseMessage, out responseHeaders, out responseStream); } catch( Exception e) { ipcServerHandler.CloseOnFatalError(e); } finally{ // Revert the principal if we had changed the principal if (principalChanged) { Thread.CurrentPrincipal = oldPrincipal; } // Revert the impersonation if we had impersonated if (impersonated) { NativePipe.RevertToSelf(); impersonated = false; } } // handle response switch (processing) { case ServerProcessing.Complete: { // Send the response. Call completed synchronously. sinkStack.Pop(this); // Send the response back to the client ipcServerHandler.SendResponse(responseHeaders, responseStream); break; } // case ServerProcessing.Complete case ServerProcessing.OneWay: { // No response needed, but the following method will make sure that // we send at least a skeleton reply if the incoming request was // not marked OneWayRequest (client/server metadata could be out of // [....]). ipcServerHandler.SendResponse(responseHeaders, responseStream); break; } // case ServerProcessing.OneWay case ServerProcessing.Async: { sinkStack.StoreAndDispatch(this, ipcServerHandler); break; }// case ServerProcessing.Async } // switch (processing) // Start waiting for the next request if (processing != ServerProcessing.Async) { ipcServerHandler.BeginReadMessage(); } } // ServiceRequest // // IServerChannelSink implementation // public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { // NOTE: This doesn't have to be implemented because the server transport // sink is always first. throw new NotSupportedException(); } public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers, Stream stream) { IpcServerHandler ipcServerHandler = null; ipcServerHandler = (IpcServerHandler)state; // send the response ipcServerHandler.SendResponse(headers, stream); //if (streamManager.CanServiceAnotherRequest()) // streamManager.BeginReadMessage(); //else // streamManager.Close(); } // AsyncProcessResponse public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers) { // We always want a stream to read from. return null; } // GetResponseStream public IServerChannelSink NextChannelSink { get { return _nextSink; } } public IDictionary Properties { get { return null; } } // Properties // // end of IServerChannelSink implementation // } // class IpcServerTransportSink } // namespace System.Runtime.Remoting.Channels.Ipc // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //============================================================================ // File: IpcServerChannel.cs // Author: [....]@Microsoft.Com // Summary: Implements a channel that receives method calls over LPC. // //========================================================================= using System; using System.Collections; using System.IO; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Messaging; using System.Security.Principal; using System.Security.AccessControl; using System.Threading; using System.Runtime.InteropServices; using System.Globalization; using System.Security.Permissions; namespace System.Runtime.Remoting.Channels.Ipc { public class IpcServerChannel : IChannelReceiver, ISecurableChannel { private int _channelPriority = 20; // priority of channel (default=20) private String _channelName = "ipc server"; // channel name private String _portName = null; private ChannelDataStore _channelData = null; // channel data private IpcPort _port = null; private bool _bSuppressChannelData = false; // should we hand out null for our channel data private bool _secure = false; // default is no authentication private bool _impersonate = false; // default is no impersonation private string _authorizedGroup = null; // default is authenticated users + deny Network sid private CommonSecurityDescriptor _securityDescriptor = null; private bool authSet = false; private bool _bExclusiveAddressUse = true; private IServerChannelSinkProvider _sinkProvider = null; private IpcServerTransportSink _transportSink = null; private Thread _listenerThread; private bool _bListening = false; private Exception _startListeningException = null; // if an exception happens on the listener thread when attempting // to start listening, that will get set here. private AutoResetEvent _waitForStartListening = new AutoResetEvent(false); public IpcServerChannel(string portName) { if (portName == null) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_NoPortNameSpecified")); _portName = portName; SetupChannel(); } // IpcServerChannel public IpcServerChannel(String name, string portName) { if (portName == null) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_NoPortNameSpecified")); _channelName = name; _portName = portName; SetupChannel(); } // IpcServerChannel public IpcServerChannel(String name, string portName, IServerChannelSinkProvider sinkProvider) { if (portName == null) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_NoPortNameSpecified")); _channelName = name; _portName = portName; _sinkProvider = sinkProvider; SetupChannel(); } // IpcServerChannel public IpcServerChannel(IDictionary properties, IServerChannelSinkProvider sinkProvider) : this(properties, sinkProvider, null) { } public IpcServerChannel(IDictionary properties, IServerChannelSinkProvider sinkProvider, CommonSecurityDescriptor securityDescriptor) { if (properties != null) { foreach (DictionaryEntry entry in properties) { switch ((String)entry.Key) { case "name": _channelName = (String)entry.Value; break; case "portName": _portName = (String)entry.Value; break; case "priority": _channelPriority = Convert.ToInt32(entry.Value, CultureInfo.InvariantCulture); break; case "secure": _secure = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "impersonate": _impersonate = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); authSet = true; break; case "suppressChannelData": _bSuppressChannelData = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "authorizedGroup": _authorizedGroup = (String)entry.Value; break; case "exclusiveAddressUse": _bExclusiveAddressUse = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; default: break; } } } if (_portName == null) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_NoPortNameSpecified")); _sinkProvider = sinkProvider; _securityDescriptor = securityDescriptor; SetupChannel(); } // IpcServerChannel // // ISecurableChannel implementation // public bool IsSecured { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _secure; } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] set { _secure = value; if (_transportSink != null) _transportSink.IsSecured = value; } } private void SetupChannel() { // set channel data // (These get changed inside of StartListening(), in the case where the listen // port is 0, because we can't determine the port number until after the // IpcListener starts.) if (authSet && !_secure) throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_AuthenticationConfig")); _channelData = new ChannelDataStore(null); _channelData.ChannelUris = new String[1]; _channelData.ChannelUris[0] = GetChannelUri(); // set default provider (soap formatter) if no provider has been set if (_sinkProvider == null) _sinkProvider = CreateDefaultServerProviderChain(); CoreChannel.CollectChannelDataFromServerSinkProviders(_channelData, _sinkProvider); // construct sink chain IServerChannelSink sink = ChannelServices.CreateServerChannelSinkChain(_sinkProvider, this); _transportSink = new IpcServerTransportSink(sink, _secure, _impersonate); // Start a thread to listen for incoming requests ThreadStart t = new ThreadStart(this.Listen); _listenerThread = new Thread(t); _listenerThread.IsBackground = true; // Wait for thread to spin up StartListening(null); } // SetupChannel private IServerChannelSinkProvider CreateDefaultServerProviderChain() { IServerChannelSinkProvider chain = new BinaryServerFormatterSinkProvider(); IServerChannelSinkProvider sink = chain; sink.Next = new SoapServerFormatterSinkProvider(); return chain; } // CreateDefaultServerProviderChain // // IChannel implementation // public int ChannelPriority { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _channelPriority; } } public String ChannelName { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _channelName; } } // returns channelURI and places object uri into out parameter [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public String Parse(String url, out String objectURI) { return IpcChannelHelper.ParseURL(url, out objectURI); } // Parse // // end of IChannel implementation // // // IChannelReceiver implementation // public Object ChannelData { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { if (_bSuppressChannelData || !_bListening) { return null; } else { return _channelData; } } } // ChannelData public String GetChannelUri() { return "ipc://" + _portName; } // GetChannelUri [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public virtual String[] GetUrlsForUri(String objectUri) { if (objectUri == null) throw new ArgumentNullException("objectUri"); String[] retVal = new String[1]; if (!objectUri.StartsWith("/", StringComparison.Ordinal)) objectUri = "/" + objectUri; retVal[0] = GetChannelUri() + objectUri; return retVal; } // GetURLsforURI [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void StartListening(Object data) { InternalRemotingServices.RemotingTrace("IpcChannel.StartListening"); if (_listenerThread.IsAlive == false) { _listenerThread.Start(); _waitForStartListening.WaitOne(); // listener thread will signal this after starting IpcListener if (_startListeningException != null) { // An exception happened when we tried to start listening (such as "socket already in use) Exception e = _startListeningException; _startListeningException = null; throw e; } _bListening = true; } } // StartListening [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void StopListening(Object data) { InternalRemotingServices.RemotingTrace("IpcChannel.StopListening"); _bListening = false; _port.Dispose(); } // StopListening // // end of IChannelReceiver implementation // // Thread for listening void Listen() { bool bOkToListen = true; InternalRemotingServices.RemotingTrace( "Waiting to Accept a Connection on Port: " + _portName); // // Wait for an incoming client connection // IntPtr handle = IntPtr.Zero; bool connected = false; CommonSecurityDescriptor descriptor = _securityDescriptor; // Connect with exlusive flag the first time if (bOkToListen) { try{ // If the descriptor is not explicitly set through code use the _authorizedGroup config if (descriptor == null && _authorizedGroup != null) { NTAccount ntAccount = new NTAccount(_authorizedGroup); descriptor = IpcPort.CreateSecurityDescriptor((SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier))); } _port = IpcPort.Create(_portName, descriptor, _bExclusiveAddressUse); } catch (Exception e) { _startListeningException = e; } finally { _waitForStartListening.Set(); // allow main thread to continue now that we have tried to start the socket } if (_port != null){ connected = _port.WaitForConnect(); bOkToListen = _bListening; } } while (bOkToListen && _startListeningException == null) { InternalRemotingServices.RemotingTrace("IpcChannel::Listen"); // For DevDiv#220882, we need to create new IpcPort before handling the current message // to avoid race condition in case the message is handled and finished before // the new IpcPort is created. The client will intermittently fail with Port not found. IpcPort port = IpcPort.Create(_portName, descriptor, false); if (connected) { // Initialize the server handler and perform an async read IpcServerHandler serverHandler = new IpcServerHandler(_port, CoreChannel.RequestQueue, new PipeStream(_port)); serverHandler.DataArrivedCallback = new WaitCallback(_transportSink.ServiceRequest); serverHandler.BeginReadMessage(); } _port = port; connected = _port.WaitForConnect(); bOkToListen = _bListening; } } } // class IpcServerChannel internal class IpcServerTransportSink : IServerChannelSink { //private const int _defaultChunkSize = 4096; private const int s_MaxSize = (2 << 24); // Max size of the payload // sink state private IServerChannelSink _nextSink; // AuthenticationMode bool _secure; bool _impersonate; public IpcServerTransportSink(IServerChannelSink nextSink, bool secure, bool impersonate) { _nextSink = nextSink; _secure = secure; _impersonate = impersonate; } // IpcServerTransportSink internal bool IsSecured { get { return _secure; } set { _secure = value; } } internal void ServiceRequest(Object state) { IpcServerHandler ipcServerHandler = (IpcServerHandler)state; // Read the headers from the stream, using the header size in the message ITransportHeaders headers = ipcServerHandler.ReadHeaders(); // Get the request Stream Stream requestStream = ipcServerHandler.GetRequestStream(); // customErrors should be disabled, since we are on the same machine headers["__CustomErrorsEnabled"] = false; // process request ServerChannelSinkStack sinkStack = new ServerChannelSinkStack(); sinkStack.Push(this, ipcServerHandler); IMessage responseMessage = null; ITransportHeaders responseHeaders = null; Stream responseStream = null; WindowsIdentity identity = null; IPrincipal oldPrincipal = null; bool impersonated = false; bool principalChanged = false; ServerProcessing processing = ServerProcessing.Complete; try{ if (_secure) { IpcPort port = ipcServerHandler.Port; port.ImpersonateClient(); oldPrincipal = Thread.CurrentPrincipal; principalChanged = true; impersonated = true; identity = WindowsIdentity.GetCurrent(); // If the authentication mode is to identify callers only revert the impersonation immediately if (!_impersonate) { NativePipe.RevertToSelf(); Thread.CurrentPrincipal = new GenericPrincipal(identity, null); impersonated = false; } else { if (identity.ImpersonationLevel == TokenImpersonationLevel.Impersonation || identity.ImpersonationLevel == TokenImpersonationLevel.Delegation) { // Set the current principal Thread.CurrentPrincipal = new WindowsPrincipal(identity); } else throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_TokenImpersonationFailure")); } } processing = _nextSink.ProcessMessage(sinkStack, null, headers, requestStream, out responseMessage, out responseHeaders, out responseStream); } catch( Exception e) { ipcServerHandler.CloseOnFatalError(e); } finally{ // Revert the principal if we had changed the principal if (principalChanged) { Thread.CurrentPrincipal = oldPrincipal; } // Revert the impersonation if we had impersonated if (impersonated) { NativePipe.RevertToSelf(); impersonated = false; } } // handle response switch (processing) { case ServerProcessing.Complete: { // Send the response. Call completed synchronously. sinkStack.Pop(this); // Send the response back to the client ipcServerHandler.SendResponse(responseHeaders, responseStream); break; } // case ServerProcessing.Complete case ServerProcessing.OneWay: { // No response needed, but the following method will make sure that // we send at least a skeleton reply if the incoming request was // not marked OneWayRequest (client/server metadata could be out of // [....]). ipcServerHandler.SendResponse(responseHeaders, responseStream); break; } // case ServerProcessing.OneWay case ServerProcessing.Async: { sinkStack.StoreAndDispatch(this, ipcServerHandler); break; }// case ServerProcessing.Async } // switch (processing) // Start waiting for the next request if (processing != ServerProcessing.Async) { ipcServerHandler.BeginReadMessage(); } } // ServiceRequest // // IServerChannelSink implementation // public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { // NOTE: This doesn't have to be implemented because the server transport // sink is always first. throw new NotSupportedException(); } public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers, Stream stream) { IpcServerHandler ipcServerHandler = null; ipcServerHandler = (IpcServerHandler)state; // send the response ipcServerHandler.SendResponse(headers, stream); //if (streamManager.CanServiceAnotherRequest()) // streamManager.BeginReadMessage(); //else // streamManager.Close(); } // AsyncProcessResponse public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers) { // We always want a stream to read from. return null; } // GetResponseStream public IServerChannelSink NextChannelSink { get { return _nextSink; } } public IDictionary Properties { get { return null; } } // Properties // // end of IServerChannelSink implementation // } // class IpcServerTransportSink } // namespace System.Runtime.Remoting.Channels.Ipc // 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
- ProfileProvider.cs
- OdbcConnectionFactory.cs
- SerializationHelper.cs
- ErrorReporting.cs
- XPathNodeInfoAtom.cs
- LocalizedNameDescriptionPair.cs
- ListViewItem.cs
- Int32Rect.cs
- EditorPartCollection.cs
- GlyphManager.cs
- WebHeaderCollection.cs
- WebPartEditVerb.cs
- LocalValueEnumerator.cs
- WebPartEditVerb.cs
- IFlowDocumentViewer.cs
- ByeMessageApril2005.cs
- QueryStringConverter.cs
- CatalogPartCollection.cs
- VectorCollection.cs
- LambdaCompiler.Expressions.cs
- DocumentXmlWriter.cs
- AxParameterData.cs
- SafeHandles.cs
- SelectorAutomationPeer.cs
- QualifiedCellIdBoolean.cs
- ReadOnlyMetadataCollection.cs
- Tracer.cs
- CompositeControl.cs
- Method.cs
- DataGridItemCollection.cs
- Triangle.cs
- ImageMapEventArgs.cs
- WebPartConnectionsConfigureVerb.cs
- RuleInfoComparer.cs
- PropertyGridCommands.cs
- XmlChoiceIdentifierAttribute.cs
- ParallelTimeline.cs
- Action.cs
- ValidationErrorInfo.cs
- LinearQuaternionKeyFrame.cs
- XmlDataImplementation.cs
- UnsafeNativeMethods.cs
- ObfuscateAssemblyAttribute.cs
- DataColumnMapping.cs
- Cursors.cs
- WindowsSolidBrush.cs
- DataGridViewCellParsingEventArgs.cs
- ProtocolsConfiguration.cs
- CatalogZone.cs
- RectValueSerializer.cs
- StyleCollectionEditor.cs
- login.cs
- DeclarativeCatalogPart.cs
- ImageFormat.cs
- XmlJsonWriter.cs
- CrossSiteScriptingValidation.cs
- Rectangle.cs
- NotifyIcon.cs
- SecurityManager.cs
- DoubleAnimationUsingPath.cs
- InteropTrackingRecord.cs
- DataTemplateSelector.cs
- HtmlTable.cs
- IWorkflowDebuggerService.cs
- CommandHelper.cs
- DefaultPropertyAttribute.cs
- InspectionWorker.cs
- TableLayoutPanelBehavior.cs
- TraceAsyncResult.cs
- FormattedText.cs
- Condition.cs
- handlecollector.cs
- RuntimeComponentFilter.cs
- DataServiceContext.cs
- FrameworkObject.cs
- DataColumnMapping.cs
- Transform.cs
- IPEndPoint.cs
- DataPagerField.cs
- XmlSchemaAppInfo.cs
- NominalTypeEliminator.cs
- BlockCollection.cs
- Container.cs
- WebFormDesignerActionService.cs
- ListenerConnectionDemuxer.cs
- BaseCollection.cs
- Part.cs
- XamlVector3DCollectionSerializer.cs
- PagesSection.cs
- GradientStop.cs
- X509SecurityToken.cs
- NamespaceList.cs
- BamlRecordReader.cs
- StateDesigner.Helpers.cs
- SignatureHelper.cs
- TextEditorSpelling.cs
- querybuilder.cs
- CalendarDateChangedEventArgs.cs
- ObjectNotFoundException.cs
- CodeCatchClauseCollection.cs