MsdtcClusterUtils.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 / MsdtcClusterUtils.cs / 1305376 / MsdtcClusterUtils.cs

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

namespace Microsoft.Tools.ServiceModel.WsatConfig 
{
    using System; 
    using System.Diagnostics; 
    using System.Runtime.InteropServices;
    using System.Security.Permissions; 
    using System.Collections.Generic;
    using System.Text;

    using Microsoft.Win32; 

    static class MsdtcClusterUtils 
    { 
        static string clusterName = null;
        const string MsdtcResourceTypeName = "Distributed Transaction Coordinator"; 

        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        internal static bool IsClusterServer(string machineName)
        { 
#pragma warning suppress 56523
            SafeHCluster hCluster = SafeNativeMethods.OpenCluster(Utilities.IsLocalMachineName(machineName) ? null : machineName); 
            bool result = false; 
            using (hCluster)
            { 
                result = !hCluster.IsInvalid;
            }
            return result;
        } 

#if WSAT_UI 
        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] 
        internal static bool ResolveVirtualServerName(string machineName, string dtcResourceName, out string virtualServer)
        { 
            virtualServer = string.Empty;
#pragma warning suppress 56523
            SafeHCluster hCluster = SafeNativeMethods.OpenCluster(Utilities.IsLocalMachineName(machineName) ? null : machineName);
            if (hCluster.IsInvalid) 
            {
                return false; 
            } 

            using (hCluster) 
            {
#pragma warning suppress 56523
                SafeHClusEnum hEnum = SafeNativeMethods.ClusterOpenEnum(hCluster, ClusterEnum.Resource);
                if (hEnum.IsInvalid) 
                {
                    return false; 
                } 

                using (hEnum) 
                {
                    uint index = 0;
                    bool moreToEnumerate;
                    SafeHResource hResource; 
                    do
                    { 
                        string theResourceName = string.Empty; 
                        moreToEnumerate = GetResourceFromEnumeration(hCluster, hEnum, index, out hResource, out theResourceName);
                        if (moreToEnumerate) 
                        {
                            if (IsTransactionManager(hResource))
                            {
                                if (string.CompareOrdinal(theResourceName, dtcResourceName) == 0) 
                                {
                                    virtualServer = GetResourceNetworkName(hResource); 
                                    return true; 
                                }
                            } 
                            hResource.Dispose();
                            index++;
                        }
                    } while (moreToEnumerate); 
                }
            } 
            return false; 
        }
#endif 

        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        internal static SafeHResource GetTransactionManagerClusterResource(string virtualServerName, out string[] nodes)
        { 
            nodes = null;
 
#pragma warning suppress 56523 
            SafeHCluster hCluster = SafeNativeMethods.OpenCluster(null);
            if (hCluster.IsInvalid) 
            {
                return null;
            }
 
            using (hCluster)
            { 
                //W2k3 cluster 
                if (Utilities.OSMajor <= 5)
                { 
                    if (Utilities.IsLocalMachineName(virtualServerName))
                    {
                        virtualServerName = GetClusterName(hCluster);
                    } 
                }
#pragma warning suppress 56523 
                SafeHClusEnum hEnum = SafeNativeMethods.ClusterOpenEnum(hCluster, ClusterEnum.Resource); 
                if (hEnum.IsInvalid)
                { 
                    return null;
                }

                using (hEnum) 
                {
                    uint index = 0; 
                    bool moreToEnumerate; 
                    SafeHResource hResource;
                    do 
                    {
                        string theResourceName = string.Empty;
                        moreToEnumerate = GetResourceFromEnumeration(hCluster, hEnum, index, out hResource, out theResourceName);
                        if (moreToEnumerate) 
                        {
                            if (IsTransactionManager(hResource)) 
                            { 
                                string networkName = GetResourceNetworkName(hResource);
                                Utilities.Log("Resource network name: " + networkName); 
                                if (Utilities.SafeCompare(networkName, virtualServerName))
                                {
                                    nodes = GetClusterNodes(hCluster);
                                    return hResource; 
                                }
                            } 
                            hResource.Dispose(); 
                            index++;
                        } 
                    } while (moreToEnumerate) ;
                }
            }
 
            return null;
        } 
 
        static string GetClusterName(SafeHCluster hCluster)
        { 
            if (clusterName == null)
            {
                uint cch = 255u;
                StringBuilder sb = new StringBuilder((int)cch); 
                int ret = SafeNativeMethods.GetClusterInformation(
                    hCluster, 
                    sb, 
                    ref cch,
                    IntPtr.Zero); 
                if (ret != SafeNativeMethods.ERROR_SUCCESS || ret == SafeNativeMethods.ERROR_MORE_DATA)
                {
                    if (ret == SafeNativeMethods.ERROR_MORE_DATA)
                    { 
                        sb = new StringBuilder((int)cch);
                        ret = SafeNativeMethods.GetClusterInformation( 
                                                        hCluster, 
                                                        sb,
                                                        ref cch, 
                                                        IntPtr.Zero);
                        if (ret != SafeNativeMethods.ERROR_SUCCESS)
                        {
                            return null; 
                        }
                    } 
                } 
                clusterName = sb.ToString();
            } 
            return clusterName;
        }

        static bool IsTransactionManager(SafeHResource hResource) 
        {
            Utilities.Log("Entered IsTransactionManager - "); 
 
            string resourceType = GetResourceType(hResource);
            Utilities.Log("Resource type name: " + resourceType); 

            return string.CompareOrdinal(resourceType, MsdtcResourceTypeName) == 0;
        }
 
