ComPlusThreadInitializer.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 / ServiceModel / System / ServiceModel / ComIntegration / ComPlusThreadInitializer.cs / 1 / ComPlusThreadInitializer.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.ComIntegration
{ 
    using System;
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Dispatcher; 
    using System.ServiceModel.Description;
    using System.Security.Principal; 
    using System.ServiceModel;
    using System.Transactions;
    using System.Diagnostics;
    using System.ServiceModel.Diagnostics; 
    using System.EnterpriseServices;
    using SR = System.ServiceModel.SR; 
    using System.Globalization; 

 
    class ComPlusThreadInitializer : ICallContextInitializer
    {
        ServiceInfo info;
        ComPlusAuthorization comAuth; 
        Guid iid;
 
        public ComPlusThreadInitializer(ContractDescription contract, 
                                        DispatchOperation operation,
                                        ServiceInfo info) 
        {
            this.info = info;
            iid = contract.ContractType.GUID;
 
            if (info.CheckRoles)
            { 
                string[] serviceRoleMembers = null; 
                string[] contractRoleMembers = null;
                string[] operationRoleMembers = null; 

                // Figure out the role members we want...
                //
                serviceRoleMembers = info.ComponentRoleMembers; 
                foreach (ContractInfo contractInfo in this.info.Contracts)
                { 
                    if (contractInfo.IID == iid) 
                    {
                        contractRoleMembers = contractInfo.InterfaceRoleMembers; 
                        foreach (OperationInfo opInfo in contractInfo.Operations)
                        {
                            if (opInfo.Name == operation.Name)
                            { 
                                operationRoleMembers = opInfo.MethodRoleMembers;
                                break; 
                            } 
                        }
 
                        if (operationRoleMembers == null)
                        {
                            // Did not find the operation
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ListenerInitFailed( 
                                SR.GetString(SR.ComOperationNotFound,
                                             contract.Name, 
                                             operation.Name))); 
                        }
                        break; 
                    }
                }

                this.comAuth = new ComPlusAuthorization(serviceRoleMembers, 
                                                        contractRoleMembers,
                                                        operationRoleMembers); 
            } 
        }
 
        public object BeforeInvoke(
            InstanceContext instanceContext,
            IClientChannel channel,
            Message message) 
        {
            ComPlusServerSecurity serverSecurity = null; 
            WindowsImpersonationContext impersonateContext = null; 
            bool errorTraced = false;
            WindowsIdentity identity = null; 
            Uri from = null;
            object instance = null;
            int instanceID = 0;
            string action = null; 
            TransactionProxy proxy = null;
            Transaction tx = null; 
            Guid incomingTransactionID = Guid.Empty; 

            // The outer try block is to comply with FXCOP's WrapVulnerableFinallyClausesInOuterTry rule. 
            try
            {
                try
                { 

                    identity = MessageUtil.GetMessageIdentity(message); 
 
                    if (message.Headers.From != null)
                        from = message.Headers.From.Uri; 

                    instance = instanceContext.GetServiceInstance(message);
                    instanceID = instance.GetHashCode();
                    action = message.Headers.Action; 

 
 
                    ComPlusMethodCallTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationInvokingMethod,
                        SR.TraceCodeComIntegrationInvokingMethod, this.info, from, action, identity.Name, iid, instanceID, false); 

                    // Security
                    //
 
                    if (this.info.CheckRoles)
                    { 
                        if (!this.comAuth.IsAuthorizedForOperation(identity)) 
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.CallAccessDenied()); 
                        }
                    }

                    if (this.info.HostingMode != HostingMode.WebHostOutOfProcess) 
                    {
                        // NOTE: This has the side effect of setting up 
                        //       the COM server security thing, so be sure 
                        //       to clear it with Dispose() eventually.
                        // 
                        serverSecurity = new ComPlusServerSecurity(identity,
                                                                   this.info.CheckRoles);
                    }
 
                    // Transactions
                    // 
                    proxy = instanceContext.Extensions.Find(); 
                    if (proxy != null)
                    { 
                        // This makes the Tx header Understood.
                        tx = MessageUtil.GetMessageTransaction(message);
                        if (tx != null)
                        { 
                            incomingTransactionID = tx.TransactionInformation.DistributedIdentifier;
                        } 
                        try 
                        {
                            if (tx != null) 
                            {
                                proxy.SetTransaction(tx);
                            }
                            else 
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.TransactionMismatch()); 
                            } 
                            ComPlusMethodCallTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationInvokingMethodNewTransaction,
                            SR.TraceCodeComIntegrationInvokingMethodNewTransaction, this.info, from, action, identity.Name, iid, instanceID, incomingTransactionID); 
                        }
                        catch (FaultException e)
                        {
                            Transaction txProxy = proxy.CurrentTransaction; 
                            Guid currentTransactionID = Guid.Empty;
                            if (txProxy != null) 
                                currentTransactionID = txProxy.TransactionInformation.DistributedIdentifier; 

                            string identityName = String.Empty; 

                            if(null != identity)
                                identityName = identity.Name;
 
                            DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
                                EventLogCategory.ComPlus, 
                                EventLogEventId.ComPlusInvokingMethodFailedMismatchedTransactions, 
                                incomingTransactionID.ToString("B").ToUpperInvariant (),
                                currentTransactionID.ToString("B").ToUpperInvariant (), 
                                from.ToString(),
                                this.info.AppID.ToString("B").ToUpperInvariant (),
                                this.info.Clsid.ToString("B").ToUpperInvariant (),
                                iid.ToString(), 
                                action,
                                instanceID.ToString(CultureInfo.InvariantCulture), 
                                System.Threading.Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.InvariantCulture), 
                                SafeNativeMethods.GetCurrentThreadId().ToString(CultureInfo.InvariantCulture),
                                identityName, 
                                e.ToString());
                            errorTraced = true;
                            throw;
                        } 
                    }
                    else 
                    { 
                        ComPlusMethodCallTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationInvokingMethodContextTransaction,
                        SR.TraceCodeComIntegrationInvokingMethodContextTransaction, this.info, from, action, identity.Name, iid, instanceID, true); 
                    }

                    // Impersonation
                    // 
                    if (this.info.HostingMode == HostingMode.WebHostOutOfProcess)
                    { 
                        impersonateContext = identity.Impersonate(); 
                    }
 
                    CorrelationState correlationState;
                    correlationState = new CorrelationState(impersonateContext,
                                                            serverSecurity,
                                                            from, 
                                                            action,
                                                            identity.Name, 
                                                            instanceID); 

                    impersonateContext = null; 
                    serverSecurity = null;


                    return correlationState; 
                }
                finally 
                { 
                    if (impersonateContext != null)
                        impersonateContext.Undo(); 

                    if (serverSecurity != null)
                        ((IDisposable)serverSecurity).Dispose();
                } 

            } 
            catch (Exception e) 
            {
                if (errorTraced == false) 
                {
                    if (DiagnosticUtility.ShouldTraceError)
                    {
                         DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error, 
                            EventLogCategory.ComPlus,
                            EventLogEventId.ComPlusInvokingMethodFailed, 
                            from == null ? string.Empty : from.ToString(), 
                            this.info.AppID.ToString("B").ToUpperInvariant (),
                            this.info.Clsid.ToString("B").ToUpperInvariant (), 
                            iid.ToString("B").ToUpperInvariant (),
                            action,
                            instanceID.ToString(CultureInfo.InvariantCulture),
                            System.Threading.Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.InvariantCulture), 
                            SafeNativeMethods.GetCurrentThreadId().ToString(CultureInfo.InvariantCulture),
                            identity.Name, 
                            e.ToString()); 
                    }
                } 
                throw;
            }

        } 

        public void AfterInvoke(object correlationState) 
        { 
            CorrelationState state = (CorrelationState)correlationState;
            if (state != null) 
            {
                ComPlusMethodCallTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationInvokedMethod,
                    SR.TraceCodeComIntegrationInvokedMethod, this.info, state.From, state.Action, state.CallerIdentity, iid, state.InstanceID, false);
                state.Cleanup(); 

            } 
        } 

        class CorrelationState 
        {
            WindowsImpersonationContext impersonationContext;
            ComPlusServerSecurity serverSecurity;
            Uri from; 
            string action;
            string callerIdentity; 
            int instanceID; 

            public CorrelationState(WindowsImpersonationContext context, 
                                    ComPlusServerSecurity serverSecurity,
                                    Uri from,
                                    string action,
                                    string callerIdentity, 
                                    int instanceID)
            { 
                this.impersonationContext = context; 
                this.serverSecurity = serverSecurity;
                this.from = from; 
                this.action = action;
                this.callerIdentity = callerIdentity;
                this.instanceID = instanceID;
            } 
            public Uri From
            { 
                get 
                {
                    return this.from; 
                }
            }

            public string Action 
            {
                get 
                { 
                    return this.action;
                } 
            }
            public string CallerIdentity
            {
                get 
                {
                    return this.callerIdentity; 
                } 
            }
 
            public int InstanceID
            {
                get
                { 
                    return this.instanceID;
                } 
            } 

            public void Cleanup() 
            {
                if (this.impersonationContext != null)
                    this.impersonationContext.Undo();
 
                if (this.serverSecurity != null)
                    ((IDisposable)this.serverSecurity).Dispose(); 
            } 
        }
    } 
}

// 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