Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / Odbc / OdbcHandle.cs / 1305376 / OdbcHandle.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
// [....]
//-----------------------------------------------------------------------------
using System;
using System.Collections;
using System.ComponentModel;
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.Text;
using System.Threading;
using System.Runtime.ConstrainedExecution;
namespace System.Data.Odbc {
internal abstract class OdbcHandle : SafeHandle {
private ODBC32.SQL_HANDLE _handleType;
private OdbcHandle _parentHandle;
protected OdbcHandle(ODBC32.SQL_HANDLE handleType, OdbcHandle parentHandle) : base(IntPtr.Zero, true) {
_handleType = handleType;
bool mustRelease = false;
ODBC32.RetCode retcode = ODBC32.RetCode.SUCCESS;
// using ConstrainedRegions to make the native ODBC call and AddRef the parent
RuntimeHelpers.PrepareConstrainedRegions();
try {
// validate handleType
switch(handleType) {
case ODBC32.SQL_HANDLE.ENV:
Debug.Assert(null == parentHandle, "did not expect a parent handle");
retcode = UnsafeNativeMethods.SQLAllocHandle(handleType, IntPtr.Zero, out base.handle);
break;
case ODBC32.SQL_HANDLE.DBC:
case ODBC32.SQL_HANDLE.STMT:
// must addref before calling native so it won't be released just after
Debug.Assert(null != parentHandle, "expected a parent handle"); // safehandle can't be null
parentHandle.DangerousAddRef(ref mustRelease);
retcode = UnsafeNativeMethods.SQLAllocHandle(handleType, parentHandle, out base.handle);
break;
// case ODBC32.SQL_HANDLE.DESC:
default:
Debug.Assert(false, "unexpected handleType");
break;
}
}
finally {
if (mustRelease) {
switch(handleType) {
case ODBC32.SQL_HANDLE.DBC:
case ODBC32.SQL_HANDLE.STMT:
if (IntPtr.Zero != base.handle) {
// must assign _parentHandle after a handle is actually created
// since ReleaseHandle will only call DangerousRelease if a handle exists
_parentHandle = parentHandle;
}
else {
// without a handle, ReleaseHandle may not be called
parentHandle.DangerousRelease();
}
break;
}
}
}
Bid.TraceSqlReturn(" %08X{SQLRETURN}\n", retcode);
if((ADP.PtrZero == base.handle) || (ODBC32.RetCode.SUCCESS != retcode)) {
//
throw ODBC.CantAllocateEnvironmentHandle(retcode);
}
}
internal OdbcHandle(OdbcStatementHandle parentHandle, ODBC32.SQL_ATTR attribute) : base(IntPtr.Zero, true) {
Debug.Assert((ODBC32.SQL_ATTR.APP_PARAM_DESC == attribute) || (ODBC32.SQL_ATTR.APP_ROW_DESC == attribute), "invalid attribute");
_handleType = ODBC32.SQL_HANDLE.DESC;
int cbActual;
ODBC32.RetCode retcode;
bool mustRelease = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
// must addref before calling native so it won't be released just after
parentHandle.DangerousAddRef(ref mustRelease);
retcode = parentHandle.GetStatementAttribute(attribute, out base.handle, out cbActual);
}
finally {
if (mustRelease) {
if (IntPtr.Zero != base.handle) {
// must call DangerousAddRef after a handle is actually created
// since ReleaseHandle will only call DangerousRelease if a handle exists
_parentHandle = parentHandle;
}
else {
// without a handle, ReleaseHandle may not be called
parentHandle.DangerousRelease();
}
}
}
if (ADP.PtrZero == base.handle) {
throw ODBC.FailedToGetDescriptorHandle(retcode);
}
// no info-message handle on getting a descriptor handle
}
internal ODBC32.SQL_HANDLE HandleType {
get {
return _handleType;
}
}
public override bool IsInvalid {
get {
// we should not have a parent if we do not have a handle
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 handle = base.handle;
base.handle = IntPtr.Zero;
if (IntPtr.Zero != handle) {
ODBC32.SQL_HANDLE handleType = HandleType;
switch (handleType) {
case ODBC32.SQL_HANDLE.DBC:
// Disconnect happens in OdbcConnectionHandle.ReleaseHandle
case ODBC32.SQL_HANDLE.ENV:
case ODBC32.SQL_HANDLE.STMT:
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLFreeHandle(handleType, handle);
Bid.TraceSqlReturn(" %08X{SQLRETURN}\n", retcode);
break;
case ODBC32.SQL_HANDLE.DESC:
// nothing to free on the handle
break;
// case 0: ThreadAbortException setting handle before HandleType
default:
Debug.Assert(ADP.PtrZero == handle, "unknown handle type");
break;
}
}
// If we ended up getting released, then we have to release
// our reference on our parent.
OdbcHandle parentHandle = _parentHandle;
_parentHandle = null;
if (null != parentHandle) {
parentHandle.DangerousRelease();
parentHandle = null;
}
return true;
}
internal ODBC32.RetCode GetDiagnosticField (out string sqlState) {
short cbActual;
// ODBC (MSDN) documents it expects a buffer large enough to hold 5(+L'\0') unicode characters
StringBuilder sb = new StringBuilder(6);
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetDiagFieldW(
HandleType,
this,
(short)1,
ODBC32.SQL_DIAG_SQLSTATE,
sb,
checked((short)(2*sb.Capacity)), // expects number of bytes, see \\kbinternal\kb\articles\294\1\69.HTM
out cbActual);
ODBC.TraceODBC(3, "SQLGetDiagFieldW", retcode);
if ((retcode == ODBC32.RetCode.SUCCESS) || (retcode == ODBC32.RetCode.SUCCESS_WITH_INFO)) {
sqlState = sb.ToString();
}
else {
sqlState = ADP.StrEmpty;
}
return retcode;
}
internal ODBC32.RetCode GetDiagnosticRecord(short record, out string sqlState, StringBuilder message, out int nativeError, out short cchActual) {
// ODBC (MSDN) documents it expects a buffer large enough to hold 4(+L'\0') unicode characters
StringBuilder sb = new StringBuilder(5);
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetDiagRecW(HandleType, this, record, sb, out nativeError, message, checked((short)message.Capacity), out cchActual);
ODBC.TraceODBC(3, "SQLGetDiagRecW", retcode);
if ((retcode == ODBC32.RetCode.SUCCESS) || (retcode == ODBC32.RetCode.SUCCESS_WITH_INFO)) {
sqlState = sb.ToString();
}
else {
sqlState = ADP.StrEmpty;
}
return retcode;
}
}
sealed internal class OdbcDescriptorHandle : OdbcHandle {
internal OdbcDescriptorHandle(OdbcStatementHandle statementHandle, ODBC32.SQL_ATTR attribute) : base(statementHandle, attribute) {
}
internal ODBC32.RetCode GetDescriptionField(int i, ODBC32.SQL_DESC attribute, CNativeBuffer buffer, out int numericAttribute) {
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetDescFieldW(this, checked((short)i), attribute, buffer, buffer.ShortLength, out numericAttribute);
ODBC.TraceODBC(3, "SQLGetDescFieldW", retcode);
return retcode;
}
internal ODBC32.RetCode SetDescriptionField1(short ordinal, ODBC32.SQL_DESC type, IntPtr value) {
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLSetDescFieldW(this, ordinal, type, value, 0);
ODBC.TraceODBC(3, "SQLSetDescFieldW", retcode);
return retcode;
}
internal ODBC32.RetCode SetDescriptionField2(short ordinal, ODBC32.SQL_DESC type, HandleRef value) {
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLSetDescFieldW(this, ordinal, type, value, 0);
ODBC.TraceODBC(3, "SQLSetDescFieldW", retcode);
return retcode;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlArrayAttribute.cs
- AppSettingsReader.cs
- XPathSingletonIterator.cs
- RadioButtonRenderer.cs
- SecurityUniqueId.cs
- PageParser.cs
- Menu.cs
- HtmlInputCheckBox.cs
- LabelInfo.cs
- ScalarType.cs
- ActiveXHost.cs
- RawUIStateInputReport.cs
- SqlClientMetaDataCollectionNames.cs
- ValueExpressions.cs
- PinnedBufferMemoryStream.cs
- OracleBoolean.cs
- RuntimeCompatibilityAttribute.cs
- Int32RectValueSerializer.cs
- HebrewNumber.cs
- PopOutPanel.cs
- WindowsStartMenu.cs
- XmlEntityReference.cs
- DeferrableContent.cs
- ContractUtils.cs
- Privilege.cs
- Query.cs
- SqlCacheDependencyDatabase.cs
- RuntimeConfigurationRecord.cs
- NamedPipeHostedTransportConfiguration.cs
- MarkupExtensionReturnTypeAttribute.cs
- GridViewRowPresenter.cs
- ToolStripPanel.cs
- ExtendedPropertyCollection.cs
- ButtonBase.cs
- SelectedDatesCollection.cs
- TargetControlTypeAttribute.cs
- TagNameToTypeMapper.cs
- cookiecollection.cs
- MetabaseReader.cs
- StrokeNodeOperations.cs
- UnsafeMethods.cs
- PersistChildrenAttribute.cs
- BitmapEffect.cs
- DataSpaceManager.cs
- PasswordRecoveryAutoFormat.cs
- SelectedCellsCollection.cs
- ResolvedKeyFrameEntry.cs
- ColumnReorderedEventArgs.cs
- SessionStateModule.cs
- BinaryNode.cs
- AuthenticationModuleElementCollection.cs
- DefaultPropertyAttribute.cs
- IProvider.cs
- Inline.cs
- InvokeSchedule.cs
- ToolStripOverflow.cs
- ResourceWriter.cs
- AssemblyFilter.cs
- CalendarDateChangedEventArgs.cs
- Win32.cs
- DataAccessException.cs
- FloaterBaseParaClient.cs
- SafeProcessHandle.cs
- HttpResponseHeader.cs
- ByteAnimationUsingKeyFrames.cs
- FrameworkElementFactory.cs
- Int64.cs
- OperandQuery.cs
- SolidColorBrush.cs
- MenuItemAutomationPeer.cs
- InputLanguage.cs
- DispatcherHookEventArgs.cs
- PKCS1MaskGenerationMethod.cs
- SQLSingleStorage.cs
- WorkflowInlining.cs
- ThumbAutomationPeer.cs
- TreeViewEvent.cs
- XmlTextReaderImplHelpers.cs
- PointCollection.cs
- XmlDataSource.cs
- OSFeature.cs
- XsltContext.cs
- StringFunctions.cs
- EmbeddedMailObjectsCollection.cs
- Error.cs
- ContainerSelectorGlyph.cs
- DataSourceProvider.cs
- ResponseStream.cs
- ViewBox.cs
- ActivityStateQuery.cs
- BuilderElements.cs
- DoubleAnimationClockResource.cs
- PageContentCollection.cs
- TypeTypeConverter.cs
- PrivateUnsafeNativeCompoundFileMethods.cs
- HotCommands.cs
- DataGridBoolColumn.cs
- BaseTemplateBuildProvider.cs
- AccessViolationException.cs
- HttpCookiesSection.cs