        static string GetResourceType(SafeHResource hResource)
        { 
            return IssueClusterResourceControlString(hResource, ClusterResourceControlCode.GetResourceType); 
        }
 
        static string GetResourceNetworkName(SafeHResource hResource)
        {
            // On Vista and above, this API can be called with null and 0 to discover the true length
            // of the return buffer. However, on Win2003 that causes the API to fail with 
            // ERROR_DEPENDENCY_NOT_FOUND. To play it safe, we simply pre-allocate a buffer up front
            // that should be enough to catch the two possible cases: 
            // - 15-character NetBios names 
            // - 63-character DNS labels
 
            uint cch = 64;
            StringBuilder sb = new StringBuilder((int)cch);
#pragma warning suppress 56523
            if (SafeNativeMethods.GetClusterResourceNetworkName(hResource, sb, ref cch)) 
            {
                return sb.ToString(); 
            } 

            return null; 
        }

        // return true if more items to enumerate, otherwise false
        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] 
        static bool GetResourceFromEnumeration(SafeHCluster hCluster,
                                               SafeHClusEnum hEnum, 
                                               uint index, out SafeHResource hResource, out string theResourceName) 
        {
            uint type, cch = 0; 
            hResource = null;
            theResourceName = string.Empty;

            uint ret = SafeNativeMethods.ClusterEnum(hEnum, index, out type, null, ref cch); 
            if (ret == SafeNativeMethods.ERROR_NO_MORE_ITEMS)
            { 
                return false; 
            }
            else if (ret == SafeNativeMethods.ERROR_SUCCESS || ret == SafeNativeMethods.ERROR_MORE_DATA) 
            {
                StringBuilder sb = new StringBuilder((int)++cch);
                ret = SafeNativeMethods.ClusterEnum(hEnum, index, out type, sb, ref cch);
 
                if (ret == SafeNativeMethods.ERROR_SUCCESS)
                { 
                    string resourceName = sb.ToString(); 

#pragma warning suppress 56523 
                    hResource = SafeNativeMethods.OpenClusterResource(hCluster, resourceName);
                    if (hResource.IsInvalid)
                    {
                        hResource = null; 
                    }
                    else 
                    { 
                        theResourceName = resourceName;
                    } 
                }
            }

            return true; 
        }
 
        static string[] GetClusterNodes(SafeHCluster hCluster) 
        {
#pragma warning suppress 56523 
            SafeHClusEnum hEnum = SafeNativeMethods.ClusterOpenEnum(hCluster, ClusterEnum.Node);
            if (hEnum.IsInvalid)
            {
                return null; 
            }
 
            List nodeList = new List(2); // 2 nodes are a typical cluster configuration 

            using (hEnum) 
            {
                uint ret, index = 0;
                do
                { 
                    uint type, cch = 0;
                    ret = SafeNativeMethods.ClusterEnum(hEnum, index, out type, null, ref cch); 
                    if (ret == SafeNativeMethods.ERROR_NO_MORE_ITEMS) 
                    {
                        break; 
                    }
                    else if (ret == SafeNativeMethods.ERROR_SUCCESS || ret == SafeNativeMethods.ERROR_MORE_DATA)
                    {
                        StringBuilder sb = new StringBuilder((int)++cch); 
                        ret = SafeNativeMethods.ClusterEnum(hEnum, index, out type, sb, ref cch);
                        if (ret == SafeNativeMethods.ERROR_SUCCESS) 
                        { 
                            Utilities.Log("Found a node: [" + sb.ToString() + "]");
                            nodeList.Add(sb.ToString()); 
                        }
                    }
                    index++;
                } while (ret == SafeNativeMethods.ERROR_SUCCESS); 
            }
 
            return nodeList.ToArray(); 
        }
 
        static byte[] IssueClusterResourceControl(SafeHResource hResource,
                                                  ClusterResourceControlCode code)
        {
            uint cb = 0; 
            uint ret = SafeNativeMethods.ClusterResourceControl(hResource,
                                                                IntPtr.Zero, 
                                                                code, 
                                                                IntPtr.Zero,
                                                                0, 
                                                                null,
                                                                0,
                                                                ref cb);
 
            if (ret == SafeNativeMethods.ERROR_SUCCESS || ret == SafeNativeMethods.ERROR_MORE_DATA)
            { 
                byte[] buffer = new byte[cb]; 
                ret = SafeNativeMethods.ClusterResourceControl(hResource,
                                                               IntPtr.Zero, 
                                                               code,
                                                               IntPtr.Zero,
                                                               0,
                                                               buffer, 
                                                               cb,
                                                               ref cb); 
 
                if (ret == SafeNativeMethods.ERROR_SUCCESS)
                { 
                    return buffer;
                }
            }
 
            return null;
        } 
 
        static string IssueClusterResourceControlString(SafeHResource hResource,
                                                        ClusterResourceControlCode code) 
        {
            byte[] buffer = IssueClusterResourceControl(hResource, code);
            if (buffer == null)
            { 
                return null;
            } 
 
            try
            { 
                return Encoding.Unicode.GetString(buffer, 0, buffer.Length - 2);
            }
            catch (ArgumentException)
            { 
                return null;
            } 
        } 
    }
} 

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