SafeNativeMethods.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 / ServiceModel / System / ServiceModel / ComIntegration / SafeNativeMethods.cs / 1 / SafeNativeMethods.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.ComIntegration
{ 
    using System;
    using System.Runtime.InteropServices; 
    using System.Runtime.InteropServices.ComTypes; 
    using System.Security;
    using System.ServiceModel.Security; 
    using System.ServiceModel.Diagnostics;
    using System.Security.Principal;
    using Microsoft.Win32;
    using Microsoft.Win32.SafeHandles; 
    using System.ComponentModel;
    using System.Collections.Specialized; 
    using System.Globalization; 
    using System.Resources;
    using System.Text; 
    using System.Runtime.ConstrainedExecution;
    using System.Security.Permissions;
    using System.Runtime.CompilerServices;
 

    using SafeCloseHandle = System.IdentityModel.SafeCloseHandle; 
    using SafeCloseHandleCritical = System.IdentityModel.SafeCloseHandleCritical; 
    using SafeHGlobalHandle = System.IdentityModel.SafeHGlobalHandle;
 
    [Flags]
    enum CLSCTX
    {
        INPROC_SERVER = 0x1, 
        INPROC_HANDLER = 0x2,
        LOCAL_SERVER = 0x4, 
        INPROC_SERVER16 = 0x8, 
        REMOTE_SERVER = 0x10,
        INPROC_HANDLER16 = 0x20, 
        RESERVED1 = 0x40,
        RESERVED2 = 0x80,
        RESERVED3 = 0x100,
        RESERVED4 = 0x200, 
        NO_CODE_DOWNLOAD = 0x400,
        RESERVED5 = 0x800, 
        NO_CUSTOM_MARSHAL = 0x1000, 
        ENABLE_CODE_DOWNLOAD = 0x2000,
        NO_FAILURE_LOG = 0x4000, 
        DISABLE_AAA = 0x8000,
        ENABLE_AAA = 0x10000,
        FROM_DEFAULT_CONTEXT = 0x20000,
        ACTIVATE_32_BIT_SERVER = 0x40000, 
        ACTIVATE_64_BIT_SERVER = 0x80000,
        INPROC = INPROC_SERVER | INPROC_HANDLER, 
        SERVER = INPROC_SERVER | LOCAL_SERVER | REMOTE_SERVER, 
        ALL = SERVER | INPROC_HANDLER
    } 

    [Flags]
    enum ComRights
    { 
        EXECUTE = 0x01,
        EXECUTE_LOCAL = 0x02, 
        EXECUTE_REMOTE = 0x04, 
        ACTIVATE_LOCAL = 0x08,
        ACTIVATE_REMOTE = 0x10 
    }

    enum TOKEN_INFORMATION_CLASS
    { 
        TokenUser = 1,
        TokenGroups, 
        TokenPrivileges, 
        TokenOwner,
        TokenPrimaryGroup, 
        TokenDefaultDacl,
        TokenSource,
        TokenType,
        TokenImpersonationLevel, 
        TokenStatistics,
        TokenRestrictedSids, 
        TokenSessionId, 
        TokenGroupsAndPrivileges,
        TokenSessionReference, 
        TokenSandBoxInert
    }

    enum SecurityImpersonationLevel 
    {
        Anonymous = 0, 
        Identification = 1, 
        Impersonation = 2,
        Delegation = 3, 
    }

    enum TokenType
    { 
        TokenPrimary = 1,
        TokenImpersonation 
    } 

    enum Win32Error 
    {
        ERROR_SUCCESS = 0,
        ERROR_INSUFFICIENT_BUFFER = 122,
        ERROR_NO_TOKEN = 1008, 
        ERROR_NONE_MAPPED = 1332,
    } 
 
    enum EXTENDED_NAME_FORMAT
    { 
        NameUnknown = 0,
        NameFullyQualifiedDN = 1,
        NameSamCompatible = 2,
        NameDisplay = 3, 
        NameUniqueId = 6,
        NameCanonical = 7, 
        NameUserPrincipalName = 8, 
        NameCanonicalEx = 9,
        NameServicePrincipalName = 10, 
        NameDnsDomainName = 12
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    struct TagVariant
    { 
        public ushort vt; 
        public ushort reserved1;
        public ushort reserved2; 
        public ushort reserved3;
        public IntPtr ptr;
        public IntPtr pRecInfo;
    } 

    static class HR 
    { 
        internal static readonly int S_OK = 0;
        internal static readonly int S_FALSE = 1; 
        internal static readonly int MK_E_SYNTAX = unchecked((int)0x800401e4);
        internal static readonly int E_INVALIDARG = unchecked((int)0x80070057);
        internal static readonly int E_UNEXPECTED = unchecked((int)0x8000ffff);
        internal static readonly int DISP_E_UNKNOWNINTERFACE = unchecked((int)0x80020001); 
        internal static readonly int DISP_E_MEMBERNOTFOUND = unchecked((int)0x80020003);
        internal static readonly int DISP_E_PARAMNOTFOUND = unchecked((int)0x80020004); 
        internal static readonly int DISP_E_TYPEMISMATCH = unchecked((int)0x80020005); 
        internal static readonly int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006);
        internal static readonly int DISP_E_NONAMEDARGS = unchecked((int)0x80020007); 
        internal static readonly int DISP_E_BADVARTYPE = unchecked((int)0x80020008);
        internal static readonly int DISP_E_EXCEPTION = unchecked((int)0x80020009);
        internal static readonly int DISP_E_OVERFLOW = unchecked((int)0x8002000A);
        internal static readonly int DISP_E_BADINDEX = unchecked((int)0x8002000B); 
        internal static readonly int DISP_E_UNKNOWNLCID = unchecked((int)0x8002000C);
        internal static readonly int DISP_E_ARRAYISLOCKED = unchecked((int)0x8002000D); 
        internal static readonly int DISP_E_BADPARAMCOUNT = unchecked((int)0x8002000E); 
        internal static readonly int DISP_E_PARAMNOTOPTIONAL = unchecked((int)0x8002000F);
        internal static readonly int DISP_E_BADCALLEE = unchecked((int)0x80020010); 
        internal static readonly int DISP_E_NOTACOLLECTION = unchecked((int)0x80020011);
        internal static readonly int DISP_E_DIVBYZERO = unchecked((int)0x80020012);
        internal static readonly int DISP_E_BUFFERTOOSMALL = unchecked((int)0x80020013);
        internal static readonly int RPC_E_TOO_LATE = unchecked((int)0x80010119); 
        internal static readonly int RPC_NT_BINDING_HAS_NO_AUTH = unchecked((int)0x800706d2);
        internal static readonly int E_FAIL = unchecked((int)0x80040005); 
        internal static readonly int COMADMIN_E_PARTITIONS_DISABLED = unchecked((int)0x80110824); 
        internal static readonly int CONTEXT_E_NOTRANSACTION = unchecked((int)0x8004E027);
        internal static readonly int ERROR_BAD_IMPERSONATION_LEVEL = unchecked ((int)(0x80070542)); 
    }

    static class InterfaceID
    { 
        public static readonly Guid idISupportErrorInfo = new Guid("{df0b3d60-548f-101b-8e65-08002b2bd119}");
        public static readonly Guid idIDispatch = new Guid("00020400-0000-0000-C000-000000000046"); 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct LUID
    {
        internal uint LowPart;
        internal int HighPart; 
    }
 
 
    [StructLayout(LayoutKind.Sequential)]
    struct TOKEN_STATISTICS 
    {
        internal LUID TokenId;
        internal LUID AuthenticationId;
        internal Int64 ExpirationTime; 
        internal uint TokenType;
        internal SecurityImpersonationLevel ImpersonationLevel; 
        internal uint DynamicCharged; 
        internal uint DynamicAvailable;
        internal uint GroupCount; 
        internal uint PrivilegeCount;
        internal LUID ModifiedId;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    class GENERIC_MAPPING 
    { 
        internal uint genericRead = 0;
        internal uint genericWrite = 0; 
        internal uint genericExecute = 0;
        internal uint genericAll = 0;
    }
 
    [Flags]
    internal enum PrivilegeAttribute : uint 
    { 
        SE_PRIVILEGE_DISABLED = 0x00000000, // note that this is not defined in the header files
        SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001, 
        SE_PRIVILEGE_ENABLED = 0x00000002,
        SE_PRIVILEGE_REMOVED = 0X00000004,
        SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000,
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct LUID_AND_ATTRIBUTES 
    {
        internal LUID Luid; 
        internal PrivilegeAttribute Attributes;
    }

    [StructLayout(LayoutKind.Sequential)] 
    class PRIVILEGE_SET
    { 
        internal uint PrivilegeCount = 1; 
        internal uint Control = 0;
        internal LUID_AND_ATTRIBUTES Privilege; 
    }

    [SuppressUnmanagedCodeSecurity]
    static class SafeNativeMethods 
    {
        internal const String KERNEL32 = "kernel32.dll"; 
        internal const String ADVAPI32 = "advapi32.dll"; 
        internal const String OLE32 = "ole32.dll";
        internal const String OLEAUT32 = "oleaut32.dll"; 
        internal const String COMSVCS = "comsvcs.dll";
        internal const String SECUR32 = "secur32.dll";

        internal const int ERROR_MORE_DATA                 = 0xEA; 
        internal const int ERROR_SUCCESS                   = 0;
        internal const int ERROR_INVALID_HANDLE            = 6; 
        internal const int ERROR_NOT_SUPPORTED             = 50; 
        internal const int READ_CONTROL                    = 0x00020000;
        internal const int SYNCHRONIZE                     = 0x00100000; 
        internal const int STANDARD_RIGHTS_READ            = READ_CONTROL;
        internal const int STANDARD_RIGHTS_WRITE           = READ_CONTROL;
        internal const int KEY_QUERY_VALUE        = 0x0001;
        internal const int KEY_SET_VALUE          = 0x0002; 
        internal const int KEY_CREATE_SUB_KEY     = 0x0004;
        internal const int KEY_ENUMERATE_SUB_KEYS = 0x0008; 
        internal const int KEY_NOTIFY             = 0x0010; 
        internal const int KEY_CREATE_LINK        = 0x0020;
        internal const int KEY_READ               =((STANDARD_RIGHTS_READ       | 
                                                           KEY_QUERY_VALUE            |
                                                           KEY_ENUMERATE_SUB_KEYS     |
                                                           KEY_NOTIFY)
                                                          & 
                                                          (~SYNCHRONIZE));
 
        internal const int KEY_WRITE              = STANDARD_RIGHTS_WRITE | 
                                                           KEY_SET_VALUE |
                                                           KEY_CREATE_SUB_KEY; 

        internal const int REG_NONE                    = 0;     // No value type
        internal const int REG_SZ                      = 1;     // Unicode nul terminated string
        internal const int REG_EXPAND_SZ               = 2;     // Unicode nul terminated string 
        internal const int KEY_WOW64_32KEY             = (0x0200);
        internal const int KEY_WOW64_64KEY             = (0x0100); 
 

        // (with environment variable references) 
        internal const int REG_BINARY                  = 3;     // Free form binary
        internal const int REG_DWORD                   = 4;     // 32-bit number
        internal const int REG_DWORD_LITTLE_ENDIAN     = 4;     // 32-bit number (same as REG_DWORD)
        internal const int REG_DWORD_BIG_ENDIAN        = 5;     // 32-bit number 
        internal const int REG_LINK                    = 6;     // Symbolic Link (unicode)
        internal const int REG_MULTI_SZ                = 7;     // Multiple Unicode strings 
        internal const int REG_RESOURCE_LIST           = 8;     // Resource list in the resource map 
        internal const int REG_FULL_RESOURCE_DESCRIPTOR  = 9;   // Resource list in the hardware description
        internal const int REG_RESOURCE_REQUIREMENTS_LIST = 10; 
        internal const int REG_QWORD                   = 11;    // 64-bit number

        internal const int HWND_BROADCAST              = 0xffff;
        internal const int WM_SETTINGCHANGE            = 0x001A; 

 
        [DllImport(ADVAPI32, CharSet=CharSet.Unicode, BestFitMapping=false)] 
        internal static extern int RegOpenKeyEx(RegistryHandle hKey, String lpSubKey,
                    int ulOptions, int samDesired, out RegistryHandle hkResult); 

        [DllImport(ADVAPI32, CharSet=CharSet.Unicode, BestFitMapping=false)]
        internal static extern int RegSetValueEx(RegistryHandle hKey, String lpValueName,
                    int Reserved, int dwType, String val, int cbData); 

        [DllImport(ADVAPI32, SetLastError=false)] 
        internal static extern int RegCloseKey(IntPtr handle); 

        [DllImport(ADVAPI32, CharSet=CharSet.Unicode, BestFitMapping=false)] 
        internal static extern int RegQueryValueEx(RegistryHandle hKey, String lpValueName,
                    int[] lpReserved, ref int lpType, [Out] byte[] lpData,
                    ref int lpcbData);
        [DllImport(ADVAPI32, CharSet=CharSet.Unicode, BestFitMapping=false)] 
        internal static extern int RegEnumKey (RegistryHandle hKey, int index, StringBuilder lpName, ref int len);
 
        [DllImport(ADVAPI32, CharSet=CharSet.Unicode, BestFitMapping=false)] 
        internal static extern int RegDeleteKey(RegistryHandle hKey, String lpValueName);
 

        [DllImport(ADVAPI32, SetLastError = true)]
        internal static extern bool
        DuplicateTokenEx( 
            [In] SafeCloseHandle ExistingToken,
            [In] TokenAccessLevels DesiredAccess, 
            [In] IntPtr TokenAttributes, 
            [In] SecurityImpersonationLevel ImpersonationLevel,
            [In] TokenType TokenType, 
            [Out] out SafeCloseHandle NewToken);


        [DllImport(ADVAPI32, SetLastError = true)] 
        internal static extern bool
        AccessCheck( 
            [In] byte[] SecurityDescriptor, 
            [In] SafeCloseHandle ClientToken,
            [In] int DesiredAccess, 
            [In] GENERIC_MAPPING GenericMapping,
            [Out] out PRIVILEGE_SET PrivilegeSet,
            [In, Out] ref uint PrivilegeSetLength,
            [Out] out uint GrantedAccess, 
            [Out] out bool AccessStatus);
 
 
        [DllImport(ADVAPI32, SetLastError = true, EntryPoint = "ImpersonateAnonymousToken")]
        internal static extern bool 
        ImpersonateAnonymousUserOnCurrentThread(
            [In] IntPtr CurrentThread);

        [DllImport(ADVAPI32, SetLastError = true, EntryPoint = "OpenThreadToken")] 
        internal static extern bool
        OpenCurrentThreadToken( 
            [In] IntPtr ThreadHandle, 
            [In] TokenAccessLevels DesiredAccess,
            [In] bool OpenAsSelf, 
            [Out] out SafeCloseHandle TokenHandle);

        [DllImport(ADVAPI32, SetLastError = true, EntryPoint = "OpenThreadToken")]
        internal static extern bool 
        OpenCurrentThreadTokenCritical(
            [In] IntPtr ThreadHandle, 
            [In] TokenAccessLevels DesiredAccess, 
            [In] bool OpenAsSelf,
            [Out] out SafeCloseHandleCritical TokenHandle); 

        [DllImport(ADVAPI32, SetLastError = true, EntryPoint = "SetThreadToken")]
        internal static extern bool
        SetCurrentThreadToken( 
            [In] IntPtr ThreadHandle,
            [In] SafeCloseHandle TokenHandle); 
 
        [DllImport(KERNEL32, SetLastError = true)]
        internal static extern IntPtr 
        GetCurrentThread();

        [DllImport(KERNEL32, SetLastError = false)]
        internal static extern int 
        GetCurrentThreadId();
 
        [DllImport(ADVAPI32, SetLastError = true)] 
        internal static extern bool
        RevertToSelf(); 

        [DllImport(ADVAPI32, SetLastError = true)]
        internal static extern bool
        GetTokenInformation( 
            [In] SafeCloseHandle TokenHandle,
            [In] TOKEN_INFORMATION_CLASS TokenInformationClass, 
            [In] SafeHandle TokenInformation, 
            [Out] uint TokenInformationLength,
            [Out] out uint ReturnLength); 

        [DllImport(KERNEL32, SetLastError = true)]
        internal static extern IntPtr
        GetCurrentProcess(); 

        [DllImport(ADVAPI32, SetLastError = true, EntryPoint = "OpenProcessToken")] 
        internal static extern bool 
        GetCurrentProcessToken(
            [In]IntPtr ProcessHandle, 
            [In]TokenAccessLevels DesiredAccess,
            [Out]out SafeCloseHandle TokenHandle);

        [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)] 
        [return: MarshalAs(UnmanagedType.Interface)]
        public static extern object CoCreateInstance( 
            [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, 
            [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
            [In] CLSCTX dwClsContext, 
            [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);

        [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)] 
        public static extern IStream CreateStreamOnHGlobal(
            [In] SafeHGlobalHandle hGlobal, 
            [In, MarshalAs(UnmanagedType.Bool)] bool fDeleteOnRelease); 

        [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)] 
        public static extern SafeHGlobalHandle GetHGlobalFromStream(IStream stream);

        [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)] 
        public static extern object CoGetObjectContext(
            [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid); 
 
        [DllImport(COMSVCS, ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)] 
        public static extern object CoCreateActivity(
            [In, MarshalAs(UnmanagedType.IUnknown)] object pIUnknown,
            [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
 
        [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)]
        internal static extern IntPtr CoSwitchCallContext(IntPtr newSecurityObject); 
 
        [DllImport(KERNEL32, ExactSpelling = true, PreserveSig = true)]
        internal static extern IntPtr GlobalLock(SafeHGlobalHandle hGlobal); 

        [DllImport(KERNEL32, ExactSpelling = true, PreserveSig = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GlobalUnlock(SafeHGlobalHandle hGlobal); 

        [DllImport(KERNEL32, ExactSpelling = true, PreserveSig = true)] 
        internal static extern IntPtr GlobalSize(SafeHGlobalHandle hGlobal); 

        [DllImport(OLEAUT32, 
           ExactSpelling = true,
           CharSet = CharSet.Unicode,
           PreserveSig = true)]
        internal static extern int LoadRegTypeLib(ref Guid rguid, ushort major, ushort minor, int lcid, 
             [MarshalAs(UnmanagedType.Interface)] out object typeLib);
 
        [DllImport(OLEAUT32, 
            ExactSpelling = true,
            CharSet = CharSet.Unicode, 
            PreserveSig = true)]
        internal static extern int SafeArrayGetDim (IntPtr pSafeArray);

        [DllImport(OLEAUT32, 
            ExactSpelling = true,
            CharSet = CharSet.Unicode, 
            PreserveSig = true)] 
        internal static extern int  SafeArrayGetElemsize (IntPtr pSafeArray);
 
        [DllImport(OLEAUT32,
            ExactSpelling = true,
            CharSet = CharSet.Unicode,
            PreserveSig = false)] 
        internal static extern int SafeArrayGetLBound  (IntPtr pSafeArray, int cDims);
        [DllImport(OLEAUT32, 
            ExactSpelling = true, 
            CharSet = CharSet.Unicode,
            PreserveSig = false)] 
        internal static extern int SafeArrayGetUBound  (IntPtr pSafeArray, int cDims);

        [DllImport(OLEAUT32,
            ExactSpelling = true, 
            CharSet = CharSet.Unicode,
            PreserveSig = false)] 
        internal static extern IntPtr SafeArrayAccessData (IntPtr pSafeArray); 

        [DllImport(OLEAUT32, 
            ExactSpelling = true,
            CharSet = CharSet.Unicode,
            PreserveSig = false)]
        internal static extern void SafeArrayUnaccessData(IntPtr pSafeArray); 

        [DllImport(SECUR32, CharSet = CharSet.Unicode, SetLastError = true)] 
        [return: MarshalAs(UnmanagedType.U1)] 
        internal extern static bool TranslateName(string input, EXTENDED_NAME_FORMAT inputFormat, EXTENDED_NAME_FORMAT outputFormat, StringBuilder outputString, out uint size);
    } 

    internal static class InterfaceHelper
    {
        // only use this helper to get interfaces that are guaranteed to be supported 
        internal static IntPtr GetInterfacePtrForObject(Guid iid, object obj)
        { 
            IntPtr pUnk = Marshal.GetIUnknownForObject(obj); 
            if (IntPtr.Zero == pUnk)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.UnableToRetrievepUnk)));
            }

            IntPtr ppv = IntPtr.Zero; 
            int hr = Marshal.QueryInterface(pUnk, ref iid, out ppv);
 
            Marshal.Release(pUnk); 

            if (hr != HR.S_OK) 
            {
                DiagnosticUtility.DebugAssert("QueryInterface should succeed");

                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            }
 
            return ppv; 
        }
    } 

    internal class RegistryHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        internal static readonly RegistryHandle HKEY_CLASSES_ROOT         = new RegistryHandle (new IntPtr(unchecked((int)0x80000000)), false); 
        internal static readonly RegistryHandle HKEY_CURRENT_USER         = new RegistryHandle (new IntPtr(unchecked((int)0x80000001)), false);
        internal static readonly RegistryHandle HKEY_LOCAL_MACHINE        = new RegistryHandle (new IntPtr(unchecked((int)0x80000002)), false); 
        internal static readonly RegistryHandle HKEY_USERS                = new RegistryHandle (new IntPtr(unchecked((int)0x80000003)), false); 
        internal static readonly RegistryHandle HKEY_PERFORMANCE_DATA     = new RegistryHandle (new IntPtr(unchecked((int)0x80000004)), false);
        internal static readonly RegistryHandle HKEY_CURRENT_CONFIG       = new RegistryHandle (new IntPtr(unchecked((int)0x80000005)), false); 
        internal static readonly RegistryHandle HKEY_DYN_DATA             = new RegistryHandle (new IntPtr(unchecked((int)0x80000006)), false);

        static RegistryHandle GetHKCR ()
        { 
            RegistryHandle regHandle = null;
            int status = SafeNativeMethods.RegOpenKeyEx (HKEY_LOCAL_MACHINE, @"Software\Classes", 0, SafeNativeMethods.KEY_READ , out regHandle); 
            if (status != SafeNativeMethods.ERROR_SUCCESS) 
            {
                Utility.CloseInvalidOutSafeHandle(regHandle); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new Win32Exception (status));
            }
            if (null == regHandle || regHandle.IsInvalid)
            { 
                DiagnosticUtility.DebugAssert("GetHKCR: RegOpenKeyEx returned null but with an invalid handle.");
                Utility.CloseInvalidOutSafeHandle(regHandle); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE)); 
            }
 
            return regHandle;
        }

 
        static RegistryHandle Get64bitHKCR ()
        { 
           RegistryHandle regHandle = null; 
           int status = SafeNativeMethods.RegOpenKeyEx (HKEY_LOCAL_MACHINE, @"Software\Classes", 0, SafeNativeMethods.KEY_READ | SafeNativeMethods.KEY_WOW64_64KEY, out regHandle);
           if (status != SafeNativeMethods.ERROR_SUCCESS) 
           {
               Utility.CloseInvalidOutSafeHandle(regHandle);
               throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
           } 
           if (null == regHandle || regHandle.IsInvalid)
           { 
               DiagnosticUtility.DebugAssert("Get64bitHKCR: RegOpenKeyEx returned null but with an invalid handle."); 
               Utility.CloseInvalidOutSafeHandle(regHandle);
               throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE)); 
           }

           return regHandle;
        } 

        static RegistryHandle Get32bitHKCR () 
        { 
           RegistryHandle regHandle = null;
           int status = SafeNativeMethods.RegOpenKeyEx (HKEY_LOCAL_MACHINE, @"Software\Classes", 0, SafeNativeMethods.KEY_READ |  SafeNativeMethods.KEY_WOW64_32KEY, out regHandle); 
           if (status != SafeNativeMethods.ERROR_SUCCESS)
           {
               Utility.CloseInvalidOutSafeHandle(regHandle);
               throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status)); 
           }
           if (null == regHandle || regHandle.IsInvalid) 
           { 
               DiagnosticUtility.DebugAssert("Get64bitHKCR: RegOpenKeyEx returned null but with an invalid handle.");
               Utility.CloseInvalidOutSafeHandle(regHandle); 
               throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE));
           }
           return regHandle;
        } 

        static RegistryHandle GetCorrectBitnessHive (bool is64bit) 
        { 
            if (is64bit && IntPtr.Size == 8) // No worries we are trying to open up a 64 bit hive just return
                return GetHKCR (); 
            else if (is64bit && IntPtr.Size == 4) // we are running under wow get the 64 bit hive
                return Get64bitHKCR ();
            else if (!is64bit && IntPtr.Size == 8) // we are running in 64 bit but need to open a 32 bit hive
                return Get32bitHKCR (); 
            else if (!is64bit && IntPtr.Size == 4)
                return GetHKCR (); 
 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_NOT_SUPPORTED));
        } 

        public static RegistryHandle GetBitnessHKCR (bool is64bit)
        {
            return GetCorrectBitnessHive (is64bit); 
        }
 
        public static RegistryHandle GetCorrectBitnessHKLMSubkey(bool is64bit, string key) 
        {
            if (is64bit && IntPtr.Size == 8) // No worries we are trying to open up a 64 bit hive just return 
                return GetHKLMSubkey(key);
            else if (is64bit && IntPtr.Size == 4) // we are running under wow get the 64 bit hive
                return Get64bitHKLMSubkey(key);
            else if (!is64bit && IntPtr.Size == 8) // we are running in 64 bit but need to open a 32 bit hive 
                return Get32bitHKLMSubkey(key);
            else if (!is64bit && IntPtr.Size == 4) 
                return GetHKLMSubkey(key); 

            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_NOT_SUPPORTED)); 
        }


        static RegistryHandle GetHKLMSubkey(string key) 
        {
            RegistryHandle regHandle = null; 
            int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, SafeNativeMethods.KEY_READ, out regHandle); 
            if (status != SafeNativeMethods.ERROR_SUCCESS)
            { 
                Utility.CloseInvalidOutSafeHandle(regHandle);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
            }
            if (null == regHandle || regHandle.IsInvalid) 
            {
                DiagnosticUtility.DebugAssert("GetHKLMSubkey: RegOpenKeyEx returned null but with an invalid handle."); 
                Utility.CloseInvalidOutSafeHandle(regHandle); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE));
            } 
            return regHandle;

        }
 
        static RegistryHandle Get64bitHKLMSubkey(string key)
        { 
            RegistryHandle regHandle = null; 
            int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, SafeNativeMethods.KEY_READ | SafeNativeMethods.KEY_WOW64_64KEY, out regHandle);
            if (status != SafeNativeMethods.ERROR_SUCCESS) 
            {
                Utility.CloseInvalidOutSafeHandle(regHandle);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
            } 
            if (null == regHandle || regHandle.IsInvalid)
            { 
                DiagnosticUtility.DebugAssert("Get64bitHKLMSubkey: RegOpenKeyEx returned null but with an invalid handle."); 
                Utility.CloseInvalidOutSafeHandle(regHandle);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE)); 
            }
            return regHandle;
        }
 
        static RegistryHandle Get32bitHKLMSubkey(string key)
        { 
            RegistryHandle regHandle = null; 
            int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, SafeNativeMethods.KEY_READ | SafeNativeMethods.KEY_WOW64_32KEY, out regHandle);
            if (status != SafeNativeMethods.ERROR_SUCCESS) 
            {
                Utility.CloseInvalidOutSafeHandle(regHandle);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
            } 
            if (null == regHandle || regHandle.IsInvalid)
            { 
                DiagnosticUtility.DebugAssert("Get32bitHKLMSubkey: RegOpenKeyEx returned null but with an invalid handle."); 
                Utility.CloseInvalidOutSafeHandle(regHandle);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE)); 
            }
            return regHandle;
        }
 
        internal static RegistryHandle GetNativeHKLMSubkey(string subKey, bool writeable)
        { 
            RegistryHandle regHandle = null; 
            int samDesired = SafeNativeMethods.KEY_READ | SafeNativeMethods.KEY_WOW64_64KEY;
 
            if (writeable)
            {
                samDesired |= SafeNativeMethods.KEY_WRITE;
            } 

            int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, 0, samDesired, out regHandle); 
            if (status != SafeNativeMethods.ERROR_SUCCESS || regHandle == null || regHandle.IsInvalid) 
            {
                Utility.CloseInvalidOutSafeHandle(regHandle); 
                return null;
            }
            return regHandle;
        } 

        public RegistryHandle(IntPtr hKey, bool ownHandle) 
            : base(ownHandle) 
        {
            handle = hKey; 
        }

        public RegistryHandle () : base (true)
        { 
        }
 
        public bool DeleteKey (string key) 
        {
            int status = SafeNativeMethods.RegDeleteKey (this, key); 
            if (status == SafeNativeMethods.ERROR_SUCCESS)
                return true;
            else
                return false; 
        }
 
        public void SetValue (string valName, string value) 
        {
            int status = SafeNativeMethods.RegSetValueEx (this, valName, 0, SafeNativeMethods.REG_SZ, value, (value.Length * 2) + 2); 
            if (status != SafeNativeMethods.ERROR_SUCCESS)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new Win32Exception (status));
        }
 
        public RegistryHandle OpenSubKey (string subkey)
        { 
            RegistryHandle regHandle = null; 
            int status = SafeNativeMethods.RegOpenKeyEx (this, subkey, 0, SafeNativeMethods.KEY_READ , out regHandle);
            if (status != SafeNativeMethods.ERROR_SUCCESS || regHandle == null || regHandle.IsInvalid) 
            {
                Utility.CloseInvalidOutSafeHandle(regHandle);
                return null;
            } 
            return regHandle;
        } 
 
        public string GetStringValue (string valName)
        { 
            int type = 0;
            int datasize = 0;
            int ret = SafeNativeMethods.RegQueryValueEx(this, valName, null, ref type, (byte[])null, ref datasize);
            if (ret == SafeNativeMethods.ERROR_SUCCESS) 
                if (type == SafeNativeMethods.REG_SZ)
                { 
                    byte [] blob = new byte [datasize]; 
                    ret = SafeNativeMethods.RegQueryValueEx(this, valName, null, ref type, (byte[]) blob, ref datasize);
                    UnicodeEncoding unicode = new UnicodeEncoding(); 
                    return unicode.GetString (blob);
                }
            return null;
        } 
        public StringCollection GetSubKeyNames ()
        { 
            int ret = 0; 
            int index = 0;
            StringCollection keyNames = new StringCollection (); 
            do
            {
                int lengthInChars = 0;
                ret = SafeNativeMethods.RegEnumKey (this, index, null, ref lengthInChars); 
                if (ret == SafeNativeMethods.ERROR_MORE_DATA)
                { 
                    StringBuilder keyName = new StringBuilder (lengthInChars + 1); 
                    ret = SafeNativeMethods.RegEnumKey (this, index, keyName, ref lengthInChars);
                    if (ret == SafeNativeMethods.ERROR_SUCCESS) 
                        keyNames.Add (keyName.ToString ());
                }
                index++;
           } 
           while (ret == SafeNativeMethods.ERROR_SUCCESS);
           return keyNames; 
 
       }
       internal unsafe object GetValue(string valName) 
       {
           object retVal = null;
           int type = 0;
           int datasize = 0; 
           int ret = SafeNativeMethods.RegQueryValueEx(this, valName, null, ref type, (byte[])null, ref datasize);
           if (SafeNativeMethods.ERROR_SUCCESS == ret) 
           { 
               byte[] blob = new byte[datasize];
               ret = SafeNativeMethods.RegQueryValueEx(this, valName, null, ref type, (byte[])blob, ref datasize); 

               if (SafeNativeMethods.ERROR_SUCCESS == ret)
               {
                   UnicodeEncoding unicode = new UnicodeEncoding(); 
                   string stringVal = unicode.GetString(blob);
 
                   switch (type) 
                   {
                       case (SafeNativeMethods.REG_BINARY): 
                           retVal = blob;
                           break;

                       case (SafeNativeMethods.REG_DWORD): 
                           fixed (byte* pBuffer = blob)
                           { 
                               retVal = Marshal.ReadInt32((IntPtr)pBuffer); 
                           }
                           break; 

                       case (SafeNativeMethods.REG_MULTI_SZ):
                           retVal = stringVal.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
                           break; 

                       case (SafeNativeMethods.REG_QWORD): 
                           fixed (byte* pBuffer = blob) 
                           {
                               retVal = Marshal.ReadInt64((IntPtr)pBuffer); 
                           }
                           break;

                       case (SafeNativeMethods.REG_EXPAND_SZ): 
                       case (SafeNativeMethods.REG_SZ):
                           retVal = stringVal.Trim(new char[] { '\0' }); 
                           break; 

                       default: 
                           retVal = blob;
                           break;
                   }
               } 
           }
 
           return retVal; 
       }
       protected override bool ReleaseHandle() 
       {
            if (SafeNativeMethods.RegCloseKey (handle) == SafeNativeMethods.ERROR_SUCCESS)
                return true;
            else 
                return false;
       } 
    } 
}

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