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

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

namespace Microsoft.Tools.ServiceModel.WsatConfig 
{
    using System; 
    using System.IO; 
    using System.Management;
    using System.Runtime.InteropServices; 
    using System.Security;
    using System.Security.AccessControl;
    using System.Security.Principal;
    using Microsoft.Win32; 

    class StdRegProviderWrapper : IDisposable 
    { 
        ManagementClass regClassInstance;
        string subKey; 
        uint hiveValue;

        bool ensuredSubKeyExists;
        bool ensuredReadAccess; 
        bool ensuredWriteAccess;
 
        RegistryExceptionHelper registryExceptionHelper; 

        static class StdRegProvMethods 
        {
            public const string GetDwordValue = "GetDWORDValue";
            public const string GetStringValue = "GetStringValue";
            public const string GetMultiStringValue = "GetMultiStringValue"; 
            public const string SetDwordValue = "SetDWORDValue";
            public const string SetStringValue = "SetStringValue"; 
            public const string SetMultiStringValue = "SetMultiStringValue"; 
            public const string EnumKey = "EnumKey";
            public const string CreateRegistryKey = "CreateKey"; 
            public const string CheckAccess = "CheckAccess";
        }

        static class InputParameters 
        {
            public const string DefKey = "hDefKey"; 
            public const string SubKeyName = "sSubKeyName"; 
            public const string ValueName = "sValueName";
            public const string AccessPermission = "uRequired"; 

            public const string DwordValueKey = "uValue";
            public const string StringValueKey = "sValue";
        } 

        static class OutputParameters 
        { 
            public const string IsAccessGranted = "bGranted";
            public const string SubKeyNames = "sNames"; 
            public const string ReturnValue = "ReturnValue";
        }

        public StdRegProviderWrapper(RegistryHive registryHive, string subKey, string machineName) 
        {
            switch (registryHive) 
            { 
                case RegistryHive.ClassesRoot:
                    this.hiveValue = 0x80000000; 
                    break;
                case RegistryHive.CurrentUser:
                    this.hiveValue = 0x80000001;
                    break; 
                case RegistryHive.LocalMachine:
                    this.hiveValue = 0x80000002; 
                    break; 
                default:
                    // We do not support other values here 
                    throw new ArgumentException("remoteHive");
            }

            registryExceptionHelper = new RegistryExceptionHelper(machineName, registryHive, subKey); 

            try 
            { 
                ConnectionOptions co = null;
 
                if (Utilities.IsLocalMachineName(machineName))
                {
                    machineName = "localhost";
                } 
                else
                { 
                    co = new ConnectionOptions(); 
                    co.Authentication = AuthenticationLevel.PacketPrivacy;
                    co.Impersonation = ImpersonationLevel.Impersonate; 
                }

                ManagementScope managementScope = new ManagementScope("\\\\" + machineName + "\\root\\DEFAULT", co);
                ManagementPath managementPath = new ManagementPath("StdRegProv"); 
                ObjectGetOptions options = new ObjectGetOptions(new ManagementNamedValueCollection(), TimeSpan.FromSeconds(15), false);
                this.regClassInstance = new ManagementClass(managementScope, managementPath, options); 
                this.subKey = subKey; 
            }
            catch (ManagementException e) 
            {
                throw registryExceptionHelper.CreateRegistryAccessException(e);
            }
            catch (COMException e) // for RPC_S_SERVER_UNAVAILABLE sort of errors 
            {
                throw registryExceptionHelper.CreateRegistryAccessException(e); 
            } 
        }
 
        StdRegProviderWrapper(uint hiveValue, string subKey, ManagementClass regClassInstance)
        {
            this.hiveValue = hiveValue;
            this.subKey = subKey; 
            this.registryExceptionHelper = new RegistryExceptionHelper(subKey);
            this.regClassInstance = new ManagementClass(regClassInstance.Path, regClassInstance.Options); 
        } 

        internal StdRegProviderWrapper OpenKey(string subKey) 
        {
            string s = this.subKey;
            RegistryExceptionHelper.EnsureEndsWithSlash(ref s);
 
            s += subKey;
 
            return new StdRegProviderWrapper(this.hiveValue, s, regClassInstance); 
        }
 
