MsdtcWrapper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Tools / WSATConfig / Configuration / MsdtcWrapper.cs / 1305376 / MsdtcWrapper.cs

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

namespace Microsoft.Tools.ServiceModel.WsatConfig 
{
    using System; 
    using System.Collections.Generic; 
    using System.Text;
 
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;

    using System.Management; 
    using System.ServiceProcess;
    using System.IO; 
 
    class MsdtcWrapper
    { 
        // the wrapper cache. one entry for one machine name
        // the cache is ever-growing in size, but this does not matter given the characteristics
        // the program
        static Dictionary wrappers = new Dictionary(); 
        // the GUID of the IDtcNetworkAccessConfig interface
        static Guid IDtcNetworkAccessConfigInterfaceId = typeof(IDtcNetworkAccessConfig).GUID; 
 
        IDtcNetworkAccessConfig proxy;
        ConfigurationProvider configProvider; 

        ServiceController controller;
        string machineName;
        string virtualServerName; 

        static string GetTransactionManagerHostName(string machineName, string virtualServerName) 
        { 
            if (MsdtcClusterUtils.IsClusterServer(machineName))
            { 
                if (!string.IsNullOrEmpty(virtualServerName))
                {
                    return virtualServerName;
                } 
                return Utilities.IsLocalMachineName(machineName) ? Utilities.LocalHostName : machineName;
            } 
 
            return Utilities.IsLocalMachineName(machineName) ? string.Empty : machineName;
        } 

        internal static MsdtcWrapper GetWrapper(string machineName, string virtualServerName, ConfigurationProvider configProvider)
        {
            MsdtcWrapper wrapper; 

            string key = GetTransactionManagerHostName(machineName, virtualServerName); 
            wrappers.TryGetValue(key, out wrapper); 
            if (wrapper == null)
            { 
                wrapper = new MsdtcWrapper(machineName, virtualServerName, configProvider);
                wrappers.Add(key, wrapper);
            }
            return wrapper; 
        }
 
        MsdtcWrapper(string machineName, string virtualServerName, ConfigurationProvider configProvider) 
        {
            if (configProvider == null) 
            {
                throw new ArgumentNullException("configProvider");
            }
 
            this.machineName = machineName;
            this.virtualServerName = virtualServerName; 
            this.configProvider = configProvider; 

            this.proxy = null; 

            int hr;

            string hostName = GetTransactionManagerHostName(machineName, virtualServerName); 
            if (IsLongHornClusterLocalDtc(machineName, virtualServerName))
            { 
                SafeNativeMethods.OLE_TM_CONFIG_PARAMS_V2 configParams = new SafeNativeMethods.OLE_TM_CONFIG_PARAMS_V2(); 
                configParams.dwVersion = SafeNativeMethods.OLE_TM_CONFIG_VERSION_2;
                configParams.pwszClusterResourceName = "LOCAL"; 

                hr = SafeNativeMethods.DtcGetTransactionManagerEx_WithConfigParams(
                    hostName,
                    string.Empty, 
                    ref IDtcNetworkAccessConfigInterfaceId,
                    SafeNativeMethods.OLE_TM_FLAG_NONE, 
                    ref configParams, 
                    out proxy);
            } 
            else
            {
                hr = SafeNativeMethods.DtcGetTransactionManagerEx(
                            hostName, 
                            string.Empty,
                            ref IDtcNetworkAccessConfigInterfaceId, 
                            SafeNativeMethods.OLE_TM_FLAG_NONE, 
                            IntPtr.Zero,
                            out proxy); 
            }

            if (proxy == null)
            { 
                // Chances are we are on a XP machine; even on XP SP2 this interface is not available
                Utilities.Log("Unable to query IDtcNetworkAccessConfig" + hr); 
 
                if (Utilities.IsLocalMachineName(machineName))
                { 
                    controller = new System.ServiceProcess.ServiceController("MSDTC");
                }
                else
                { 
                    // We do not use ServiceController to control remote services for secuirty concerns - use WMI remote process invocation to do that
                    controller = null; 
                } 
            }
        } 

        static bool IsLongHornClusterLocalDtc(string machineName, string virtualServerName)
        {
            if (Utilities.GetOSMajor(machineName) > 5 && MsdtcClusterUtils.IsClusterServer(machineName)) 
            {
                if (string.IsNullOrEmpty(virtualServerName)) 
                { 
                    return true;
                } 
            }
            return false;
        }
 
        // Get whether the NetworkTransactions are enabled
        // it uses a fallback strategy: if the proxy could not be instantiated, it tries to read registry to find out 
        internal bool GetNetworkTransactionAccess() 
        {
            if (proxy != null) 
            {
                try
                {
                    bool retVal = false; 
                    proxy.GetNetworkTransactionAccess(ref retVal);
                    return retVal; 
                } 
                catch (COMException e)
                { 
                    if (!IsLongHornClusterLocalDtc(machineName, virtualServerName))
                    {
                        throw new WsatAdminException(WsatAdminErrorCode.CANNOT_GET_MSDTC_NETWORK_ACCESS_SETTING,
                             SR.GetString(SR.ErrorCannotGetMsdtcNetworkAccessSetting, e.Message), e); 
                    }
                    // Otherwise, it's very likely that, due to WinOS bug 1455344, we are not able to call 
                    // proxy.GetNetworkTransactionAccess on a local DTC TM of a LHS cluster. 
                    // The workaround is to determine network transaction access by msdtc security registry settings
                } 
                catch (UnauthorizedAccessException e)
                {
                    throw new WsatAdminException(WsatAdminErrorCode.MSDTC_NETWORK_ACCESS_DENIED,
                                                 SR.GetString(SR.ErrorMsdtcNetworkAccessDenied), e); 
                }
                catch (FileNotFoundException e) 
                { 
                    throw new WsatAdminException(WsatAdminErrorCode.CANNOT_GET_MSDTC_NETWORK_ACCESS_SETTING,
                                                SR.GetString(SR.ErrorCannotGetMsdtcNetworkAccessSettingWithDiagnostics), e); 
                }
            }

            return DetermineNetworkTransactionAccessByRegistrySettings(); 
        }
 
