| File: PropertyInfoSet.cs | Web Access |
| Project: src\runtime\src\libraries\System.Data.OleDb\src\System.Data.OleDb.csproj (System.Data.OleDb) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Data.Common; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Data.OleDb { internal sealed class OleDbPropertyInfo { public Guid _propertySet; public int _propertyID; public string? _description; public string? _lowercase; public Type? _type; public int _flags; public int _vtype; public object? _supportedValues; public object? _defaultValue; } internal sealed class PropertyInfoSet : SafeHandle { private readonly int setCount; private IntPtr descBuffer; internal PropertyInfoSet(UnsafeNativeMethods.IDBProperties idbProperties, PropertyIDSet propIDSet) : base(IntPtr.Zero, true) { OleDbHResult hr; int propIDSetCount = propIDSet.Count; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { hr = idbProperties.GetPropertyInfo(propIDSetCount, propIDSet, out this.setCount, out base.handle, out this.descBuffer); } if ((0 <= hr) && (IntPtr.Zero != handle)) { SafeNativeMethods.Wrapper.ClearErrorInfo(); } } public override bool IsInvalid { get { return ((IntPtr.Zero == base.handle) && (IntPtr.Zero == this.descBuffer)); } } internal Dictionary<string, OleDbPropertyInfo>? GetValues() { Dictionary<string, OleDbPropertyInfo>? propertyLookup = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); if (IntPtr.Zero != this.handle) { propertyLookup = new Dictionary<string, OleDbPropertyInfo>(StringComparer.OrdinalIgnoreCase); IntPtr setPtr = this.handle; ItagDBPROPINFO propinfo = OleDbStructHelpers.CreateTagDbPropInfo(); tagDBPROPINFOSET propinfoset = new tagDBPROPINFOSET(); for (int i = 0; i < setCount; ++i, setPtr = ADP.IntPtrOffset(setPtr, ODB.SizeOf_tagDBPROPINFOSET)) { Marshal.PtrToStructure(setPtr, propinfoset); int infoCount = propinfoset.cPropertyInfos; IntPtr infoPtr = propinfoset.rgPropertyInfos; for (int k = 0; k < infoCount; ++k, infoPtr = ADP.IntPtrOffset(infoPtr, ODB.SizeOf_tagDBPROPINFO)) { Marshal.PtrToStructure(infoPtr, propinfo); OleDbPropertyInfo propertyInfo = new OleDbPropertyInfo(); propertyInfo._propertySet = propinfoset.guidPropertySet; propertyInfo._propertyID = propinfo.dwPropertyID; propertyInfo._flags = propinfo.dwFlags; propertyInfo._vtype = propinfo.vtType; propertyInfo._supportedValues = propinfo.vValue; propertyInfo._description = propinfo.pwszDescription; propertyInfo._lowercase = propinfo.pwszDescription!.ToLowerInvariant(); propertyInfo._type = PropertyInfoSet.FromVtType(propinfo.vtType); propertyLookup[propertyInfo._lowercase] = propertyInfo; } } } } finally { if (mustRelease) { DangerousRelease(); } } return propertyLookup; } protected override 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 (IntPtr.Zero != ptr) { int count = this.setCount; for (int i = 0; i < count; ++i) { int offset = (i * ODB.SizeOf_tagDBPROPINFOSET); IntPtr infoPtr = Marshal.ReadIntPtr(ptr, offset); if (IntPtr.Zero != infoPtr) { int infoCount = Marshal.ReadInt32(ptr, offset + IntPtr.Size); for (int k = 0; k < infoCount; ++k) { IntPtr valuePtr = ADP.IntPtrOffset(infoPtr, (k * ODB.SizeOf_tagDBPROPINFO) + ODB.OffsetOf_tagDBPROPINFO_Value); Interop.Ole32.PropVariantClear(valuePtr); } Interop.Ole32.CoTaskMemFree(infoPtr); // was allocated by provider } } Interop.Ole32.CoTaskMemFree(ptr); } ptr = this.descBuffer; this.descBuffer = IntPtr.Zero; if (IntPtr.Zero != ptr) { Interop.Ole32.CoTaskMemFree(ptr); } return true; } internal static Type? FromVtType(int vartype) => (VarEnum)vartype switch { VarEnum.VT_EMPTY => null, VarEnum.VT_NULL => typeof(System.DBNull), VarEnum.VT_I2 => typeof(short), VarEnum.VT_I4 => typeof(int), VarEnum.VT_R4 => typeof(float), VarEnum.VT_R8 => typeof(double), VarEnum.VT_CY => typeof(decimal), VarEnum.VT_DATE => typeof(System.DateTime), VarEnum.VT_BSTR => typeof(string), VarEnum.VT_DISPATCH => typeof(object), VarEnum.VT_ERROR => typeof(int), VarEnum.VT_BOOL => typeof(bool), VarEnum.VT_VARIANT => typeof(object), VarEnum.VT_UNKNOWN => typeof(object), VarEnum.VT_DECIMAL => typeof(decimal), VarEnum.VT_I1 => typeof(sbyte), VarEnum.VT_UI1 => typeof(byte), VarEnum.VT_UI2 => typeof(ushort), VarEnum.VT_UI4 => typeof(uint), VarEnum.VT_I8 => typeof(long), VarEnum.VT_UI8 => typeof(ulong), VarEnum.VT_INT => typeof(int), VarEnum.VT_UINT => typeof(uint), _ => typeof(object), }; } }