        internal uint ReadUInt32(string name, uint defaultValue)
        {
            return (uint)DoReadData(name, InputParameters.DwordValueKey, defaultValue, StdRegProvMethods.GetDwordValue);
        } 

        internal string ReadString(string name, string defaultValue) 
        { 
            return (string)DoReadData(name, InputParameters.StringValueKey, defaultValue, StdRegProvMethods.GetStringValue);
        } 

        internal string[] ReadMultiString(string name, string[] defaultValue)
        {
            return (string[])DoReadData(name, InputParameters.StringValueKey, defaultValue, StdRegProvMethods.GetMultiStringValue); 
        }
 
        internal void WriteUInt32(string name, uint value) 
        {
            DoWriteData(name, InputParameters.DwordValueKey, value, StdRegProvMethods.SetDwordValue); 
        }

        internal void WriteString(string name, string value)
        { 
            DoWriteData(name, InputParameters.StringValueKey, value, StdRegProvMethods.SetStringValue);
        } 
 
        internal void WriteMultiString(string name, string[] value)
        { 
            DoWriteData(name, InputParameters.StringValueKey, value, StdRegProvMethods.SetMultiStringValue);
        }

        object DoReadData(string name, string valueKey, object defaultValue, string readMethod) 
        {
            EnsureReadAccess(); 
 
            try
            { 
                ManagementBaseObject inParams = regClassInstance.GetMethodParameters(readMethod);

                inParams[InputParameters.DefKey] = this.hiveValue;
                inParams[InputParameters.SubKeyName] = subKey; 
                inParams[InputParameters.ValueName] = name;
 
                ManagementBaseObject outParams = regClassInstance.InvokeMethod(readMethod, 
                                                                                inParams, null);
                uint ret = (uint)outParams[OutputParameters.ReturnValue]; 
                if (ret == 0) // zero means success
                {
                    return outParams[valueKey];
                } 
                return defaultValue;
            } 
#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.CreateRegistryAccessException(name, e); 
            }
        } 

