DBPropSet.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 / fx / src / Data / System / Data / OleDb / DBPropSet.cs / 1305376 / DBPropSet.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System;
using System.Data; 
using System.Data.Common;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices; 
using System.Runtime.InteropServices;
using System.Security; 
using System.Security.Permissions; 
using System.Threading;
using System.Runtime.ConstrainedExecution; 

namespace System.Data.OleDb {

    sealed internal class DBPropSet : SafeHandle { 

        private readonly Int32 propertySetCount; 
 
        // VSDD 621427: stores the exception with last error.HRESULT from IDBProperties.GetProperties
        private Exception lastErrorFromProvider; 

        private DBPropSet() : base(IntPtr.Zero, true) {
            propertySetCount = 0;
        } 

        internal DBPropSet(int propertysetCount) : this() { 
            this.propertySetCount = propertysetCount; 
            IntPtr countOfBytes = (IntPtr)(propertysetCount * ODB.SizeOf_tagDBPROPSET);
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try {} finally {
                base.handle = SafeNativeMethods.CoTaskMemAlloc(countOfBytes);
                if (ADP.PtrZero != base.handle) {
                    SafeNativeMethods.ZeroMemory(base.handle, countOfBytes); 
                }
            } 
            if (ADP.PtrZero == base.handle) { 
                throw new OutOfMemoryException();
            } 
        }

        internal DBPropSet(UnsafeNativeMethods.IDBProperties properties, PropertyIDSet propidset, out OleDbHResult hr) : this() {
            Debug.Assert(null != properties, "null IDBProperties"); 

            int propidsetcount = 0; 
            if (null != propidset) { 
                propidsetcount = propidset.Count;
            } 
            Bid.Trace("\n");
            hr = properties.GetProperties(propidsetcount, propidset, out this.propertySetCount, out base.handle);
            Bid.Trace(" %08X{HRESULT}\n", hr);
 
            if (hr < 0) {
                // VSDD 621427: remember the last HRESULT. Note we do not want to raise exception now to avoid breaking change from Orcas RTM/SP1 
                SetLastErrorInfo(hr); 
            }
        } 

        internal DBPropSet(UnsafeNativeMethods.IRowsetInfo properties, PropertyIDSet propidset, out OleDbHResult hr) : this() {
            Debug.Assert(null != properties, "null IRowsetInfo");
 
            int propidsetcount = 0;
            if (null != propidset) { 
                propidsetcount = propidset.Count; 
            }
            Bid.Trace("\n"); 
            hr = properties.GetProperties(propidsetcount, propidset, out this.propertySetCount, out base.handle);
            Bid.Trace(" %08X{HRESULT}\n", hr);

            if (hr < 0) { 
                // VSDD 621427: remember the last HRESULT. Note we do not want to raise exception now to avoid breaking change from Orcas RTM/SP1
                SetLastErrorInfo(hr); 
            } 
        }
 
        internal DBPropSet(UnsafeNativeMethods.ICommandProperties properties, PropertyIDSet propidset, out OleDbHResult hr) : this() {
            Debug.Assert(null != properties, "null ICommandProperties");

            int propidsetcount = 0; 
            if (null != propidset) {
                propidsetcount = propidset.Count; 
            } 
            Bid.Trace("\n");
            hr = properties.GetProperties(propidsetcount, propidset, out this.propertySetCount, out base.handle); 
            Bid.Trace(" %08X{HRESULT}\n", hr);

            if (hr < 0) {
                // VSDD 621427: remember the last HRESULT. Note we do not want to raise exception now to avoid breaking change from Orcas RTM/SP1 
                SetLastErrorInfo(hr);
            } 
        } 

        private void SetLastErrorInfo(OleDbHResult lastErrorHr) { 
            // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes
            UnsafeNativeMethods.IErrorInfo errorInfo = null;
            string message = String.Empty;
 
            OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo);  // 0 - IErrorInfo exists, 1 - no IErrorInfo
            if ((errorInfoHr == OleDbHResult.S_OK) && (errorInfo != null)) { 
                ODB.GetErrorDescription(errorInfo, lastErrorHr, out message); 
                // note that either GetErrorInfo or GetErrorDescription might fail in which case we will have only the HRESULT value in exception message
            } 
            lastErrorFromProvider = new COMException(message, (int)lastErrorHr);
        }

        public override bool IsInvalid { 
            get {
                return (IntPtr.Zero == base.handle); 
            } 
        }
 
         override protected bool ReleaseHandle() {
            // NOTE: The SafeHandle class guarantees this will be called exactly once and is non-interrutible.
            IntPtr ptr = base.handle;
            base.handle = IntPtr.Zero; 
            if (ADP.PtrZero != ptr) {
 
                int count = this.propertySetCount; 
                for (int i = 0, offset = 0; i < count; ++i, offset += ODB.SizeOf_tagDBPROPSET) {
 
                    IntPtr rgProperties = Marshal.ReadIntPtr(ptr, offset);
                    if(ADP.PtrZero != rgProperties) {
                        int cProperties = Marshal.ReadInt32(ptr, offset + ADP.PtrSize);
 
                        IntPtr vptr = ADP.IntPtrOffset(rgProperties, ODB.OffsetOf_tagDBPROP_Value);
                        for (int k = 0; k < cProperties; ++k, vptr = ADP.IntPtrOffset(vptr, ODB.SizeOf_tagDBPROP)) { 
                            SafeNativeMethods.VariantClear(vptr); 
                        }
                        SafeNativeMethods.CoTaskMemFree(rgProperties); 
                    }
                }
                SafeNativeMethods.CoTaskMemFree(ptr);
            } 
            return true;
        } 
 
