ClusterUtils.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 / TransactionBridge / Microsoft / Transactions / Wsat / Clusters / ClusterUtils.cs / 1 / ClusterUtils.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
using System;
using System.Diagnostics; 
using System.Runtime.InteropServices;
using System.Text; 
 
using Microsoft.Transactions.Bridge;
using Microsoft.Transactions.Wsat.Messaging; 
using Microsoft.Transactions.Wsat.Protocol;
using Microsoft.Win32;

namespace Microsoft.Transactions.Wsat.Clusters 
{
    static class ClusterUtils 
    { 
        public static SafeHResource GetTransactionManagerClusterResource(string virtualServerName,
                                                                         string transactionManagerResourceType) 
        {
            if (DebugTrace.Info)
                DebugTrace.Trace(TraceLevel.Info,
                                "Looking for cluster resource of type {0} dependent on network name {1}", 
                                transactionManagerResourceType,
                                virtualServerName); 
 
            SafeHCluster hCluster = SafeNativeMethods.OpenCluster(null);
            if (hCluster.IsInvalid) 
            {
                int gle = Marshal.GetLastWin32Error();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new ConfigurationProviderException(SR.GetString(SR.OpenClusterFailed, gle))); 
            }
 
            using (hCluster) 
            {
                SafeHClusEnum hEnum = SafeNativeMethods.ClusterOpenEnum(hCluster, ClusterEnum.Resource); 
                if (hEnum.IsInvalid)
                {
                    int gle = Marshal.GetLastWin32Error();
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                        new ConfigurationProviderException(SR.GetString(SR.ClusterOpenEnumFailed, gle)));
                } 
 
                using (hEnum)
                { 
                    uint index = 0;
                    while (true)
                    {
                        SafeHResource hResource = GetResourceFromEnumeration(hCluster, hEnum, index); 
                        if (hResource == null)
                        { 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                                new ConfigurationProviderException(SR.GetString(SR.ClusterResourceNotFound, virtualServerName)));
                        } 

                        try
                        {
                            if (IsTransactionManager(hResource, virtualServerName, transactionManagerResourceType)) 
                                return hResource;
                        } 
                        catch 
                        {
                            hResource.Dispose(); 
                            throw;
                        }

                        index++; 
                    }
                } 
            } 
        }
 
        static bool IsTransactionManager(SafeHResource hResource,
                                         string virtualServerName,
                                         string transactionManagerResourceType)
        { 
            string resourceType = GetResourceType(hResource);
            if (DebugTrace.Verbose) 
                DebugTrace.Trace(TraceLevel.Verbose, "Examining cluster resource of type {0}", resourceType); 

            if (string.Compare(resourceType, 
                               transactionManagerResourceType,
                               StringComparison.OrdinalIgnoreCase) == 0)
            {
                // It's a TM resource 
                string networkName = GetResourceNetworkName(hResource);
                if (DebugTrace.Verbose) 
                    DebugTrace.Trace(TraceLevel.Verbose, "Dependent network name is {0}", networkName); 

                if (string.Compare(networkName, 
                                   virtualServerName,
                                   StringComparison.OrdinalIgnoreCase) == 0)
                {
                    return true; 
                }
            } 
 
            return false;
        } 

        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);
 
            bool ret = SafeNativeMethods.GetClusterResourceNetworkName(hResource, sb, ref cch);
            int gle = Marshal.GetLastWin32Error();

            if (ret) 
                return sb.ToString();
 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                new ConfigurationProviderException(SR.GetString(SR.GetClusterResourceNetworkNameFailed, gle)));
        } 

        static SafeHResource GetResourceFromEnumeration(SafeHCluster hCluster,
                                                        SafeHClusEnum hEnum,
                                                        uint index) 
        {
            uint type, cch = 0; 
            uint ret = SafeNativeMethods.ClusterEnum(hEnum, index, out type, null, ref cch); 
            if (ret == SafeNativeMethods.ERROR_NO_MORE_ITEMS)
                // The enumeration is complete 
                return null;

            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();
                    if (DebugTrace.Verbose)
                        DebugTrace.Trace(TraceLevel.Verbose, "Opening cluster resource {0}", resourceName); 

                    SafeHResource hResource = SafeNativeMethods.OpenClusterResource(hCluster, resourceName); 
                    if (hResource.IsInvalid) 
                    {
                        int gle = Marshal.GetLastWin32Error(); 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                            new ConfigurationProviderException(SR.GetString(SR.OpenClusterResourceFailed, gle)));
                    }
                    return hResource; 
                }
            } 
 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                new ConfigurationProviderException(SR.GetString(SR.ClusterEnumFailed, ret))); 
        }

        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; 
                }
            } 
 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                new ConfigurationProviderException(SR.GetString(SR.ClusterResourceControlFailed, code, ret))); 
        }

        static string IssueClusterResourceControlString(SafeHResource hResource,
                                                        ClusterResourceControlCode code) 
        {
            byte[] buffer = IssueClusterResourceControl(hResource, code); 
            try 
            {
                return Encoding.Unicode.GetString(buffer, 0, buffer.Length - 2); 
            }
            catch (ArgumentException e)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                    new ConfigurationProviderException(SR.GetString(SR.ClusterResourceControlInvalidResults, code), e));
            } 
        } 
    }
} 

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