        void DoWriteData(string name, string valueKey, object value, string writeMethod)
        {
            EnsureSubKeyExists(); 
            EnsureWriteAccess();
 
            try 
            {
                ManagementBaseObject inParams = regClassInstance.GetMethodParameters(writeMethod); 

                inParams[InputParameters.DefKey] = this.hiveValue;
                inParams[InputParameters.SubKeyName] = subKey;
                inParams[InputParameters.ValueName] = name; 
                inParams[valueKey] = value;
 
                ManagementBaseObject outParams = regClassInstance.InvokeMethod(writeMethod, 
                                                                                inParams, null);
                uint ret = (uint)outParams[OutputParameters.ReturnValue]; 
                if (ret != 0) // zero means success
                {
                    string registryKey = this.subKey;
                    RegistryExceptionHelper.EnsureEndsWithSlash(ref registryKey); 
                    registryKey += name;
 
                    registryExceptionHelper.CreateRegistryWriteException(registryKey, null); 
                }
            } 
#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.CreateRegistryAccessException(name, e);
            }
        }
 
        void EnsureSubKeyExists()
        { 
            try 
            {
                if (!ensuredSubKeyExists) 
                {
                    ManagementBaseObject inParams = regClassInstance.GetMethodParameters(StdRegProvMethods.CreateRegistryKey);
                    inParams[InputParameters.DefKey] = this.hiveValue;
                    inParams[InputParameters.SubKeyName] = this.subKey; 

                    ManagementBaseObject outParams = regClassInstance.InvokeMethod(StdRegProvMethods.CreateRegistryKey, inParams, null); 
                    uint ret = (uint)outParams[OutputParameters.ReturnValue]; 
                    if (ret != 0) // zero means success
                    { 
                        throw registryExceptionHelper.CreateRegistryAccessException(ret);
                    }
                    ensuredSubKeyExists = true;
                } 
            }
#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.CreateRegistryAccessException(e); 
            } 
        }
 
        const uint ERROR_ACCESS_DENIED = 5;

        bool CheckRegistryAccess(UInt32 accessPermission, out bool isAccessGranted)
        { 
            ManagementBaseObject inParams = null;
 
            try 
            {
                inParams = regClassInstance.GetMethodParameters(StdRegProvMethods.CheckAccess); 
            }
#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.CreateRegistryAccessException(e);
            }
 
            inParams[InputParameters.DefKey] = this.hiveValue;
            inParams[InputParameters.SubKeyName] = this.subKey; 
            inParams[InputParameters.AccessPermission] = accessPermission; 

            ManagementBaseObject outParams = regClassInstance.InvokeMethod(StdRegProvMethods.CheckAccess, inParams, null); 
            uint ret = (uint)outParams[OutputParameters.ReturnValue];
            isAccessGranted = (bool)outParams[OutputParameters.IsAccessGranted];
            return ret == 0 || ret == ERROR_ACCESS_DENIED;
        } 

        const UInt32 KEY_QUERY_VALUE = 0x01; 
        const UInt32 KEY_SET_VALUE = 0x02; 

        void EnsureReadAccess() 
        {
            if (!ensuredReadAccess)
            {
                bool accessGranted = false; 
                if (CheckRegistryAccess(KEY_QUERY_VALUE, out accessGranted))
                { 
                    if (!accessGranted) 
                    {
                        throw registryExceptionHelper.CreateRegistryAccessException(null); 
                    }
                    ensuredReadAccess = true;
                }
            } 
        }
 
        void EnsureWriteAccess() 
        {
            if (!ensuredWriteAccess) 
            {
                bool accessGranted = false;
                if (CheckRegistryAccess(KEY_QUERY_VALUE | KEY_SET_VALUE, out accessGranted))
                { 
                    if (!accessGranted)
                    { 
                        throw registryExceptionHelper.CreateRegistryWriteException(null); 
                    }
                    ensuredWriteAccess = true; 
                }
            }
        }
 
        internal void AdjustRegKeyPermission()
        { 
            try 
            {
                RegistryKey regKey; 
                regKey = Registry.LocalMachine.OpenSubKey(
                    WsatKeys.WsatRegKey,
                    RegistryKeyPermissionCheck.ReadWriteSubTree,
                    RegistryRights.FullControl); 

                if (regKey != null) 
                { 
                    using (regKey)
                    { 
                        // NetworkService always needs access to the WS-AT key
                        // On some platforms, it doesn't inherit this permission from the parent MSDTC key
                        RegistryAccessRule rule = new RegistryAccessRule(
                            new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null), 
                            RegistryRights.ReadKey,
                            InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, 
                            PropagationFlags.None, 
                            AccessControlType.Allow);
 
                        // Ensure the authenticated users have read access to the WS-AT key
                        // there is a key under the WS-AT key named OleTxUpgradeEnabled that requires the permission
                        RegistryAccessRule rule2 = new RegistryAccessRule(
                            new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), 
                            RegistryRights.ReadKey,
                            InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, 
                            PropagationFlags.None, 
                            AccessControlType.Allow);
 
                        RegistrySecurity registrySecurity = regKey.GetAccessControl();
                        registrySecurity.AddAccessRule(rule);
                        registrySecurity.AddAccessRule(rule2);
                        regKey.SetAccessControl(registrySecurity); 
                    }
                } 
            } 
            catch (SecurityException e)
            { 
                throw registryExceptionHelper.CreateRegistryWriteException(e);
            }
            catch (ObjectDisposedException e)
            { 
                throw registryExceptionHelper.CreateRegistryWriteException(e);
            } 
            catch (ArgumentNullException e) 
            {
                throw registryExceptionHelper.CreateRegistryWriteException(e); 
            }
            catch (ArgumentException e)
            {
                throw registryExceptionHelper.CreateRegistryWriteException(e); 
            }
            catch (UnauthorizedAccessException e) 
            { 
                throw registryExceptionHelper.CreateRegistryWriteException(e);
            } 
        }

        public void Dispose()
        { 
            if(regClassInstance != null)
            { 
                regClassInstance.Dispose(); 
                regClassInstance = 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