SharingService.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / SMSvcHost / System / ServiceModel / Activation / SharingService.cs / 1 / SharingService.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.ServiceModel.Activation 
{
    using System; 
    using System.ServiceModel; 
    using System.ServiceModel.Description;
    using System.Diagnostics; 
    using System.Security.Principal;
    using System.Collections.Generic;
    using System.Threading;
    using System.ServiceModel.Diagnostics; 
    using System.ServiceModel.Activation.Diagnostics;
    using System.ServiceModel.Activation.Configuration; 
    using System.ServiceModel.Channels; 
    using System.ComponentModel;
    using System.Globalization; 
    using EventLogCategory = System.ServiceModel.Diagnostics.EventLogCategory;
    using EventLogEventId = System.ServiceModel.Diagnostics.EventLogEventId;

    abstract class SharingService 
    {
        static object thisLock = new object(); 
 
        Guid controlServiceGuid;
        bool isPaused; 
        ServiceHostBase controlServiceHost;
        SharedMemory sharedMemory;
        string sharedMemoryName;
        string serviceName; 
        TransportType transportType;
 
        public const bool CanHandlePowerEvent = false; 
        public const bool AutoLog = false;
        public const bool CanStop = true; 
        public const bool CanShutdown = true;

        protected SharingService(TransportType transportType, string serviceName, string sharedMemoryName)
        { 
            this.serviceName = serviceName;
            this.transportType = transportType; 
            this.sharedMemoryName = sharedMemoryName; 
        }
 
        static Binding CreateRegisterBinding(TransportType transportType)
        {
            NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
            binding.MaxReceivedMessageSize = ListenerConstants.RegistrationMaxReceivedMessageSize; 
            CustomBinding customBinding = new CustomBinding(binding);
            NamedPipeTransportBindingElement namedPipeBindingElement = customBinding.Elements.Find(); 
            namedPipeBindingElement.ExposeConnectionProperty = true; 
            namedPipeBindingElement.AllowedUsers = ListenerConfig.GetAllowAccounts(transportType);
            customBinding.ReceiveTimeout = TimeSpan.MaxValue; 
            return customBinding;
        }

        public bool IsPaused { get { return isPaused; } } 
        static object ThisLock { get { return thisLock; } }
 
#if DEBUG 
        bool IsHealthy()
        { 
            try
            {
                return controlServiceGuid.ToString().Equals(SharedMemory.Read(sharedMemoryName));
            } 
            catch (Win32Exception)
            { 
                return false; 
            }
        } 
#endif

        public void OnContinue()
        { 
            isPaused = false;
        } 
 
        public void OnPause()
        { 
            isPaused = true;
        }

        public void OnShutdown() 
        {
            Shutdown(); 
        } 

        public void Start() 
        {
            isPaused = false;

            GrantPermissionToAllowedAccounts(); 
            StartControlService();
            CreateSharedMemory(); 
        } 

        void GrantPermissionToAllowedAccounts() 
        {
            // SECURITY
            // we need to do this to allow services to lookup our LogonSid and ProcessToken User
            lock (ThisLock) 
            {
                Utility.AddRightGrantedToAccounts(ListenerConfig.GetAllowAccounts(this.transportType), 
                    ListenerUnsafeNativeMethods.PROCESS_QUERY_INFORMATION, true); 

                Utility.AddRightGrantedToAccounts(ListenerConfig.GetAllowAccounts(this.transportType), 
                    ListenerUnsafeNativeMethods.TOKEN_QUERY, false);
            }
        }
 
        void StartControlService()
        { 
            controlServiceHost = null; 
            Exception lastException = null;
            for (int iteration = 0; iteration < ListenerConstants.MaxRetries; iteration++) 
            {
                controlServiceGuid = Guid.NewGuid();
                string listenerEndPoint = controlServiceGuid.ToString();
                try 
                {
                    Type contractType; 
                    if (transportType == TransportType.Tcp) 
                    {
                        contractType = typeof(TcpWorkerProcess); 
                    }
                    else
                    {
                        contractType = typeof(NamedPipeWorkerProcess); 
                    }
 
                    ServiceHost typedServiceHost = new ServiceHost(contractType, 
                        Utility.FormatListenerEndpoint(serviceName, listenerEndPoint));
                    typedServiceHost.ServiceThrottle.MaxConcurrentSessions = ListenerConstants.RegistrationMaxConcurrentSessions; 
                    typedServiceHost.Description.Behaviors.Remove(typeof(ServiceMetadataBehavior));
                    typedServiceHost.AddServiceEndpoint(typeof(IConnectionRegister),
                        CreateRegisterBinding(this.transportType), string.Empty);
 
                    controlServiceHost = typedServiceHost;
                    controlServiceHost.Open(); 
                    break; 
                }
                catch (CommunicationException exception) 
                {
                    if (DiagnosticUtility.ShouldTraceWarning)
                    {
                        ListenerTraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.ServiceStartPipeError, this, exception); 
                    }
 
                    lastException = exception; 
                    controlServiceHost = null;
                } 
            }

            if (controlServiceHost == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(SR.GetString(SR.ServiceStartErrorEndpoint, this.serviceName), 
                    lastException)); 
            }
        } 

        void CreateSharedMemory()
        {
            try 
            {
                sharedMemory = SharedMemory.Create(ListenerConstants.GlobalPrefix + sharedMemoryName, controlServiceGuid, 
                    ListenerConfig.GetAllowAccounts(this.transportType)); 

                Debug.Print("SharedMemory.Create() sharedMemoryName: " + sharedMemoryName); 
            }
            catch (Win32Exception exception)
            {
                Debug.Print("SharedMemory.Create() exception: " + exception); 
                DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
                    EventLogCategory.SharingService, 
                    EventLogEventId.StartErrorPublish, 
                    exception.ToString());
 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(SR.GetString(SR.ServiceStartErrorPublish, this.serviceName),
                    exception));
            } 
        }
 
        public void OnStop() 
        {
            Shutdown(); 
        }

        void Shutdown()
        { 
            try
            { 
                if (sharedMemory != null) 
                {
                    sharedMemory.Dispose(); 
                }

                MessageQueue.CloseAll(transportType);
            } 
#pragma warning suppress 56500 // [....], catch block unconditionally fails fast
            catch (Exception exception) 
            { 
                if (DiagnosticUtility.ShouldTraceError)
                { 
                    ListenerTraceUtility.TraceEvent(TraceEventType.Error, TraceCode.ServiceShutdownError, this, exception);
                }

                if (DiagnosticUtility.IsFatal(exception)) 
                {
                    throw; 
                } 

                // We exit the service gracefully so that other services that share the process will not be affected. 
            }
            finally
            {
                if (controlServiceHost != null) 
                {
                    controlServiceHost.Abort(); 
                } 
            }
        } 

#if DEBUG
        public void OnCustomCommand(int command)
        { 
            switch (command)
            { 
                case (int)CustomCommand.DumpTable: 
                    RoutingTable.DumpTables(transportType);
                    break; 
                case (int)CustomCommand.CheckHealth:
                    DiagnosticUtility.DebugAssert(IsHealthy(), "Not healthy, killing ourselves!");
                    break;
                default: 
                    break;
            } 
        } 
#endif
    } 
#if DEBUG
    enum CustomCommand
    {
        DumpTable = 129, 
        CheckHealth = 130,
    } 
#endif 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK