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
|
//------------------------------------------------------------------------------
// <copyright file="SafeHandles.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>
//------------------------------------------------------------------------------
namespace System.Data.OleDb {
using System;
using System.Data.Common;
using System.Data.ProviderBase;
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;
internal sealed class DualCoTaskMem : SafeHandle {
private IntPtr handle2; // this must be protected so derived classes can use out params.
private DualCoTaskMem() : base(IntPtr.Zero, true) {
this.handle2 = IntPtr.Zero;
}
// IDBInfo.GetLiteralInfo
internal DualCoTaskMem(UnsafeNativeMethods.IDBInfo dbInfo, int[] literals, out int literalCount, out IntPtr literalInfo, out OleDbHResult hr) : this() {
int count = (null != literals) ? literals.Length : 0;
Bid.Trace("<oledb.IDBInfo.GetLiteralInfo|API|OLEDB>\n");
hr = dbInfo.GetLiteralInfo(count, literals, out literalCount, out base.handle, out this.handle2);
literalInfo = base.handle;
Bid.Trace("<oledb.IDBInfo.GetLiteralInfo|API|OLEDB|RET> %08X{HRESULT}\n", hr);
}
// IColumnsInfo.GetColumnInfo
internal DualCoTaskMem(UnsafeNativeMethods.IColumnsInfo columnsInfo, out IntPtr columnCount, out IntPtr columnInfos, out OleDbHResult hr) : this() {
Bid.Trace("<oledb.IColumnsInfo.GetColumnInfo|API|OLEDB>\n");
hr = columnsInfo.GetColumnInfo(out columnCount, out base.handle, out this.handle2);
columnInfos = base.handle;
Bid.Trace("<oledb.IColumnsInfo.GetColumnInfo|API|OLEDB|RET> %08X{HRESULT}\n", hr);
}
// IDBSchemaRowset.GetSchemas
internal DualCoTaskMem(UnsafeNativeMethods.IDBSchemaRowset dbSchemaRowset, out int schemaCount, out IntPtr schemaGuids, out IntPtr schemaRestrictions, out OleDbHResult hr) : this() {
Bid.Trace("<oledb.IDBSchemaRowset.GetSchemas|API|OLEDB>\n");
hr = dbSchemaRowset.GetSchemas(out schemaCount, out base.handle, out this.handle2);
schemaGuids = base.handle;
schemaRestrictions = this.handle2;
Bid.Trace("<oledb.IDBSchemaRowset.GetSchemas|API|OLEDB|RET> %08X{HRESULT}\n", hr);
}
internal DualCoTaskMem(UnsafeNativeMethods.IColumnsRowset icolumnsRowset, out IntPtr cOptColumns, out OleDbHResult hr) : base(IntPtr.Zero, true) {
Bid.Trace("<oledb.IColumnsRowset.GetAvailableColumns|API|OLEDB>\n");
hr = icolumnsRowset.GetAvailableColumns(out cOptColumns, out base.handle);
Bid.Trace("<oledb.IColumnsRowset.GetAvailableColumns|API|OLEDB|RET> %08X{HRESULT}\n", hr);
}
public override bool IsInvalid {
get {
return (((IntPtr.Zero == base.handle)) && (IntPtr.Zero == this.handle2));
}
}
protected override bool ReleaseHandle() {
// NOTE: The SafeHandle class guarantees this will be called exactly once.
IntPtr ptr = base.handle;
base.handle = IntPtr.Zero;
if (IntPtr.Zero != ptr) {
SafeNativeMethods.CoTaskMemFree(ptr);
}
ptr = this.handle2;
this.handle2 = IntPtr.Zero;
if (IntPtr.Zero != ptr) {
SafeNativeMethods.CoTaskMemFree(ptr);
}
return true;
}
}
internal sealed class RowHandleBuffer : DbBuffer {
internal RowHandleBuffer(IntPtr rowHandleFetchCount) : base((int)rowHandleFetchCount*ADP.PtrSize) {
}
internal IntPtr GetRowHandle(int index) {
IntPtr value = ReadIntPtr( index * ADP.PtrSize);
Debug.Assert(ODB.DB_NULL_HROW != value, "bad rowHandle");
return value;
}
}
internal sealed class StringMemHandle : DbBuffer {
internal StringMemHandle(string value) : base((null != value) ? checked(2+2*value.Length) : 0) {
if (null != value) {
// null-termination exists because of the extra 2+ which is zero'd during on allocation
WriteCharArray(0, value.ToCharArray(), 0, value.Length);
}
}
}
internal sealed class ChapterHandle : WrappedIUnknown {
internal static readonly ChapterHandle DB_NULL_HCHAPTER = new ChapterHandle(IntPtr.Zero);
private IntPtr _chapterHandle;
internal static ChapterHandle CreateChapterHandle(object chapteredRowset, RowBinding binding, int valueOffset) {
if ((null == chapteredRowset) || (IntPtr.Zero == binding.ReadIntPtr(valueOffset))) {
return ChapterHandle.DB_NULL_HCHAPTER;
}
return new ChapterHandle(chapteredRowset, binding, valueOffset);
}
// from ADODBRecordSetConstruction we do not want to release the initial chapter handle
internal static ChapterHandle CreateChapterHandle(IntPtr chapter) {
if (IntPtr.Zero == chapter) {
return ChapterHandle.DB_NULL_HCHAPTER;
}
return new ChapterHandle(chapter);
}
// from ADODBRecordSetConstruction we do not want to release the initial chapter handle
private ChapterHandle(IntPtr chapter) : base((object)null) {
_chapterHandle = chapter;
}
private ChapterHandle(object chapteredRowset, RowBinding binding, int valueOffset) : base(chapteredRowset) {
RuntimeHelpers.PrepareConstrainedRegions();
try {} finally {
_chapterHandle = binding.InterlockedExchangePointer(valueOffset);
}
}
internal IntPtr HChapter {
get {
return _chapterHandle;
}
}
protected override bool ReleaseHandle() {
// NOTE: The SafeHandle class guarantees this will be called exactly once and is non-interrutible.
IntPtr chapter = _chapterHandle;
_chapterHandle = IntPtr.Zero;
if ((IntPtr.Zero != base.handle) && (IntPtr.Zero != chapter)) {
Bid.Trace("<oledb.IChapteredRowset.ReleaseChapter|API|OLEDB> Chapter=%Id\n", chapter);
OleDbHResult hr = (OleDbHResult)NativeOledbWrapper.IChapteredRowsetReleaseChapter(base.handle, chapter);
Bid.Trace("<oledb.IChapteredRowset.ReleaseChapter|API|OLEDB|RET> %08X{HRESULT}\n", hr);
}
return base.ReleaseHandle();
}
}
}
|