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

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
//
// Implement the ConfigurationProvider base class for the cluster registry 
//
//----------------------------------------------------------------------------- 
 
namespace Microsoft.Tools.ServiceModel.WsatConfig
{ 
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.InteropServices; 
    using System.Security.AccessControl;
    using System.Security.Permissions; 
    using System.Security.Principal; 
    using System.Text;
 
    using Microsoft.Win32;

    class ClusterRegistryConfigurationProvider : ConfigurationProvider
    { 
        SafeHKey hKey;
        RegistryExceptionHelper registryExceptionHelper = null; 
        string registryKey; 

        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] 
        internal ClusterRegistryConfigurationProvider(SafeHResource hResource, string key)
        {
            SafeHKey rootKey = SafeNativeMethods.GetClusterResourceKey(hResource,
                                                                RegistryRights.ReadKey | 
                                                                RegistryRights.EnumerateSubKeys |
                                                                RegistryRights.QueryValues); 
            if (rootKey.IsInvalid) 
            {
                int lastError = Marshal.GetLastWin32Error(); 
                throw new WsatAdminException(WsatAdminErrorCode.REGISTRY_ACCESS, SR.GetString(SR.CannotOpenClusterRegistry, lastError));
            }

            if (string.IsNullOrEmpty(key)) 
            {
                hKey = rootKey; 
            } 
            else
            { 
                using (rootKey)
                {
                    int disposition;
                    int ret = SafeNativeMethods.ClusterRegCreateKey(rootKey, 
                                                                    key,
                                                                    SafeNativeMethods.REG_OPTION_NON_VOLATILE, 
                                                                    RegistryRights.FullControl, 
                                                                    IntPtr.Zero,
                                                                    out this.hKey, 
                                                                    out disposition);
                    if (ret != SafeNativeMethods.ERROR_SUCCESS)
                    {
                        throw new WsatAdminException(WsatAdminErrorCode.REGISTRY_ACCESS, SR.GetString(SR.CannotOpenClusterRegistry, ret)); 
                    }
                } 
            } 

            registryExceptionHelper = new RegistryExceptionHelper(key); 
            this.registryKey = key;
            RegistryExceptionHelper.EnsureEndsWithSlash(ref this.registryKey);
        }
 
        ClusterRegistryConfigurationProvider(SafeHKey key, string registryKey)
        { 
            this.hKey = key; 

            this.registryExceptionHelper = new RegistryExceptionHelper(registryKey); 
            this.registryKey = registryKey;
            RegistryExceptionHelper.EnsureEndsWithSlash(ref registryKey);
        }
 
        public override void Dispose()
        { 
            this.hKey = null; 
            GC.SuppressFinalize(this);
        } 

        internal override ConfigurationProvider OpenKey(string subKey)
        {
            SafeHKey hSubKey; 
            int disposition;
            int ret = SafeNativeMethods.ClusterRegCreateKey(hKey, 
                                              subKey, 
                                              SafeNativeMethods.REG_OPTION_NON_VOLATILE,
                                              RegistryRights.FullControl, 
                                              IntPtr.Zero,
                                              out hSubKey,
                                              out disposition);
            if (ret != SafeNativeMethods.ERROR_SUCCESS) 
            {
                throw new WsatAdminException(WsatAdminErrorCode.REGISTRY_ACCESS, SR.GetString(SR.CannotOpenClusterRegistry, ret)); 
            } 

            return new ClusterRegistryConfigurationProvider(hSubKey, registryKey + subKey); 
        }