        bool DetermineNetworkTransactionAccessByRegistrySettings() 
        {
            ConfigurationProvider dtcSecurityConfigProvider = configProvider.OpenKey(WsatKeys.MsdtcSecurityKey); 
            bool networkDtcAccess, networkDtcAccessInbound, networkDtcAccessOutbound, networkDtcAccessTransactions;
            networkDtcAccess = (dtcSecurityConfigProvider.ReadUInt32(NetworkDtcAccessRegValues.NetworkDtcAccess, 0) != 0);
            networkDtcAccessInbound = (dtcSecurityConfigProvider.ReadUInt32(NetworkDtcAccessRegValues.NetworkDtcAccessInbound, 0) != 0);
            networkDtcAccessOutbound = (dtcSecurityConfigProvider.ReadUInt32(NetworkDtcAccessRegValues.NetworkDtcAccessOutbound, 0) != 0); 
            networkDtcAccessTransactions = (dtcSecurityConfigProvider.ReadUInt32(NetworkDtcAccessRegValues.NetworkDtcAccessTransactions, 0) != 0);
            return (networkDtcAccess && (networkDtcAccessInbound || networkDtcAccessOutbound) && networkDtcAccessTransactions); 
        } 

        static class NetworkDtcAccessRegValues 
        {
            public const string NetworkDtcAccess = "NetworkDtcAccess";
            public const string NetworkDtcAccessInbound = "NetworkDtcAccessInbound";
            public const string NetworkDtcAccessOutbound = "NetworkDtcAccessOutbound"; 
            public const string NetworkDtcAccessTransactions = "NetworkDtcAccessTransactions";
        } 
 
        // Restarts the MSDTC_NOTIF for the local/remote machine
        // it uses a fallback strategy: if the proxy could not be instantiated, 
        // it tries will restart MSDTC_NOTIF by using the ServiceController class
        // The proxy ONLY works on Windows VISTA
        internal void RestartDtcService()
        { 
            if (proxy != null)
            { 
                int hr = proxy.RestartDtcService(); 
                if (hr != 0)
                { 
                    throw new WsatAdminException(WsatAdminErrorCode.DTC_RESTART_ERROR, SR.GetString(SR.ErrorRestartMSDTCWithErrorCode, hr));
                }
            }
            else 
            {
                System.Diagnostics.Debug.Assert(controller != null, 
                                                "Do not call RestartDtcService for remote machines, use SaveRemote instead!"); 
                if (controller.Status != System.ServiceProcess.ServiceControllerStatus.Stopped)
                { 
                    if (controller.Status != System.ServiceProcess.ServiceControllerStatus.StopPending)
                    {
                        if (controller.CanStop)
                        { 
                            controller.Stop();
                        } 
                        else 
                        {
                            throw new WsatAdminException(WsatAdminErrorCode.DTC_RESTART_ERROR, SR.GetString(SR.ErrorRestartMSDTC)); 
                        }
                    }

                    controller.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30)); 
                    if (controller.Status != System.ServiceProcess.ServiceControllerStatus.Stopped)
                    { 
                        throw new WsatAdminException(WsatAdminErrorCode.DTC_RESTART_ERROR, SR.GetString(SR.ErrorRestartMSDTC)); 
                    }
                } 

                controller.Start();
                controller.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running, TimeSpan.FromSeconds(30));
                if (controller.Status != System.ServiceProcess.ServiceControllerStatus.Running) 
                {
                    throw new WsatAdminException(WsatAdminErrorCode.DTC_RESTART_ERROR, SR.GetString(SR.ErrorRestartMSDTC)); 
                } 
            }
        } 
    }

    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("9797C15D-A428-4291-87B6-0995031A678D")]
    interface IDtcNetworkAccessConfig 
    {
        void GetAnyNetworkAccess( 
            /* [out] */ ref bool anyNetworkAccess); 

        void SetAnyNetworkAccess( 
            /* [in] */ bool anyNetworkAccess);

        void GetNetworkAdministrationAccess(
            /* [out] */ ref bool networkAdministrationAccess); 

        void SetNetworkAdministrationAccess( 
            /* [in] */ bool networkAdministrationAccess); 

        void GetNetworkTransactionAccess( 
            /* [out] */ ref bool networkTransactionAccess);

        void SetNetworkTransactionAccess(
            /* [in] */ bool networkTransactionAccess); 

        void GetNetworkClientAccess( 
            /* [out] */ ref bool networkClientAccess); 

        void SetNetworkClientAccess( 
            /* [in] */ bool networkClientAccess);

        void GetNetworkTipAccess(
            /* [out] */ ref bool networkTipAccess); 

        void SetNetworkTipAccess( 
            /* [in] */ bool networkTipAccess); 

        void GetXAAccess( 
            /* [out] */ ref bool xaAccess);

        void SetXAAccess(
            /* [in] */ bool xaAccess); 

        [PreserveSig()] 
        int RestartDtcService(); 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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