Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / DataOracleClient / System / Data / OracleClient / OciHandle.cs / 1 / OciHandle.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Data.OracleClient { using System; using System.Data.Common; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Threading; using System.Runtime.ConstrainedExecution; //--------------------------------------------------------------------- // OciHandle // // Class to manage the lifetime of Oracle Call Interface handles, and // to simplify a number of handle-related operations // abstract internal class OciHandle : SafeHandle { [Flags] protected enum HANDLEFLAG { DEFAULT = 0, UNICODE = 1<<0, NLS = 1<<1, } private OCI.HTYPE _handleType; private int _refCount; private OciHandle _parentHandle; private bool _isUnicode; // default constructor protected OciHandle() : base(IntPtr.Zero, true) { } // OciSimpleHandle constructor protected OciHandle(OCI.HTYPE handleType) : base(IntPtr.Zero, false) { _handleType = handleType; } protected OciHandle(OciHandle parentHandle, OCI.HTYPE handleType) : this(parentHandle, handleType, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) { } protected OciHandle(OciHandle parentHandle, OCI.HTYPE handleType, OCI.MODE ocimode, HANDLEFLAG handleflags) : this() { int rc; Debug.Assert (!(parentHandle is OciSimpleHandle), "Must not create handle on top of OciSimpleHandle"); RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { _handleType = handleType; _parentHandle = parentHandle; _refCount = 1; // switch (handleType) { case OCI.HTYPE.OCI_HTYPE_ENV: Debug.Assert(null == parentHandle, "not null parentHandle?"); if ((handleflags & HANDLEFLAG.NLS) == HANDLEFLAG.NLS) { rc = TracedNativeMethods.OCIEnvNlsCreate( out base.handle, ocimode, 0, 0); if (0 != rc || IntPtr.Zero == base.handle) { throw ADP.OperationFailed("OCIEnvNlsCreate", rc); } } else { rc = TracedNativeMethods.OCIEnvCreate( out base.handle, ocimode); if (0 != rc || IntPtr.Zero == base.handle) { throw ADP.OperationFailed("OCIEnvCreate", rc); } } break; case OCI.HTYPE.OCI_HTYPE_ERROR: case OCI.HTYPE.OCI_HTYPE_SERVER: case OCI.HTYPE.OCI_HTYPE_SVCCTX: case OCI.HTYPE.OCI_HTYPE_SESSION: case OCI.HTYPE.OCI_HTYPE_STMT: Debug.Assert(null != parentHandle, "null parentHandle?"); rc = TracedNativeMethods.OCIHandleAlloc( parentHandle.EnvironmentHandle, out base.handle, handleType); if (0 != rc || IntPtr.Zero == base.handle) { throw ADP.OperationFailed("OCIHandleAlloc", rc); } break; case OCI.HTYPE.OCI_DTYPE_LOB: case OCI.HTYPE.OCI_DTYPE_FILE: case OCI.HTYPE.OCI_DTYPE_ROWID: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ: case OCI.HTYPE.OCI_DTYPE_INTERVAL_DS: Debug.Assert(null != parentHandle, "null parentHandle?"); rc = TracedNativeMethods.OCIDescriptorAlloc( parentHandle.EnvironmentHandle, out base.handle, handleType); if (0 != rc || IntPtr.Zero == base.handle) { throw ADP.OperationFailed("OCIDescriptorAlloc", rc); } break; case OCI.HTYPE.OCI_HTYPE_BIND: case OCI.HTYPE.OCI_HTYPE_DEFINE: case OCI.HTYPE.OCI_DTYPE_PARAM: Debug.Assert(null != parentHandle, "null parentHandle?"); // These three handles are Simple OCI handles -- they do not // need to be freed. break; default: Debug.Assert(false, "unexpected handleType"); break; } // If we get here, we successfully allocated the handle, so we had // better better up the parent's ref count. if (null != parentHandle) { parentHandle.AddRef(); _isUnicode = parentHandle.IsUnicode; } else { _isUnicode = (handleflags & HANDLEFLAG.UNICODE) == HANDLEFLAG.UNICODE; } } } internal OciHandle EnvironmentHandle { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { OciHandle value; if (HandleType == OCI.HTYPE.OCI_HTYPE_ENV) { value = this; } else { value = ParentHandle.EnvironmentHandle; } return value; } } internal OCI.HTYPE HandleType { get { return _handleType; } } public override bool IsInvalid { get { return (IntPtr.Zero == base.handle); } } internal bool IsUnicode { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return _isUnicode; } } internal OciHandle ParentHandle { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return _parentHandle; } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal int AddRef() { int refCount = Interlocked.Increment(ref _refCount); return refCount; } // Wrap the OCIAttrGet calls. We do not expect OCIAttrGet to fail, // so we will throw if it does. There are multiple overloads here, // one for each type of parameter that Oracle supports internal void GetAttribute(OCI.ATTR attribute, out byte value, OciErrorHandle errorHandle) { uint zero = 0; int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void GetAttribute(OCI.ATTR attribute, out short value, OciErrorHandle errorHandle) { uint zero = 0; int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void GetAttribute(OCI.ATTR attribute, out int value, OciErrorHandle errorHandle) { uint zero = 0; int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void GetAttribute(OCI.ATTR attribute, out string value, OciErrorHandle errorHandle, OracleConnection connection) { IntPtr tempptr = IntPtr.Zero; // note: no need to clean up tempptr pointer uint tempub4 = 0; int rc = TracedNativeMethods.OCIAttrGet( this, ref tempptr, ref tempub4, attribute, errorHandle ); if (0 != rc) { OracleException.Check(errorHandle, rc); } byte[] bytearray = new byte[tempub4]; Marshal.Copy(tempptr, bytearray, 0, checked((int)tempub4)); value = connection.GetString(bytearray); } internal byte[] GetBytes(string value) { byte[] result; uint valueLength = (uint)value.Length; if (IsUnicode) { result = new byte[valueLength * ADP.CharSize]; GetBytes(value.ToCharArray(), 0, valueLength, result, 0); } else { byte[] temp = new byte[valueLength * 4]; // one Unicode character can map to up to 4 bytes uint tempLength = GetBytes(value.ToCharArray(), 0, valueLength, temp, 0); result = new byte[tempLength]; Buffer.BlockCopy(temp, 0, result, 0, checked ((int)tempLength)); } return result; } internal uint GetBytes(char[] chars, int charIndex, uint charCount, byte[] bytes, int byteIndex) { uint byteCount; if (IsUnicode) { byteCount = checked ((uint)(charCount * ADP.CharSize)); Buffer.BlockCopy(chars, charIndex*ADP.CharSize, bytes, byteIndex, checked ((int)byteCount)); } else { OciHandle environmentHandle = EnvironmentHandle; GCHandle charsHandle = new GCHandle(); GCHandle bytesHandle = new GCHandle(); int rc; try { charsHandle = GCHandle.Alloc(chars, GCHandleType.Pinned); IntPtr charsPtr = new IntPtr((long)charsHandle.AddrOfPinnedObject() + charIndex); IntPtr bytesPtr; if (null == bytes) { bytesPtr = IntPtr.Zero; byteCount = 0; } else { bytesHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); bytesPtr = new IntPtr((long)bytesHandle.AddrOfPinnedObject() + byteIndex); byteCount = checked((uint)(bytes.Length-byteIndex)); } rc = UnsafeNativeMethods.OCIUnicodeToCharSet( environmentHandle, bytesPtr, byteCount, charsPtr, charCount, out byteCount ); } finally { charsHandle.Free(); if (bytesHandle.IsAllocated) bytesHandle.Free(); } if (0 != rc) { throw ADP.OperationFailed("OCIUnicodeToCharSet", rc); } } return byteCount; } internal uint GetChars(byte[] bytes, int byteIndex, uint byteCount, char[] chars, int charIndex) { uint charCount; if (IsUnicode) { Debug.Assert(0 == (byteCount & 0x1), "Odd Number of Unicode Bytes?"); charCount = checked ((uint)(byteCount / ADP.CharSize)); Buffer.BlockCopy(bytes, byteIndex, chars, charIndex*ADP.CharSize, checked((int)byteCount)); } else { OciHandle environmentHandle = EnvironmentHandle; GCHandle bytesHandle = new GCHandle(); GCHandle charsHandle = new GCHandle(); int rc; try { bytesHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); IntPtr bytesPtr = new IntPtr((long)bytesHandle.AddrOfPinnedObject() + byteIndex); IntPtr charsPtr; if (null == chars) { charsPtr = IntPtr.Zero; charCount = 0; } else { charsHandle = GCHandle.Alloc(chars, GCHandleType.Pinned); charsPtr = new IntPtr((long)charsHandle.AddrOfPinnedObject() + charIndex); charCount = checked((uint)(chars.Length-charIndex)); } rc = UnsafeNativeMethods.OCICharSetToUnicode( environmentHandle, charsPtr, charCount, bytesPtr, byteCount, out charCount ); } finally { bytesHandle.Free(); if (charsHandle.IsAllocated) charsHandle.Free(); } if (0 != rc) { throw ADP.OperationFailed("OCICharSetToUnicode", rc); } } return charCount; } //--------------------------------------------------------------------- static internal string GetAttributeName ( OciHandle handle, OCI.ATTR atype ) { if (OCI.HTYPE.OCI_DTYPE_PARAM == handle.HandleType) return ((OCI.PATTR)atype).ToString(); return atype.ToString(); } //---------------------------------------------------------------------- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] static internal IntPtr HandleValueToTrace ( OciHandle handle ) { return handle.DangerousGetHandle(); // for tracing purposes, it's safe to just print this -- no handle recycling issues. } internal string PtrToString(NativeBuffer buf) { string result = null; if (IsUnicode) result = buf.PtrToStringUni(0); else result = buf.PtrToStringAnsi(0); return result; } internal string PtrToString(IntPtr buf, int len) { string result; if (IsUnicode) result = Marshal.PtrToStringUni(buf, len); else result = Marshal.PtrToStringAnsi(buf, len); return result; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal int Release() { int refCount; RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { refCount = Interlocked.Decrement(ref _refCount); Debug.Assert (0 <= refCount, "refCount is negative?"); if (0 == refCount) { //Debug.WriteLine(String.Format("Releasing hande={0} value={1}", HandleTypeToString(this), HandleValueToString(base.handle))); IntPtr handle = Interlocked.CompareExchange(ref base.handle, IntPtr.Zero, base.handle); if (IntPtr.Zero != handle) { OCI.HTYPE handleType = HandleType; OciHandle parentHandle = ParentHandle; int rc; switch (handleType) { case OCI.HTYPE.OCI_HTYPE_ENV: Debug.Assert(null == parentHandle, "not null parentHandle?"); rc = TracedNativeMethods.OCIHandleFree(handle, handleType); if (0 != rc) { throw ADP.OperationFailed("OCIHandleFree", rc); } break; case OCI.HTYPE.OCI_HTYPE_SERVER: Debug.Assert(null != parentHandle, "null parentHandle?"); Debug.Assert(OCI.HTYPE.OCI_HTYPE_ERROR == parentHandle.HandleType, "parentHandle of server handle must be the error handle!"); // NOTE: while it might seem to be a problem here that // we are using DangerousGetHandle on the parent // handle here, the reason that we're doing it is // that we're in shutdown mode and the handle may // have already been released -- attempting to use // it any other way would cause the CLR to throw // an ObjectDisposedException wit the message // "Safe handle has been closed". The reasons for // this are that we're using our ref-counting // to enforce a specific release order, but the // GC will let the safehandle be closed long // before all of the handles that have a ref- // counts on this handle are closed, which means // that the last one will cause the server detach // call. // // There is no likelihood of having a handle // recycling attack here, because we're making // the call that we would have been making in // ReleaseHandle -- we still own the handle // until ServerDetach is called. TracedNativeMethods.OCIServerDetach(handle, parentHandle.DangerousGetHandle(), OCI.MODE.OCI_DEFAULT); // we eat failures here -- what would you suggest we do otherwise? goto case OCI.HTYPE.OCI_HTYPE_SESSION; case OCI.HTYPE.OCI_HTYPE_SVCCTX: // NOTE: while it might seem to be a problem here that // we are using DangerousGetHandle on the parent // handle here, the reason that we're doing it is // that we're in shutdown mode and the handle may // have already been released -- attempting to use // it any other way would cause the CLR to throw // an ObjectDisposedException wit the message // "Safe handle has been closed". The reasons for // this are that we're using our ref-counting // to enforce a specific release order, but the // GC will let the safehandle be closed long // before all of the handles that have a ref- // counts on this handle are closed, which means // that the last one will cause the server detach // call. // // There is no likelihood of having a handle // recycling attack here, because we're making // the call that we would have been making in // ReleaseHandle -- we still own the handle // until they are freed, and our ref counting // prevents them from being freed out of order. OciHandle sessionHandle = parentHandle; if (null != sessionHandle) { OciHandle serverHandle = sessionHandle.ParentHandle; if (null != serverHandle) { OciHandle errorHandle = serverHandle.ParentHandle; if (null != errorHandle) { rc = TracedNativeMethods.OCISessionEnd( handle, // svchp errorHandle.DangerousGetHandle(), // errhp sessionHandle.DangerousGetHandle(), // usrhp OCI.MODE.OCI_DEFAULT // mode ); } } } // we eat failures here -- what would you suggest we do otherwise? goto case OCI.HTYPE.OCI_HTYPE_ERROR; case OCI.HTYPE.OCI_HTYPE_ERROR: case OCI.HTYPE.OCI_HTYPE_SESSION: case OCI.HTYPE.OCI_HTYPE_STMT: Debug.Assert(null != parentHandle, "null parentHandle?"); rc = TracedNativeMethods.OCIHandleFree(handle, handleType); if (0 != rc) { throw ADP.OperationFailed("OCIHandleFree", rc); } break; case OCI.HTYPE.OCI_DTYPE_LOB: case OCI.HTYPE.OCI_DTYPE_FILE: case OCI.HTYPE.OCI_DTYPE_ROWID: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ: case OCI.HTYPE.OCI_DTYPE_INTERVAL_DS: Debug.Assert(null != parentHandle, "null parentHandle?"); rc = TracedNativeMethods.OCIDescriptorFree(handle, handleType); if (0 != rc) { throw ADP.OperationFailed("OCIDescriptorFree", rc); } break; default: Debug.Assert(false, "unexpected handleType"); break; } // If we ended up getting released, then we have to release // our reference on our parent. if (null != parentHandle) { parentHandle.Release(); } } } } return refCount; } override protected bool ReleaseHandle() { //Debug.WriteLine(String.Format("ReleaseHandle type={0} value={1}", HandleTypeToString(this), HandleValueToString(this))); // NOTE: The SafeHandle class guarantees this will be called exactly once. Release(); return true; } static internal void SafeDispose(ref OciHandle handle) { // Safely disposes of the handle (even if it is already null) and // then nulls it out. if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciEnvironmentHandle handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciErrorHandle handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciRowidDescriptor handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciStatementHandle handle) { if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciSessionHandle handle) { if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciServiceContextHandle handle) { if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciServerHandle handle) { if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciDefineHandle handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciBindHandle handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciParameterDescriptor handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciDateTimeDescriptor handle) { if (handle != null) { handle.Dispose(); } handle = null; } // Wrap the OCIAttrSet calls. We do not expect OCIAttrSet to fail, // so we will throw if it does. There are multiple overloads here, // one for each type of parameter that Oracle supports internal void SetAttribute(OCI.ATTR attribute, int value, OciErrorHandle errorHandle) { int rc = TracedNativeMethods.OCIAttrSet( this, // trgthndlp/trghndltyp ref value, // attributep 0, // size attribute, // attrtype errorHandle // errhp ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void SetAttribute(OCI.ATTR attribute, OciHandle value, OciErrorHandle errorHandle) { int rc = TracedNativeMethods.OCIAttrSet( this, // trgthndlp/trghndltyp value, // attributep 0, // size attribute, // attrtype errorHandle // errhp ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void SetAttribute(OCI.ATTR attribute, string value, OciErrorHandle errorHandle) { uint valueLengthAsChars = unchecked((uint)value.Length); byte[] valueAsBytes = new byte[valueLengthAsChars * 4]; uint valueLengthAsBytes = GetBytes(value.ToCharArray(), 0, valueLengthAsChars, valueAsBytes, 0); int rc = TracedNativeMethods.OCIAttrSet( this, // trgthndlp/trghndltyp valueAsBytes, // attributep valueLengthAsBytes, // size attribute, // attrtype errorHandle // errhp ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } } sealed internal class OciEnvironmentHandle : OciHandle { internal OciEnvironmentHandle(OCI.MODE environmentMode, bool unicode) : base(null, OCI.HTYPE.OCI_HTYPE_ENV, environmentMode, unicode?HANDLEFLAG.UNICODE:HANDLEFLAG.DEFAULT) {} } sealed internal class OciErrorHandle : OciHandle { bool _connectionIsBroken; internal OciErrorHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_ERROR) {} internal bool ConnectionIsBroken { get { return _connectionIsBroken; } set { _connectionIsBroken = value; } } } sealed internal class OciDateTimeDescriptor : OciHandle { internal OciDateTimeDescriptor(OciHandle parent, OCI.HTYPE dateTimeType) : base(parent, AssertDateTimeType(dateTimeType)) { } static OCI.HTYPE AssertDateTimeType(OCI.HTYPE dateTimeType) { Debug.Assert( dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP || dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ || dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ, "unexpected OciDateTime handleType"); return dateTimeType; } } sealed internal class OciFileDescriptor : OciHandle { internal OciFileDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_FILE) {} [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal int OCILobFileSetNameWrapper( OciHandle envhp, OciHandle errhp, byte[] dirAlias, ushort dirAliasLength, byte[] fileName, ushort fileNameLength) { int rc; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { IntPtr bfileDescriptor = DangerousGetHandle(); rc = UnsafeNativeMethods.OCILobFileSetName( envhp, errhp, ref bfileDescriptor, dirAlias, dirAliasLength, fileName, fileNameLength); base.handle = bfileDescriptor; } } finally { if (mustRelease) { DangerousRelease(); } } return rc; } }; sealed internal class OciIntervalDescriptor : OciHandle { internal OciIntervalDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_INTERVAL_DS) { } } sealed internal class OciLobDescriptor : OciHandle { internal OciLobDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_LOB) {} } sealed internal class OciNlsEnvironmentHandle : OciHandle { internal OciNlsEnvironmentHandle(OCI.MODE environmentMode ) : base(null, OCI.HTYPE.OCI_HTYPE_ENV, environmentMode, HANDLEFLAG.NLS) {} } sealed internal class OciRowidDescriptor : OciHandle { internal OciRowidDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_ROWID) {} internal void GetRowid( OciStatementHandle statementHandle, OciErrorHandle errorHandle ) { uint zero = 0; int rc = TracedNativeMethods.OCIAttrGet( statementHandle, this, out zero, OCI.ATTR.OCI_ATTR_ROWID, errorHandle ); if ((int)OCI.RETURNCODE.OCI_NO_DATA == rc) { Dispose(); } else if (0 != rc) { OracleException.Check(errorHandle, rc); } } } sealed internal class OciServerHandle : OciHandle { internal OciServerHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_SERVER, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {} } sealed internal class OciServiceContextHandle : OciHandle { internal OciServiceContextHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_SVCCTX, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {} } sealed internal class OciSessionHandle:OciHandle{ internal OciSessionHandle(OciHandle parent):base(parent, OCI.HTYPE.OCI_HTYPE_SESSION, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT){} } sealed internal class OciStatementHandle : OciHandle { internal OciStatementHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_STMT) { } internal OciParameterDescriptor GetDescriptor(int i, OciErrorHandle errorHandle) { // Wraps the OCIParamGet call. We do not expect it to fail, so we // will throw if it does. IntPtr paramdesc; int rc = TracedNativeMethods.OCIParamGet(this, HandleType, errorHandle, out paramdesc, i+1 ); // NOTE: Oracle is 1-based, but we're zero-based. if (0 != rc) { OracleException.Check(errorHandle, rc); } OciParameterDescriptor result = new OciParameterDescriptor(this, paramdesc); return result; } internal OciRowidDescriptor GetRowid( OciHandle environmentHandle, OciErrorHandle errorHandle ) { OciRowidDescriptor rowidHandle = new OciRowidDescriptor(environmentHandle); rowidHandle.GetRowid(this, errorHandle); return rowidHandle; } } /*+---------------------------------------------------------------------------------------------------+*/ // should be moved to a separate file abstract internal class OciSimpleHandle : OciHandle { // This class implements OciHandle for handle types that do not require // cricial finalization. internal OciSimpleHandle(OciHandle parent, OCI.HTYPE handleType, IntPtr value) : base(handleType) { base.handle = value; } public override bool IsInvalid { get { return true; // guarantees we never try and release this... } } } sealed internal class OciBindHandle : OciSimpleHandle { internal OciBindHandle(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_HTYPE_BIND, value) { } }; sealed internal class OciDefineHandle : OciSimpleHandle { internal OciDefineHandle(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_HTYPE_DEFINE, value) { } }; sealed internal class OciParameterDescriptor : OciSimpleHandle { internal OciParameterDescriptor(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_DTYPE_PARAM, value) { } }; } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Data.OracleClient { using System; using System.Data.Common; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Threading; using System.Runtime.ConstrainedExecution; //--------------------------------------------------------------------- // OciHandle // // Class to manage the lifetime of Oracle Call Interface handles, and // to simplify a number of handle-related operations // abstract internal class OciHandle : SafeHandle { [Flags] protected enum HANDLEFLAG { DEFAULT = 0, UNICODE = 1<<0, NLS = 1<<1, } private OCI.HTYPE _handleType; private int _refCount; private OciHandle _parentHandle; private bool _isUnicode; // default constructor protected OciHandle() : base(IntPtr.Zero, true) { } // OciSimpleHandle constructor protected OciHandle(OCI.HTYPE handleType) : base(IntPtr.Zero, false) { _handleType = handleType; } protected OciHandle(OciHandle parentHandle, OCI.HTYPE handleType) : this(parentHandle, handleType, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) { } protected OciHandle(OciHandle parentHandle, OCI.HTYPE handleType, OCI.MODE ocimode, HANDLEFLAG handleflags) : this() { int rc; Debug.Assert (!(parentHandle is OciSimpleHandle), "Must not create handle on top of OciSimpleHandle"); RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { _handleType = handleType; _parentHandle = parentHandle; _refCount = 1; // switch (handleType) { case OCI.HTYPE.OCI_HTYPE_ENV: Debug.Assert(null == parentHandle, "not null parentHandle?"); if ((handleflags & HANDLEFLAG.NLS) == HANDLEFLAG.NLS) { rc = TracedNativeMethods.OCIEnvNlsCreate( out base.handle, ocimode, 0, 0); if (0 != rc || IntPtr.Zero == base.handle) { throw ADP.OperationFailed("OCIEnvNlsCreate", rc); } } else { rc = TracedNativeMethods.OCIEnvCreate( out base.handle, ocimode); if (0 != rc || IntPtr.Zero == base.handle) { throw ADP.OperationFailed("OCIEnvCreate", rc); } } break; case OCI.HTYPE.OCI_HTYPE_ERROR: case OCI.HTYPE.OCI_HTYPE_SERVER: case OCI.HTYPE.OCI_HTYPE_SVCCTX: case OCI.HTYPE.OCI_HTYPE_SESSION: case OCI.HTYPE.OCI_HTYPE_STMT: Debug.Assert(null != parentHandle, "null parentHandle?"); rc = TracedNativeMethods.OCIHandleAlloc( parentHandle.EnvironmentHandle, out base.handle, handleType); if (0 != rc || IntPtr.Zero == base.handle) { throw ADP.OperationFailed("OCIHandleAlloc", rc); } break; case OCI.HTYPE.OCI_DTYPE_LOB: case OCI.HTYPE.OCI_DTYPE_FILE: case OCI.HTYPE.OCI_DTYPE_ROWID: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ: case OCI.HTYPE.OCI_DTYPE_INTERVAL_DS: Debug.Assert(null != parentHandle, "null parentHandle?"); rc = TracedNativeMethods.OCIDescriptorAlloc( parentHandle.EnvironmentHandle, out base.handle, handleType); if (0 != rc || IntPtr.Zero == base.handle) { throw ADP.OperationFailed("OCIDescriptorAlloc", rc); } break; case OCI.HTYPE.OCI_HTYPE_BIND: case OCI.HTYPE.OCI_HTYPE_DEFINE: case OCI.HTYPE.OCI_DTYPE_PARAM: Debug.Assert(null != parentHandle, "null parentHandle?"); // These three handles are Simple OCI handles -- they do not // need to be freed. break; default: Debug.Assert(false, "unexpected handleType"); break; } // If we get here, we successfully allocated the handle, so we had // better better up the parent's ref count. if (null != parentHandle) { parentHandle.AddRef(); _isUnicode = parentHandle.IsUnicode; } else { _isUnicode = (handleflags & HANDLEFLAG.UNICODE) == HANDLEFLAG.UNICODE; } } } internal OciHandle EnvironmentHandle { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { OciHandle value; if (HandleType == OCI.HTYPE.OCI_HTYPE_ENV) { value = this; } else { value = ParentHandle.EnvironmentHandle; } return value; } } internal OCI.HTYPE HandleType { get { return _handleType; } } public override bool IsInvalid { get { return (IntPtr.Zero == base.handle); } } internal bool IsUnicode { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return _isUnicode; } } internal OciHandle ParentHandle { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get { return _parentHandle; } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal int AddRef() { int refCount = Interlocked.Increment(ref _refCount); return refCount; } // Wrap the OCIAttrGet calls. We do not expect OCIAttrGet to fail, // so we will throw if it does. There are multiple overloads here, // one for each type of parameter that Oracle supports internal void GetAttribute(OCI.ATTR attribute, out byte value, OciErrorHandle errorHandle) { uint zero = 0; int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void GetAttribute(OCI.ATTR attribute, out short value, OciErrorHandle errorHandle) { uint zero = 0; int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void GetAttribute(OCI.ATTR attribute, out int value, OciErrorHandle errorHandle) { uint zero = 0; int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void GetAttribute(OCI.ATTR attribute, out string value, OciErrorHandle errorHandle, OracleConnection connection) { IntPtr tempptr = IntPtr.Zero; // note: no need to clean up tempptr pointer uint tempub4 = 0; int rc = TracedNativeMethods.OCIAttrGet( this, ref tempptr, ref tempub4, attribute, errorHandle ); if (0 != rc) { OracleException.Check(errorHandle, rc); } byte[] bytearray = new byte[tempub4]; Marshal.Copy(tempptr, bytearray, 0, checked((int)tempub4)); value = connection.GetString(bytearray); } internal byte[] GetBytes(string value) { byte[] result; uint valueLength = (uint)value.Length; if (IsUnicode) { result = new byte[valueLength * ADP.CharSize]; GetBytes(value.ToCharArray(), 0, valueLength, result, 0); } else { byte[] temp = new byte[valueLength * 4]; // one Unicode character can map to up to 4 bytes uint tempLength = GetBytes(value.ToCharArray(), 0, valueLength, temp, 0); result = new byte[tempLength]; Buffer.BlockCopy(temp, 0, result, 0, checked ((int)tempLength)); } return result; } internal uint GetBytes(char[] chars, int charIndex, uint charCount, byte[] bytes, int byteIndex) { uint byteCount; if (IsUnicode) { byteCount = checked ((uint)(charCount * ADP.CharSize)); Buffer.BlockCopy(chars, charIndex*ADP.CharSize, bytes, byteIndex, checked ((int)byteCount)); } else { OciHandle environmentHandle = EnvironmentHandle; GCHandle charsHandle = new GCHandle(); GCHandle bytesHandle = new GCHandle(); int rc; try { charsHandle = GCHandle.Alloc(chars, GCHandleType.Pinned); IntPtr charsPtr = new IntPtr((long)charsHandle.AddrOfPinnedObject() + charIndex); IntPtr bytesPtr; if (null == bytes) { bytesPtr = IntPtr.Zero; byteCount = 0; } else { bytesHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); bytesPtr = new IntPtr((long)bytesHandle.AddrOfPinnedObject() + byteIndex); byteCount = checked((uint)(bytes.Length-byteIndex)); } rc = UnsafeNativeMethods.OCIUnicodeToCharSet( environmentHandle, bytesPtr, byteCount, charsPtr, charCount, out byteCount ); } finally { charsHandle.Free(); if (bytesHandle.IsAllocated) bytesHandle.Free(); } if (0 != rc) { throw ADP.OperationFailed("OCIUnicodeToCharSet", rc); } } return byteCount; } internal uint GetChars(byte[] bytes, int byteIndex, uint byteCount, char[] chars, int charIndex) { uint charCount; if (IsUnicode) { Debug.Assert(0 == (byteCount & 0x1), "Odd Number of Unicode Bytes?"); charCount = checked ((uint)(byteCount / ADP.CharSize)); Buffer.BlockCopy(bytes, byteIndex, chars, charIndex*ADP.CharSize, checked((int)byteCount)); } else { OciHandle environmentHandle = EnvironmentHandle; GCHandle bytesHandle = new GCHandle(); GCHandle charsHandle = new GCHandle(); int rc; try { bytesHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); IntPtr bytesPtr = new IntPtr((long)bytesHandle.AddrOfPinnedObject() + byteIndex); IntPtr charsPtr; if (null == chars) { charsPtr = IntPtr.Zero; charCount = 0; } else { charsHandle = GCHandle.Alloc(chars, GCHandleType.Pinned); charsPtr = new IntPtr((long)charsHandle.AddrOfPinnedObject() + charIndex); charCount = checked((uint)(chars.Length-charIndex)); } rc = UnsafeNativeMethods.OCICharSetToUnicode( environmentHandle, charsPtr, charCount, bytesPtr, byteCount, out charCount ); } finally { bytesHandle.Free(); if (charsHandle.IsAllocated) charsHandle.Free(); } if (0 != rc) { throw ADP.OperationFailed("OCICharSetToUnicode", rc); } } return charCount; } //--------------------------------------------------------------------- static internal string GetAttributeName ( OciHandle handle, OCI.ATTR atype ) { if (OCI.HTYPE.OCI_DTYPE_PARAM == handle.HandleType) return ((OCI.PATTR)atype).ToString(); return atype.ToString(); } //---------------------------------------------------------------------- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] static internal IntPtr HandleValueToTrace ( OciHandle handle ) { return handle.DangerousGetHandle(); // for tracing purposes, it's safe to just print this -- no handle recycling issues. } internal string PtrToString(NativeBuffer buf) { string result = null; if (IsUnicode) result = buf.PtrToStringUni(0); else result = buf.PtrToStringAnsi(0); return result; } internal string PtrToString(IntPtr buf, int len) { string result; if (IsUnicode) result = Marshal.PtrToStringUni(buf, len); else result = Marshal.PtrToStringAnsi(buf, len); return result; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal int Release() { int refCount; RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { refCount = Interlocked.Decrement(ref _refCount); Debug.Assert (0 <= refCount, "refCount is negative?"); if (0 == refCount) { //Debug.WriteLine(String.Format("Releasing hande={0} value={1}", HandleTypeToString(this), HandleValueToString(base.handle))); IntPtr handle = Interlocked.CompareExchange(ref base.handle, IntPtr.Zero, base.handle); if (IntPtr.Zero != handle) { OCI.HTYPE handleType = HandleType; OciHandle parentHandle = ParentHandle; int rc; switch (handleType) { case OCI.HTYPE.OCI_HTYPE_ENV: Debug.Assert(null == parentHandle, "not null parentHandle?"); rc = TracedNativeMethods.OCIHandleFree(handle, handleType); if (0 != rc) { throw ADP.OperationFailed("OCIHandleFree", rc); } break; case OCI.HTYPE.OCI_HTYPE_SERVER: Debug.Assert(null != parentHandle, "null parentHandle?"); Debug.Assert(OCI.HTYPE.OCI_HTYPE_ERROR == parentHandle.HandleType, "parentHandle of server handle must be the error handle!"); // NOTE: while it might seem to be a problem here that // we are using DangerousGetHandle on the parent // handle here, the reason that we're doing it is // that we're in shutdown mode and the handle may // have already been released -- attempting to use // it any other way would cause the CLR to throw // an ObjectDisposedException wit the message // "Safe handle has been closed". The reasons for // this are that we're using our ref-counting // to enforce a specific release order, but the // GC will let the safehandle be closed long // before all of the handles that have a ref- // counts on this handle are closed, which means // that the last one will cause the server detach // call. // // There is no likelihood of having a handle // recycling attack here, because we're making // the call that we would have been making in // ReleaseHandle -- we still own the handle // until ServerDetach is called. TracedNativeMethods.OCIServerDetach(handle, parentHandle.DangerousGetHandle(), OCI.MODE.OCI_DEFAULT); // we eat failures here -- what would you suggest we do otherwise? goto case OCI.HTYPE.OCI_HTYPE_SESSION; case OCI.HTYPE.OCI_HTYPE_SVCCTX: // NOTE: while it might seem to be a problem here that // we are using DangerousGetHandle on the parent // handle here, the reason that we're doing it is // that we're in shutdown mode and the handle may // have already been released -- attempting to use // it any other way would cause the CLR to throw // an ObjectDisposedException wit the message // "Safe handle has been closed". The reasons for // this are that we're using our ref-counting // to enforce a specific release order, but the // GC will let the safehandle be closed long // before all of the handles that have a ref- // counts on this handle are closed, which means // that the last one will cause the server detach // call. // // There is no likelihood of having a handle // recycling attack here, because we're making // the call that we would have been making in // ReleaseHandle -- we still own the handle // until they are freed, and our ref counting // prevents them from being freed out of order. OciHandle sessionHandle = parentHandle; if (null != sessionHandle) { OciHandle serverHandle = sessionHandle.ParentHandle; if (null != serverHandle) { OciHandle errorHandle = serverHandle.ParentHandle; if (null != errorHandle) { rc = TracedNativeMethods.OCISessionEnd( handle, // svchp errorHandle.DangerousGetHandle(), // errhp sessionHandle.DangerousGetHandle(), // usrhp OCI.MODE.OCI_DEFAULT // mode ); } } } // we eat failures here -- what would you suggest we do otherwise? goto case OCI.HTYPE.OCI_HTYPE_ERROR; case OCI.HTYPE.OCI_HTYPE_ERROR: case OCI.HTYPE.OCI_HTYPE_SESSION: case OCI.HTYPE.OCI_HTYPE_STMT: Debug.Assert(null != parentHandle, "null parentHandle?"); rc = TracedNativeMethods.OCIHandleFree(handle, handleType); if (0 != rc) { throw ADP.OperationFailed("OCIHandleFree", rc); } break; case OCI.HTYPE.OCI_DTYPE_LOB: case OCI.HTYPE.OCI_DTYPE_FILE: case OCI.HTYPE.OCI_DTYPE_ROWID: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ: case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ: case OCI.HTYPE.OCI_DTYPE_INTERVAL_DS: Debug.Assert(null != parentHandle, "null parentHandle?"); rc = TracedNativeMethods.OCIDescriptorFree(handle, handleType); if (0 != rc) { throw ADP.OperationFailed("OCIDescriptorFree", rc); } break; default: Debug.Assert(false, "unexpected handleType"); break; } // If we ended up getting released, then we have to release // our reference on our parent. if (null != parentHandle) { parentHandle.Release(); } } } } return refCount; } override protected bool ReleaseHandle() { //Debug.WriteLine(String.Format("ReleaseHandle type={0} value={1}", HandleTypeToString(this), HandleValueToString(this))); // NOTE: The SafeHandle class guarantees this will be called exactly once. Release(); return true; } static internal void SafeDispose(ref OciHandle handle) { // Safely disposes of the handle (even if it is already null) and // then nulls it out. if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciEnvironmentHandle handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciErrorHandle handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciRowidDescriptor handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciStatementHandle handle) { if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciSessionHandle handle) { if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciServiceContextHandle handle) { if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciServerHandle handle) { if (null != handle) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciDefineHandle handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciBindHandle handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose (ref OciParameterDescriptor handle) { if (handle != null) { handle.Dispose(); } handle = null; } static internal void SafeDispose(ref OciDateTimeDescriptor handle) { if (handle != null) { handle.Dispose(); } handle = null; } // Wrap the OCIAttrSet calls. We do not expect OCIAttrSet to fail, // so we will throw if it does. There are multiple overloads here, // one for each type of parameter that Oracle supports internal void SetAttribute(OCI.ATTR attribute, int value, OciErrorHandle errorHandle) { int rc = TracedNativeMethods.OCIAttrSet( this, // trgthndlp/trghndltyp ref value, // attributep 0, // size attribute, // attrtype errorHandle // errhp ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void SetAttribute(OCI.ATTR attribute, OciHandle value, OciErrorHandle errorHandle) { int rc = TracedNativeMethods.OCIAttrSet( this, // trgthndlp/trghndltyp value, // attributep 0, // size attribute, // attrtype errorHandle // errhp ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } internal void SetAttribute(OCI.ATTR attribute, string value, OciErrorHandle errorHandle) { uint valueLengthAsChars = unchecked((uint)value.Length); byte[] valueAsBytes = new byte[valueLengthAsChars * 4]; uint valueLengthAsBytes = GetBytes(value.ToCharArray(), 0, valueLengthAsChars, valueAsBytes, 0); int rc = TracedNativeMethods.OCIAttrSet( this, // trgthndlp/trghndltyp valueAsBytes, // attributep valueLengthAsBytes, // size attribute, // attrtype errorHandle // errhp ); if (0 != rc) { OracleException.Check(errorHandle, rc); } } } sealed internal class OciEnvironmentHandle : OciHandle { internal OciEnvironmentHandle(OCI.MODE environmentMode, bool unicode) : base(null, OCI.HTYPE.OCI_HTYPE_ENV, environmentMode, unicode?HANDLEFLAG.UNICODE:HANDLEFLAG.DEFAULT) {} } sealed internal class OciErrorHandle : OciHandle { bool _connectionIsBroken; internal OciErrorHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_ERROR) {} internal bool ConnectionIsBroken { get { return _connectionIsBroken; } set { _connectionIsBroken = value; } } } sealed internal class OciDateTimeDescriptor : OciHandle { internal OciDateTimeDescriptor(OciHandle parent, OCI.HTYPE dateTimeType) : base(parent, AssertDateTimeType(dateTimeType)) { } static OCI.HTYPE AssertDateTimeType(OCI.HTYPE dateTimeType) { Debug.Assert( dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP || dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ || dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ, "unexpected OciDateTime handleType"); return dateTimeType; } } sealed internal class OciFileDescriptor : OciHandle { internal OciFileDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_FILE) {} [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal int OCILobFileSetNameWrapper( OciHandle envhp, OciHandle errhp, byte[] dirAlias, ushort dirAliasLength, byte[] fileName, ushort fileNameLength) { int rc; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { IntPtr bfileDescriptor = DangerousGetHandle(); rc = UnsafeNativeMethods.OCILobFileSetName( envhp, errhp, ref bfileDescriptor, dirAlias, dirAliasLength, fileName, fileNameLength); base.handle = bfileDescriptor; } } finally { if (mustRelease) { DangerousRelease(); } } return rc; } }; sealed internal class OciIntervalDescriptor : OciHandle { internal OciIntervalDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_INTERVAL_DS) { } } sealed internal class OciLobDescriptor : OciHandle { internal OciLobDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_LOB) {} } sealed internal class OciNlsEnvironmentHandle : OciHandle { internal OciNlsEnvironmentHandle(OCI.MODE environmentMode ) : base(null, OCI.HTYPE.OCI_HTYPE_ENV, environmentMode, HANDLEFLAG.NLS) {} } sealed internal class OciRowidDescriptor : OciHandle { internal OciRowidDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_ROWID) {} internal void GetRowid( OciStatementHandle statementHandle, OciErrorHandle errorHandle ) { uint zero = 0; int rc = TracedNativeMethods.OCIAttrGet( statementHandle, this, out zero, OCI.ATTR.OCI_ATTR_ROWID, errorHandle ); if ((int)OCI.RETURNCODE.OCI_NO_DATA == rc) { Dispose(); } else if (0 != rc) { OracleException.Check(errorHandle, rc); } } } sealed internal class OciServerHandle : OciHandle { internal OciServerHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_SERVER, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {} } sealed internal class OciServiceContextHandle : OciHandle { internal OciServiceContextHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_SVCCTX, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {} } sealed internal class OciSessionHandle:OciHandle{ internal OciSessionHandle(OciHandle parent):base(parent, OCI.HTYPE.OCI_HTYPE_SESSION, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT){} } sealed internal class OciStatementHandle : OciHandle { internal OciStatementHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_STMT) { } internal OciParameterDescriptor GetDescriptor(int i, OciErrorHandle errorHandle) { // Wraps the OCIParamGet call. We do not expect it to fail, so we // will throw if it does. IntPtr paramdesc; int rc = TracedNativeMethods.OCIParamGet(this, HandleType, errorHandle, out paramdesc, i+1 ); // NOTE: Oracle is 1-based, but we're zero-based. if (0 != rc) { OracleException.Check(errorHandle, rc); } OciParameterDescriptor result = new OciParameterDescriptor(this, paramdesc); return result; } internal OciRowidDescriptor GetRowid( OciHandle environmentHandle, OciErrorHandle errorHandle ) { OciRowidDescriptor rowidHandle = new OciRowidDescriptor(environmentHandle); rowidHandle.GetRowid(this, errorHandle); return rowidHandle; } } /*+---------------------------------------------------------------------------------------------------+*/ // should be moved to a separate file abstract internal class OciSimpleHandle : OciHandle { // This class implements OciHandle for handle types that do not require // cricial finalization. internal OciSimpleHandle(OciHandle parent, OCI.HTYPE handleType, IntPtr value) : base(handleType) { base.handle = value; } public override bool IsInvalid { get { return true; // guarantees we never try and release this... } } } sealed internal class OciBindHandle : OciSimpleHandle { internal OciBindHandle(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_HTYPE_BIND, value) { } }; sealed internal class OciDefineHandle : OciSimpleHandle { internal OciDefineHandle(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_HTYPE_DEFINE, value) { } }; sealed internal class OciParameterDescriptor : OciSimpleHandle { internal OciParameterDescriptor(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_DTYPE_PARAM, value) { } }; } // 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
- XmlWellformedWriter.cs
- CommonProperties.cs
- Vector3DCollectionConverter.cs
- Dispatcher.cs
- WebPartVerbsEventArgs.cs
- ErrorView.xaml.cs
- WindowCollection.cs
- RenderData.cs
- MetadataWorkspace.cs
- AccessDataSourceView.cs
- KeyedCollection.cs
- ImageConverter.cs
- RSACryptoServiceProvider.cs
- SchemeSettingElementCollection.cs
- DirectoryNotFoundException.cs
- HtmlEncodedRawTextWriter.cs
- MessageQueueConverter.cs
- SQLInt64.cs
- SqlGatherProducedAliases.cs
- TextRangeEditTables.cs
- ConnectionStringSettingsCollection.cs
- loginstatus.cs
- System.Data_BID.cs
- CultureInfoConverter.cs
- DataPagerFieldCommandEventArgs.cs
- ResourceReferenceExpressionConverter.cs
- ReadOnlyHierarchicalDataSourceView.cs
- ProfileManager.cs
- DispatcherObject.cs
- DockPanel.cs
- ItemsControl.cs
- BufferedOutputStream.cs
- Baml2006ReaderContext.cs
- Int64AnimationBase.cs
- RotateTransform3D.cs
- PagedControl.cs
- SqlDependencyUtils.cs
- EntityStoreSchemaFilterEntry.cs
- CredentialCache.cs
- Models.cs
- ContextMenuStrip.cs
- BindingCompleteEventArgs.cs
- SqlPersistenceWorkflowInstanceDescription.cs
- TransformerInfo.cs
- MethodExecutor.cs
- RawStylusActions.cs
- QueryExtender.cs
- DurableTimerExtension.cs
- DrawingContextWalker.cs
- DataGridViewDesigner.cs
- MouseGestureConverter.cs
- FileInfo.cs
- SqlTypesSchemaImporter.cs
- XPathBuilder.cs
- TextAction.cs
- BuildManager.cs
- ScriptResourceInfo.cs
- ExpressionParser.cs
- PrintController.cs
- CodeSpit.cs
- XhtmlBasicLinkAdapter.cs
- DataRecordInternal.cs
- DeadCharTextComposition.cs
- Int32Collection.cs
- DataObjectSettingDataEventArgs.cs
- PersonalizationProviderCollection.cs
- SecUtil.cs
- CommandBindingCollection.cs
- SmtpException.cs
- SingleObjectCollection.cs
- ConfigurationSchemaErrors.cs
- TileBrush.cs
- SerializableAttribute.cs
- Camera.cs
- TypeCodeDomSerializer.cs
- VirtualPath.cs
- HtmlTable.cs
- RtfNavigator.cs
- wmiprovider.cs
- RequestQueue.cs
- TouchFrameEventArgs.cs
- TextDecorationCollection.cs
- ApplicationSecurityManager.cs
- SecurityPolicySection.cs
- TransportConfigurationTypeElementCollection.cs
- TheQuery.cs
- Closure.cs
- EntityContainerEntitySet.cs
- ProtocolsSection.cs
- IImplicitResourceProvider.cs
- SoundPlayer.cs
- ButtonBase.cs
- StringFreezingAttribute.cs
- SqlMetaData.cs
- XPathException.cs
- RangeBase.cs
- Process.cs
- BrowserCapabilitiesCodeGenerator.cs
- Condition.cs
- SqlCachedBuffer.cs