        byte[] QueryValue(string name, RegistryValueKind valueType)
        { 
            if (this.hKey == null || this.hKey.IsInvalid)
            { 
                return null; 
            }
 
            RegistryValueKind type;
            uint cb = 0;
            int ret = SafeNativeMethods.ClusterRegQueryValue(this.hKey,
                                                             name, 
                                                             out type,
                                                             null, 
                                                             ref cb); 
            Utilities.Log("ClusterRegQueryValue [" + name + "], returned [" + ret + "]");
            if (ret == SafeNativeMethods.ERROR_SUCCESS || ret == SafeNativeMethods.ERROR_MORE_DATA) 
            {
                if (valueType != type)
                {
                    return null; 
                }
 
                byte[] buffer = new byte[cb]; 
                ret = SafeNativeMethods.ClusterRegQueryValue(this.hKey,
                                                             name, 
                                                             out type,
                                                             buffer,
                                                             ref cb);
                if (ret == SafeNativeMethods.ERROR_SUCCESS) 
                {
                    if (valueType != type) 
                    { 
                        return null;
                    } 

                    return buffer;
                }
            } 

            return null; 
        } 

        void WriteValue(string name, byte[] value, RegistryValueKind valueType) 
        {
            if(this.hKey != null && !this.hKey.IsInvalid)
            {
                int ret = SafeNativeMethods.ClusterRegSetValue(this.hKey, 
                                                                name,
                                                                valueType, 
                                                                value, 
                                                                (uint)value.Length);
                if (ret == SafeNativeMethods.ERROR_SUCCESS) 
                {
                    return;
                }
            } 

            throw registryExceptionHelper.CreateRegistryWriteException(name, null); 
        } 

        internal override uint ReadUInt32(string name, uint defaultValue) 
        {
            byte[] buffer = QueryValue(name, RegistryValueKind.DWord);
            if (buffer == null)
            { 
                return defaultValue;
            } 
 
            return (uint)BitConverter.ToUInt32(buffer, 0);
        } 

        internal override void WriteUInt32(string name, uint value)
        {
            byte[] buffer = BitConverter.GetBytes(value); 
            WriteValue(name, buffer, RegistryValueKind.DWord);
        } 
 
/*        internal override ushort ReadUInt16(string name, ushort defaultValue)
        { 
            uint regValue = ReadUInt32(name, defaultValue);

            return (regValue <= (uint)ushort.MaxValue) ? (ushort)regValue : defaultValue;
        }*/ 

        internal override string ReadString(string value, string defaultValue) 
        { 
            byte[] buffer = QueryValue(value, RegistryValueKind.String);
            if (buffer == null || buffer.Length < 2) 
            {
                return defaultValue;
            }
 
            return Encoding.Unicode.GetString(buffer, 0, buffer.Length-2);
        } 
 
        byte[] GetByteArrayFromString(string s)
        { 
#pragma warning suppress 56507
            if (s == null)
            {
                s = string.Empty; 
            }
            byte[] temp = Encoding.Unicode.GetBytes(s); 
            byte[] buffer = new byte[temp.Length + 2]; 
            Array.Copy(temp, buffer, temp.Length);
            buffer[temp.Length] = 0; 
            buffer[temp.Length + 1] = 0;
            return buffer;
        }
 
        internal override void WriteString(string name, string value)
        { 
            byte[] buffer = GetByteArrayFromString(value); 
            WriteValue(name, buffer, RegistryValueKind.String);
        } 

        internal override string[] ReadMultiString(string value, string[] defaultValue)
        {
            byte[] buffer = QueryValue(value, RegistryValueKind.MultiString); 
            if (buffer == null)
            { 
                return defaultValue; 
            }
 
            List list = new List(5);
            string item;
            int index = 0;
            while ((item = GetStringFromMultiSz(value, buffer, ref index)) != null) 
            {
                list.Add(item); 
            } 

            return list.ToArray(); 
        }

        internal override void WriteMultiString(string name, string[] value)
        { 
            int len = 0;
            foreach (string s in value) 
            { 
                if (!string.IsNullOrEmpty(s))
                { 
                    len += s.Length;
                }
            }
 
            byte[] buffer = new byte[(len + value.Length + 1) * 2 ];
            int index = 0; 
            foreach (string s in value) 
            {
                // this alrady contains the null terminator 
                byte[] temp = GetByteArrayFromString(s);
                Array.Copy(temp, 0, buffer, index, temp.Length);
                index += temp.Length;
            } 
            // The very last Unicode NULL
            buffer[index++] = 0; 
            buffer[index++] = 0; 

            WriteValue(name, buffer, RegistryValueKind.MultiString); 
        }


