1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
//------------------------------------------------------------------------------
// <copyright file="PropertyInfoSet.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">Microsoft</owner>
// <owner current="true" primary="false">Microsoft</owner>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
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 OleDbPropertyInfo {
public Guid _propertySet;
public Int32 _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 int setCount;
private IntPtr descBuffer;
internal PropertyInfoSet(UnsafeNativeMethods.IDBProperties idbProperties, PropertyIDSet propIDSet) : base(IntPtr.Zero, true) {
OleDbHResult hr;
int propIDSetCount = propIDSet.Count; // avoid need for ReliabilityContract on get_Count
Bid.Trace("<oledb.IDBProperties.GetPropertyInfo|API|OLEDB>\n");
RuntimeHelpers.PrepareConstrainedRegions();
try {} finally {
hr = idbProperties.GetPropertyInfo(propIDSetCount, propIDSet, out this.setCount, out base.handle, out this.descBuffer);
}
Bid.Trace("<oledb.IDBProperties.GetPropertyInfo|API|OLEDB|RET> %08X{HRESULT}\n", hr);
if ((0 <= hr) && (ADP.PtrZero != 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 (ADP.PtrZero != this.handle) {
propertyLookup = new Dictionary<string,OleDbPropertyInfo>(StringComparer.OrdinalIgnoreCase);
IntPtr setPtr = this.handle;
tagDBPROPINFO propinfo = new tagDBPROPINFO();
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.ToLower(CultureInfo.InvariantCulture);
propertyInfo._type = PropertyInfoSet.FromVtType(propinfo.vtType);
if (Bid.AdvancedOn) {
Bid.Trace("<oledb.struct.OleDbPropertyInfo|INFO|ADV> \n");//, propertyInfo);
}
propertyLookup[propertyInfo._lowercase] = propertyInfo;
}
}
}
}
finally {
if (mustRelease) {
DangerousRelease();
}
}
return propertyLookup;
}
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 (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 + ADP.PtrSize);
for (int k = 0; k < infoCount; ++k) {
IntPtr valuePtr = ADP.IntPtrOffset(infoPtr, (k * ODB.SizeOf_tagDBPROPINFO) + ODB.OffsetOf_tagDBPROPINFO_Value);
SafeNativeMethods.VariantClear(valuePtr);
}
SafeNativeMethods.CoTaskMemFree(infoPtr); // was allocated by provider
}
}
SafeNativeMethods.CoTaskMemFree(ptr);
}
ptr = this.descBuffer;
this.descBuffer = IntPtr.Zero;
if (IntPtr.Zero != ptr) {
SafeNativeMethods.CoTaskMemFree(ptr);
}
return true;
}
internal static Type FromVtType(int vartype) {
switch((VarEnum)vartype) {
case VarEnum.VT_EMPTY: return null;
case VarEnum.VT_NULL: return typeof(System.DBNull);
case VarEnum.VT_I2: return typeof(System.Int16);
case VarEnum.VT_I4: return typeof(System.Int32);
case VarEnum.VT_R4: return typeof(System.Single);
case VarEnum.VT_R8: return typeof(System.Double);
case VarEnum.VT_CY: return typeof(System.Decimal);
case VarEnum.VT_DATE: return typeof(System.DateTime);
case VarEnum.VT_BSTR: return typeof(System.String);
case VarEnum.VT_DISPATCH: return typeof(System.Object);
case VarEnum.VT_ERROR: return typeof(System.Int32);
case VarEnum.VT_BOOL: return typeof(System.Boolean);
case VarEnum.VT_VARIANT: return typeof(System.Object);
case VarEnum.VT_UNKNOWN: return typeof(System.Object);
case VarEnum.VT_DECIMAL: return typeof(System.Decimal);
case VarEnum.VT_I1: return typeof(System.SByte);
case VarEnum.VT_UI1: return typeof(System.Byte);
case VarEnum.VT_UI2: return typeof(System.UInt16);
case VarEnum.VT_UI4: return typeof(System.UInt32);
case VarEnum.VT_I8: return typeof(System.Int64);
case VarEnum.VT_UI8: return typeof(System.UInt64);
case VarEnum.VT_INT: return typeof(System.Int32);
case VarEnum.VT_UINT: return typeof(System.UInt32);
default: return typeof(System.Object);
}
} }
}
|