MetabaseReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / System.ServiceModel.Activation / System / ServiceModel / Activation / MetabaseReader.cs / 1305376 / MetabaseReader.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Activation
{ 
    using System;
    using System.Collections.Generic; 
    using System.Globalization; 
    using System.Runtime;
    using System.Runtime.InteropServices; 
    using System.Security;
    using System.ServiceModel.Activation.Interop;
    using System.Threading;
 
    // These values are copied from %SDXROOT%\public\sdk\inc\iiscnfg.h.
    enum MetabasePropertyType 
    { 
        ServerBindings = 1023,
        SecureBindings = 2021, 
        AuthFlags = 6000,
        Realm = 6001,
        AnonymousUserName = 6020,
        AnonymousPassword = 6021, 
        AccessSslFlags = 6030,
        AuthPersistence = 6031, 
        AuthProviders = 6032, 
    }
 
    [Fx.Tag.SecurityNote(Critical = "Does a bunch of unsafe and native access." +
        "Caller should guard MetabaseReader instance as well as any results.")]
#pragma warning disable 618 // have not moved to the v4 security model yet
    [SecurityCritical(SecurityCriticalScope.Everything)] 
#pragma warning restore 618
    class MetabaseReader : IDisposable 
    { 
        internal const string LMPath = "/LM";
        const uint E_INSUFFICIENT_BUFFER = 0x8007007A; 
        const uint E_PATH_NOT_FOUND = 0x80070003;
        const uint E_DATA_NOT_FOUND = 0x800CC801;

        static IMSAdminBase adminBase; 
        static object syncRoot = new object();
        int mdHandle = 0; 
 
        [Fx.Tag.SecurityNote(Critical = "Stores a handle.")]
        [SecurityCritical] 
        METADATA_RECORD record;

        [Fx.Tag.SecurityNote(Critical = "Handle to an unmanaged resource.")]
        [SecurityCritical] 
        SafeHandle bufferHandle;
 
        uint currentBufferSize = 1024; 
        bool disposed;
        [Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")] 
        [SecuritySafeCritical]
        public MetabaseReader()
        {
            lock (syncRoot) 
            {
                if (adminBase == null) 
                { 
                    adminBase = (IMSAdminBase)new MSAdminBase();
                } 
            }

            uint handle;
            uint hResult = adminBase.OpenKey(MSAdminBase.METADATA_MASTER_ROOT_HANDLE, LMPath, 
                MSAdminBase.METADATA_PERMISSION_READ, MSAdminBase.DEFAULT_METABASE_TIMEOUT, out handle);
            mdHandle = (int) handle; 
 
            if (hResult != 0)
            { 
                throw FxTrace.Exception.AsError(new COMException(SR.Hosting_MetabaseAccessError, (int)hResult));
            }

            bufferHandle = SafeHGlobalHandleCritical.AllocHGlobal(currentBufferSize); 
        }
 
        ~MetabaseReader() 
        {
            Dispose(false); 
        }
        [Fx.Tag.SecurityNote(Safe = "Access Critical Private Members and returns a managed representation of the handle.")]
        [SecurityCritical]
        public object GetData(string path, MetabasePropertyType propertyType) 
        {
            return GetData(path, (uint)propertyType); 
        } 

        public void Dispose() 
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        } 
        [Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
        [SecuritySafeCritical] 
        void EnsureRecordBuffer(uint bytes) 
        {
            if (bytes <= currentBufferSize) 
            {
                return;
            }
 
            bufferHandle.Close();
            currentBufferSize = bytes; 
            bufferHandle = SafeHGlobalHandleCritical.AllocHGlobal(currentBufferSize); 

            record.pbMDData = bufferHandle.DangerousGetHandle(); 
            record.dwMDDataLen = currentBufferSize;
        }
        [Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
        [SecurityCritical] 
        object GetData(string path, uint type)
        { 
            uint bytes = currentBufferSize; 
            record.dwMDAttributes = MSAdminBase.METADATA_INHERIT;
            record.dwMDUserType = MSAdminBase.IIS_MD_UT_SERVER; 
            record.dwMDDataType = MSAdminBase.ALL_METADATA;
            record.dwMDIdentifier = type;
            record.pbMDData = bufferHandle.DangerousGetHandle();
            record.dwMDDataLen = currentBufferSize; 

            uint hResult = adminBase.GetData((uint) mdHandle, path, ref record, ref bytes); 
            if (hResult == E_INSUFFICIENT_BUFFER) 
            {
                EnsureRecordBuffer(bytes); 
                hResult = adminBase.GetData((uint) mdHandle, path, ref record, ref bytes);
            }

            if (hResult == E_PATH_NOT_FOUND || hResult == E_DATA_NOT_FOUND) 
            {
                return null; 
            } 
            else if (hResult != 0)
            { 
                throw FxTrace.Exception.AsError(new COMException(SR.Hosting_MetabaseAccessError, (int)hResult));
            }

            return ConvertData(); 
        }
        [Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")] 
        [SecurityCritical] 
        object ConvertData()
        { 
            switch (record.dwMDDataType)
            {
                case MSAdminBase.DWORD_METADATA:
                    return (UInt32)Marshal.ReadInt32(record.pbMDData); 
                case MSAdminBase.EXPANDSZ_METADATA:
                case MSAdminBase.STRING_METADATA: 
                    return Marshal.PtrToStringUni(record.pbMDData); 
                case MSAdminBase.MULTISZ_METADATA:
                    return RecordToStringArray(); 
                default:
                    throw FxTrace.Exception.AsError(new NotSupportedException(
                        SR.Hosting_MetabaseDataTypeUnsupported(
                        record.dwMDDataType.ToString(NumberFormatInfo.CurrentInfo), 
                        record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
            } 
        } 
        [Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
        [SecurityCritical] 
        string[] RecordToStringArray()
        {
            List list = new List();
            if (record.dwMDDataType == MSAdminBase.MULTISZ_METADATA) 
            {
                // Ensure that the data is an array of double-byte unicode chars. 
                if ((record.dwMDDataLen & 1) != 0) 
                {
                    throw FxTrace.Exception.AsError(new DataMisalignedException( 
                        SR.Hosting_MetabaseDataStringsTerminate(record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
                }

                int startPos = 0; 
                int endPos = 0;
                while (record.dwMDDataLen > 0) 
                { 
                    // Scan for a null terminator.
                    while (endPos < record.dwMDDataLen && Marshal.ReadInt16(record.pbMDData, endPos) != 0) 
                    {
                        endPos += 2;
                    }
 
                    if (endPos == record.dwMDDataLen &&
                        Marshal.ReadInt16(record.pbMDData, endPos - 2) != 0) 
                    { 
                        throw FxTrace.Exception.AsError(new DataMisalignedException(
                            SR.Hosting_MetabaseDataStringsTerminate(record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo)))); 
                    }

                    // End of the string.
                    if (endPos == startPos) 
                    {
                        break; 
                    } 

                    // Convert to string. 
                    list.Add(Marshal.PtrToStringUni(new IntPtr(record.pbMDData.ToInt64() + startPos),
                        (endPos - startPos)/2));

                    // Go to next string 
                    startPos = endPos += 2;
                } 
            } 

            return list.ToArray(); 
        }
        [Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
        [SecuritySafeCritical]
        void Dispose(bool disposing) 
        {
            if (!disposed) 
            { 
                if (disposing)
                { 
                    record.pbMDData = IntPtr.Zero;
                    currentBufferSize = 0;

                    if (bufferHandle != null) 
                    {
                        bufferHandle.Close(); 
                    } 
                }
 
                int handleToClose = Interlocked.Exchange(ref mdHandle, 0);
                if (handleToClose != 0)
                {
                    adminBase.CloseKey((uint) handleToClose); 
                }
 
                //Notice we cannot assign adminBase to NULL in Dispose, because 
                //it could be shared by multiple instances of MetabaseReader.
 
                disposed = true;
            }
        }
 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Activation
{ 
    using System;
    using System.Collections.Generic; 
    using System.Globalization; 
    using System.Runtime;
    using System.Runtime.InteropServices; 
    using System.Security;
    using System.ServiceModel.Activation.Interop;
    using System.Threading;
 
    // These values are copied from %SDXROOT%\public\sdk\inc\iiscnfg.h.
    enum MetabasePropertyType 
    { 
        ServerBindings = 1023,
        SecureBindings = 2021, 
        AuthFlags = 6000,
        Realm = 6001,
        AnonymousUserName = 6020,
        AnonymousPassword = 6021, 
        AccessSslFlags = 6030,
        AuthPersistence = 6031, 
        AuthProviders = 6032, 
    }
 
    [Fx.Tag.SecurityNote(Critical = "Does a bunch of unsafe and native access." +
        "Caller should guard MetabaseReader instance as well as any results.")]
#pragma warning disable 618 // have not moved to the v4 security model yet
    [SecurityCritical(SecurityCriticalScope.Everything)] 
#pragma warning restore 618
    class MetabaseReader : IDisposable 
    { 
        internal const string LMPath = "/LM";
        const uint E_INSUFFICIENT_BUFFER = 0x8007007A; 
        const uint E_PATH_NOT_FOUND = 0x80070003;
        const uint E_DATA_NOT_FOUND = 0x800CC801;

        static IMSAdminBase adminBase; 
        static object syncRoot = new object();
        int mdHandle = 0; 
 
        [Fx.Tag.SecurityNote(Critical = "Stores a handle.")]
        [SecurityCritical] 
        METADATA_RECORD record;

        [Fx.Tag.SecurityNote(Critical = "Handle to an unmanaged resource.")]
        [SecurityCritical] 
        SafeHandle bufferHandle;
 
        uint currentBufferSize = 1024; 
        bool disposed;
        [Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")] 
        [SecuritySafeCritical]
        public MetabaseReader()
        {
            lock (syncRoot) 
            {
                if (adminBase == null) 
                { 
                    adminBase = (IMSAdminBase)new MSAdminBase();
                } 
            }

            uint handle;
            uint hResult = adminBase.OpenKey(MSAdminBase.METADATA_MASTER_ROOT_HANDLE, LMPath, 
                MSAdminBase.METADATA_PERMISSION_READ, MSAdminBase.DEFAULT_METABASE_TIMEOUT, out handle);
            mdHandle = (int) handle; 
 
            if (hResult != 0)
            { 
                throw FxTrace.Exception.AsError(new COMException(SR.Hosting_MetabaseAccessError, (int)hResult));
            }

            bufferHandle = SafeHGlobalHandleCritical.AllocHGlobal(currentBufferSize); 
        }
 
        ~MetabaseReader() 
        {
            Dispose(false); 
        }
        [Fx.Tag.SecurityNote(Safe = "Access Critical Private Members and returns a managed representation of the handle.")]
        [SecurityCritical]
        public object GetData(string path, MetabasePropertyType propertyType) 
        {
            return GetData(path, (uint)propertyType); 
        } 

        public void Dispose() 
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        } 
        [Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
        [SecuritySafeCritical] 
        void EnsureRecordBuffer(uint bytes) 
        {
            if (bytes <= currentBufferSize) 
            {
                return;
            }
 
            bufferHandle.Close();
            currentBufferSize = bytes; 
            bufferHandle = SafeHGlobalHandleCritical.AllocHGlobal(currentBufferSize); 

            record.pbMDData = bufferHandle.DangerousGetHandle(); 
            record.dwMDDataLen = currentBufferSize;
        }
        [Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
        [SecurityCritical] 
        object GetData(string path, uint type)
        { 
            uint bytes = currentBufferSize; 
            record.dwMDAttributes = MSAdminBase.METADATA_INHERIT;
            record.dwMDUserType = MSAdminBase.IIS_MD_UT_SERVER; 
            record.dwMDDataType = MSAdminBase.ALL_METADATA;
            record.dwMDIdentifier = type;
            record.pbMDData = bufferHandle.DangerousGetHandle();
            record.dwMDDataLen = currentBufferSize; 

            uint hResult = adminBase.GetData((uint) mdHandle, path, ref record, ref bytes); 
            if (hResult == E_INSUFFICIENT_BUFFER) 
            {
                EnsureRecordBuffer(bytes); 
                hResult = adminBase.GetData((uint) mdHandle, path, ref record, ref bytes);
            }

            if (hResult == E_PATH_NOT_FOUND || hResult == E_DATA_NOT_FOUND) 
            {
                return null; 
            } 
            else if (hResult != 0)
            { 
                throw FxTrace.Exception.AsError(new COMException(SR.Hosting_MetabaseAccessError, (int)hResult));
            }

            return ConvertData(); 
        }
        [Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")] 
        [SecurityCritical] 
        object ConvertData()
        { 
            switch (record.dwMDDataType)
            {
                case MSAdminBase.DWORD_METADATA:
                    return (UInt32)Marshal.ReadInt32(record.pbMDData); 
                case MSAdminBase.EXPANDSZ_METADATA:
                case MSAdminBase.STRING_METADATA: 
                    return Marshal.PtrToStringUni(record.pbMDData); 
                case MSAdminBase.MULTISZ_METADATA:
                    return RecordToStringArray(); 
                default:
                    throw FxTrace.Exception.AsError(new NotSupportedException(
                        SR.Hosting_MetabaseDataTypeUnsupported(
                        record.dwMDDataType.ToString(NumberFormatInfo.CurrentInfo), 
                        record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
            } 
        } 
        [Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
        [SecurityCritical] 
        string[] RecordToStringArray()
        {
            List list = new List();
            if (record.dwMDDataType == MSAdminBase.MULTISZ_METADATA) 
            {
                // Ensure that the data is an array of double-byte unicode chars. 
                if ((record.dwMDDataLen & 1) != 0) 
                {
                    throw FxTrace.Exception.AsError(new DataMisalignedException( 
                        SR.Hosting_MetabaseDataStringsTerminate(record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
                }

                int startPos = 0; 
                int endPos = 0;
                while (record.dwMDDataLen > 0) 
                { 
                    // Scan for a null terminator.
                    while (endPos < record.dwMDDataLen && Marshal.ReadInt16(record.pbMDData, endPos) != 0) 
                    {
                        endPos += 2;
                    }
 
                    if (endPos == record.dwMDDataLen &&
                        Marshal.ReadInt16(record.pbMDData, endPos - 2) != 0) 
                    { 
                        throw FxTrace.Exception.AsError(new DataMisalignedException(
                            SR.Hosting_MetabaseDataStringsTerminate(record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo)))); 
                    }

                    // End of the string.
                    if (endPos == startPos) 
                    {
                        break; 
                    } 

                    // Convert to string. 
                    list.Add(Marshal.PtrToStringUni(new IntPtr(record.pbMDData.ToInt64() + startPos),
                        (endPos - startPos)/2));

                    // Go to next string 
                    startPos = endPos += 2;
                } 
            } 

            return list.ToArray(); 
        }
        [Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
        [SecuritySafeCritical]
        void Dispose(bool disposing) 
        {
            if (!disposed) 
            { 
                if (disposing)
                { 
                    record.pbMDData = IntPtr.Zero;
                    currentBufferSize = 0;

                    if (bufferHandle != null) 
                    {
                        bufferHandle.Close(); 
                    } 
                }
 
                int handleToClose = Interlocked.Exchange(ref mdHandle, 0);
                if (handleToClose != 0)
                {
                    adminBase.CloseKey((uint) handleToClose); 
                }
 
                //Notice we cannot assign adminBase to NULL in Dispose, because 
                //it could be shared by multiple instances of MetabaseReader.
 
                disposed = true;
            }
        }
 
    }
} 

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