        string GetStringFromMultiSz(string value, byte[] buffer, ref int index) 
        {
            // E.g. abc\0def\0\0 
            // This loop terminates when it finds a null terminating character 
            // The index will be left pointing at the first null terminator it finds
            int start = index; 
            for (;
                 index < buffer.Length - 1 && BitConverter.ToChar(buffer, index) != 0;
                 index += 2) ;
 
            // If we found no valid characters, we're done
            if (start == index) 
            { 
                return null;
            } 

            // Skip past the null terminator at which we stopped
            index += 2;
 
            // Convert the characters we found to a string
            return Encoding.Unicode.GetString(buffer, start, index - start - 2); 
        } 

        internal override void AdjustRegKeyPermission() 
        {
            const uint maxSecurityDescriptorSize = 40960;
            byte[] binarySecurityDescriptor;
            CommonSecurityDescriptor securityDescriptor = null; 
            int ret;
            uint dwSize = 256; 
 
            do
            { 
                binarySecurityDescriptor = new byte[dwSize];
                ret = SafeNativeMethods.ClusterRegGetKeySecurity(hKey, SecurityInfos.DiscretionaryAcl, binarySecurityDescriptor, ref dwSize);
                if (ret == SafeNativeMethods.ERROR_SUCCESS)
                { 
                    break;
                } 
                else if (ret == SafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 
                {
                    dwSize *= 2; 
                }
                else
                {
                    throw registryExceptionHelper.CreateRegistryWriteException(null); 
                }
            } while (dwSize <= maxSecurityDescriptorSize); 
 
            if (dwSize > maxSecurityDescriptorSize)
            { 
                throw registryExceptionHelper.CreateRegistryWriteException(null);
            }

            try 
            {
                securityDescriptor = new CommonSecurityDescriptor(false, false, binarySecurityDescriptor, 0); 
                DiscretionaryAcl dacl = securityDescriptor.DiscretionaryAcl; 
                if (dacl.Count == 1)
                { 
                    CommonAce ace = dacl[0] as CommonAce;
                    if (ace != null && ace.AceType == AceType.AccessAllowed && ace.SecurityIdentifier.IsWellKnown(WellKnownSidType.WorldSid))
                    {
                        // This is the Allowed for everyone full access ACE that's automatically added by 
                        // CommonSecurityDescriptor ctor; we should remove it
                        dacl.Purge(new SecurityIdentifier(WellKnownSidType.WorldSid, null)); 
                    } 
                }
 
                // Add Read access for Authenticated Users account and Network Service account
                dacl.AddAccess(AccessControlType.Allow, new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null),
                    unchecked((int)0x80000000), InheritanceFlags.None, PropagationFlags.None);
                dacl.AddAccess(AccessControlType.Allow, new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null), 
                    unchecked((int)0x80000000), InheritanceFlags.None, PropagationFlags.None);
            } 
            #pragma warning suppress 56500 
            catch (Exception e)
            { 
                // MSDN does not have a spec of possible exceptions for the APIs used above.
                // To be safe, we should be a bit more generic in catching exceptions
                if (Utilities.IsCriticalException(e))
                { 
                    throw;
                } 
                throw registryExceptionHelper.CreateRegistryWriteException(e); 
            }
 
            int dsNewSecDescSize = securityDescriptor.BinaryLength;
            byte[] newBinarySecurityDescriptor = new byte[dsNewSecDescSize];
            securityDescriptor.GetBinaryForm(newBinarySecurityDescriptor, 0);
 
            ret = SafeNativeMethods.ClusterRegSetKeySecurity(hKey, SecurityInfos.DiscretionaryAcl, newBinarySecurityDescriptor);
            if (ret != SafeNativeMethods.ERROR_SUCCESS) 
            { 
                throw registryExceptionHelper.CreateRegistryWriteException(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