        internal int PropertySetCount {
            get { 
                return this.propertySetCount;
            }
        }
 
        internal tagDBPROP[] GetPropertySet(int index, out Guid propertyset) {
            if ((index < 0) || (PropertySetCount <= index)) { 
                if (lastErrorFromProvider != null) 
                {
                    // VSDD 621427: add extra error information for CSS/stress troubleshooting. 
                    // We need to keep same exception type to avoid breaking change with Orcas RTM/SP1.
                    throw ADP.InternalError(ADP.InternalErrorCode.InvalidBuffer, lastErrorFromProvider);
                }
                else { 
                    throw ADP.InternalError(ADP.InternalErrorCode.InvalidBuffer);
                } 
            } 

            tagDBPROPSET propset = new tagDBPROPSET(); 
            tagDBPROP[] properties = null;

            bool mustRelease = false;
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try {
                DangerousAddRef(ref mustRelease); 
                IntPtr propertySetPtr = ADP.IntPtrOffset(DangerousGetHandle(), index * ODB.SizeOf_tagDBPROPSET); 
                Marshal.PtrToStructure(propertySetPtr, propset);
                propertyset = propset.guidPropertySet; 

                properties = new tagDBPROP[propset.cProperties];
                for(int i = 0; i < properties.Length; ++i) {
                    properties[i] = new tagDBPROP(); 
                    IntPtr ptr = ADP.IntPtrOffset(propset.rgProperties, i * ODB.SizeOf_tagDBPROP);
                    Marshal.PtrToStructure(ptr, properties[i]); 
                } 
            }
            finally { 
                if (mustRelease) {
                    DangerousRelease();
                }
            } 
            return properties;
        } 
 
        internal void SetPropertySet(int index, Guid propertySet, tagDBPROP[] properties) {
            if ((index < 0) || (PropertySetCount <= index)) { 
                if (lastErrorFromProvider != null) {
                    // VSDD 621427: add extra error information for CSS/stress troubleshooting.
                    // We need to keep same exception type to avoid breaking change with Orcas RTM/SP1.
                    throw ADP.InternalError(ADP.InternalErrorCode.InvalidBuffer, lastErrorFromProvider); 
                }
                else { 
                    throw ADP.InternalError(ADP.InternalErrorCode.InvalidBuffer); 
                }
            } 
            Debug.Assert(Guid.Empty != propertySet, "invalid propertySet");
            Debug.Assert((null != properties) && (0 < properties.Length), "invalid properties");

            IntPtr countOfBytes = (IntPtr)(properties.Length * ODB.SizeOf_tagDBPROP); 
            tagDBPROPSET propset = new tagDBPROPSET(properties.Length, propertySet);
 
            bool mustRelease = false; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                DangerousAddRef(ref mustRelease);

                IntPtr propsetPtr = ADP.IntPtrOffset(DangerousGetHandle(), index * ODB.SizeOf_tagDBPROPSET);
 
                RuntimeHelpers.PrepareConstrainedRegions();
                try {} finally { 
                    // must allocate and clear the memory without interruption 
                    propset.rgProperties = SafeNativeMethods.CoTaskMemAlloc(countOfBytes);
                    if (ADP.PtrZero != propset.rgProperties) { 
                        // clearing is important so that we don't treat existing
                        // garbage as important information during releaseHandle
                        SafeNativeMethods.ZeroMemory(propset.rgProperties, countOfBytes);
 
                        // writing the structure to native memory so that it knows to free the referenced pointers
                        Marshal.StructureToPtr(propset, propsetPtr, false/*deleteold*/); 
                    } 
                }
                if (ADP.PtrZero == propset.rgProperties) { 
                    throw new OutOfMemoryException();
                }

                for(int i = 0; i < properties.Length; ++i) { 
                    Debug.Assert(null != properties[i], "null tagDBPROP " + i.ToString(CultureInfo.InvariantCulture));
                    IntPtr propertyPtr = ADP.IntPtrOffset(propset.rgProperties, i * ODB.SizeOf_tagDBPROP); 
                    Marshal.StructureToPtr(properties[i], propertyPtr, false/*deleteold*/); 
                }
            } 
            finally {
                if (mustRelease) {
                    DangerousRelease();
                } 
            }
        } 
 
        static internal DBPropSet CreateProperty(Guid propertySet, int propertyId, bool required, object value) {
            tagDBPROP dbprop = new tagDBPROP(propertyId, required, value); 
            DBPropSet propertyset = new DBPropSet(1);
            propertyset.SetPropertySet(0, propertySet, new tagDBPROP[1] { dbprop });
            return propertyset;
        } 
    }
} 

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