diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
index bfeaed46f5..494bd0b96c 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -123,6 +123,9 @@
Microsoft\Data\ProviderBase\DbConnectionPoolGroupProviderInfo.cs
+
+ Microsoft\Data\ProviderBase\DbConnectionPoolIdentity.cs
+
Microsoft\Data\ProviderBase\DbConnectionPoolOptions.cs
@@ -634,8 +637,6 @@
-
-
@@ -839,6 +840,9 @@
Microsoft\Data\Common\AdapterUtil.Windows.cs
+
+ Microsoft\Data\ProviderBase\DbConnectionPoolIdentity.Windows.cs
+
Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs
@@ -856,7 +860,6 @@
-
@@ -909,9 +912,11 @@
Microsoft\Data\Common\AdapterUtil.Unix.cs
+
+ Microsoft\Data\ProviderBase\DbConnectionPoolIdentity.Unix.cs
+
-
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs
deleted file mode 100644
index 4a59e0b858..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#if NET6_0_OR_GREATER
-
-using System.Diagnostics;
-using Microsoft.Data.Common;
-using Microsoft.Data.SqlClient;
-
-namespace Microsoft.Data.ProviderBase
-{
- internal sealed partial class DbConnectionPool
- {
- private bool IsBlockingPeriodEnabled()
- {
- var poolGroupConnectionOptions = _connectionPoolGroup.ConnectionOptions as SqlConnectionString;
- if (poolGroupConnectionOptions == null)
- {
- return true;
- }
- var policy = poolGroupConnectionOptions.PoolBlockingPeriod;
-
- switch (policy)
- {
- case PoolBlockingPeriod.Auto:
- {
- return !ADP.IsAzureSqlServerEndpoint(poolGroupConnectionOptions.DataSource);
- }
- case PoolBlockingPeriod.AlwaysBlock:
- {
- return true; //Enabled
- }
- case PoolBlockingPeriod.NeverBlock:
- {
- return false; //Disabled
- }
- default:
- {
- //we should never get into this path.
- Debug.Fail("Unknown PoolBlockingPeriod. Please specify explicit results in above switch case statement.");
- return true;
- }
- }
- }
- }
-}
-
-#endif
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs
index 745ca55c0e..5694d8c05f 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs
@@ -15,7 +15,7 @@
namespace Microsoft.Data.ProviderBase
{
- sealed internal partial class DbConnectionPool
+ internal sealed class DbConnectionPool
{
private enum State
{
@@ -1763,5 +1763,39 @@ private DbConnectionInternal UserCreateRequest(DbConnection owningObject, DbConn
return obj;
}
}
+
+#if NET6_0_OR_GREATER
+ private bool IsBlockingPeriodEnabled()
+ {
+ var poolGroupConnectionOptions = _connectionPoolGroup.ConnectionOptions as SqlConnectionString;
+ if (poolGroupConnectionOptions == null)
+ {
+ return true;
+ }
+ var policy = poolGroupConnectionOptions.PoolBlockingPeriod;
+
+ switch (policy)
+ {
+ case PoolBlockingPeriod.Auto:
+ {
+ return !ADP.IsAzureSqlServerEndpoint(poolGroupConnectionOptions.DataSource);
+ }
+ case PoolBlockingPeriod.AlwaysBlock:
+ {
+ return true; //Enabled
+ }
+ case PoolBlockingPeriod.NeverBlock:
+ {
+ return false; //Disabled
+ }
+ default:
+ {
+ //we should never get into this path.
+ Debug.Fail("Unknown PoolBlockingPeriod. Please specify explicit results in above switch case statement.");
+ return true;
+ }
+ }
+ }
+#endif
}
}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
index 840f5b6520..2a15e3245a 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -147,6 +147,12 @@
Microsoft\Data\ProviderBase\DbConnectionPoolGroupProviderInfo.cs
+
+ Microsoft\Data\ProviderBase\DbConnectionPoolIdentity.cs
+
+
+ Microsoft\Data\ProviderBase\DbConnectionPoolIdentity.Windows.cs
+
Microsoft\Data\ProviderBase\DbConnectionPoolOptions.cs
@@ -662,13 +668,11 @@
-
-
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbBuffer.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbBuffer.cs
deleted file mode 100644
index 590561d7fc..0000000000
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbBuffer.cs
+++ /dev/null
@@ -1,807 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace Microsoft.Data.ProviderBase
-{
- using System;
- using System.Diagnostics;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using Microsoft.Data.Common;
-
- // DbBuffer is abstract to require derived class to exist
- // so that when debugging, we can tell the difference between one DbBuffer and another
- internal abstract class DbBuffer : SafeHandle
- {
- internal const int LMEM_FIXED = 0x0000;
- internal const int LMEM_MOVEABLE = 0x0002;
- internal const int LMEM_ZEROINIT = 0x0040;
-
- private readonly int _bufferLength;
-
- private DbBuffer(int initialSize, bool zeroBuffer) : base(IntPtr.Zero, true)
- {
- if (0 < initialSize)
- {
- int flags = ((zeroBuffer) ? LMEM_ZEROINIT : LMEM_FIXED);
-
- _bufferLength = initialSize;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- { }
- finally
- {
- base.handle = SafeNativeMethods.LocalAlloc(flags, (IntPtr)initialSize);
- }
- if (IntPtr.Zero == base.handle)
- {
- throw new OutOfMemoryException();
- }
- }
- }
-
- protected DbBuffer(int initialSize) : this(initialSize, true)
- {
- }
-
- protected DbBuffer(IntPtr invalidHandleValue, bool ownsHandle) : base(invalidHandleValue, ownsHandle)
- {
- }
-
- private int BaseOffset { get { return 0; } }
-
- public override bool IsInvalid
- {
- get
- {
- return (IntPtr.Zero == base.handle);
- }
- }
-
- internal int Length
- {
- get
- {
- return _bufferLength;
- }
- }
-
- internal string PtrToStringUni(int offset)
- {
- offset += BaseOffset;
- Validate(offset, 2);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
-
- string value = null;
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- int length = UnsafeNativeMethods.lstrlenW(ptr);
- Validate(offset, (2 * (length + 1)));
- value = Marshal.PtrToStringUni(ptr, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
-
- return value;
- }
-
- internal String PtrToStringUni(int offset, int length)
- {
- offset += BaseOffset;
- Validate(offset, 2 * length);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
-
- string value = null;
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- value = Marshal.PtrToStringUni(ptr, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- return value;
- }
-
- internal byte ReadByte(int offset)
- {
- offset += BaseOffset;
- ValidateCheck(offset, 1);
- Debug.Assert(0 == offset % 4, "invalid alignment");
-
- byte value;
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- value = Marshal.ReadByte(ptr, offset);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- return value;
- }
-
- internal byte[] ReadBytes(int offset, int length)
- {
- byte[] value = new byte[length];
- return ReadBytes(offset, value, 0, length);
- }
-
- internal byte[] ReadBytes(int offset, byte[] destination, int startIndex, int length)
- {
- offset += BaseOffset;
- Validate(offset, length);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
- Debug.Assert(destination != null, "null destination");
- Debug.Assert(startIndex + length <= destination.Length, "destination too small");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- Marshal.Copy(ptr, destination, startIndex, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- return destination;
- }
-
- internal Char ReadChar(int offset)
- {
- short value = ReadInt16(offset);
- return unchecked((char)value);
- }
-
- internal char[] ReadChars(int offset, char[] destination, int startIndex, int length)
- {
- offset += BaseOffset;
- Validate(offset, 2 * length);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
- Debug.Assert(destination != null, "null destination");
- Debug.Assert(startIndex + length <= destination.Length, "destination too small");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- Marshal.Copy(ptr, destination, startIndex, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- return destination;
- }
-
- internal Double ReadDouble(int offset)
- {
- Int64 value = ReadInt64(offset);
- return BitConverter.Int64BitsToDouble(value);
- }
-
- internal Int16 ReadInt16(int offset)
- {
- offset += BaseOffset;
- ValidateCheck(offset, 2);
- Debug.Assert(0 == offset % 2, "invalid alignment");
-
- short value;
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- value = Marshal.ReadInt16(ptr, offset);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- return value;
- }
-
- internal void ReadInt16Array(int offset, short[] destination, int startIndex, int length)
- {
- offset += BaseOffset;
- Validate(offset, 2 * length);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
- Debug.Assert(destination != null, "null destination");
- Debug.Assert(startIndex + length <= destination.Length, "destination too small");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- Marshal.Copy(ptr, destination, startIndex, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal Int32 ReadInt32(int offset)
- {
- offset += BaseOffset;
- ValidateCheck(offset, 4);
- Debug.Assert(0 == offset % 4, "invalid alignment");
-
- int value;
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- value = Marshal.ReadInt32(ptr, offset);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- return value;
- }
-
- internal void ReadInt32Array(int offset, int[] destination, int startIndex, int length)
- {
- offset += BaseOffset;
- Validate(offset, 4 * length);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
- Debug.Assert(destination != null, "null destination");
- Debug.Assert(startIndex + length <= destination.Length, "destination too small");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- Marshal.Copy(ptr, destination, startIndex, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal Int64 ReadInt64(int offset)
- {
- offset += BaseOffset;
- ValidateCheck(offset, 8);
- Debug.Assert(0 == offset % IntPtr.Size, "invalid alignment");
-
- long value;
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- value = Marshal.ReadInt64(ptr, offset);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- return value;
- }
-
- internal IntPtr ReadIntPtr(int offset)
- {
- offset += BaseOffset;
- ValidateCheck(offset, IntPtr.Size);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
-
- IntPtr value;
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- value = Marshal.ReadIntPtr(ptr, offset);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- return value;
- }
-
- internal unsafe Single ReadSingle(int offset)
- {
- Int32 value = ReadInt32(offset);
- return *(Single*)&value;
- }
-
- override protected 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.LocalFree(ptr);
- }
- return true;
- }
-
- private void StructureToPtr(int offset, object structure)
- {
- Debug.Assert(structure != null, "null structure");
- offset += BaseOffset;
- ValidateCheck(offset, Marshal.SizeOf(structure.GetType()));
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- Marshal.StructureToPtr(structure, ptr, false/*fDeleteOld*/);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal void WriteByte(int offset, byte value)
- {
- offset += BaseOffset;
- ValidateCheck(offset, 1);
- Debug.Assert(0 == offset % 4, "invalid alignment");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- Marshal.WriteByte(ptr, offset, value);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal void WriteBytes(int offset, byte[] source, int startIndex, int length)
- {
- offset += BaseOffset;
- Validate(offset, length);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
- Debug.Assert(source != null, "null source");
- Debug.Assert(startIndex + length <= source.Length, "source too small");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- Marshal.Copy(source, startIndex, ptr, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal void WriteCharArray(int offset, char[] source, int startIndex, int length)
- {
- offset += BaseOffset;
- Validate(offset, 2 * length);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
- Debug.Assert(source != null, "null source");
- Debug.Assert(startIndex + length <= source.Length, "source too small");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- Marshal.Copy(source, startIndex, ptr, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal void WriteDouble(int offset, Double value)
- {
- WriteInt64(offset, BitConverter.DoubleToInt64Bits(value));
- }
-
- internal void WriteInt16(int offset, short value)
- {
- offset += BaseOffset;
- ValidateCheck(offset, 2);
- Debug.Assert(0 == offset % 2, "invalid alignment");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- Marshal.WriteInt16(ptr, offset, value);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal void WriteInt16Array(int offset, short[] source, int startIndex, int length)
- {
- offset += BaseOffset;
- Validate(offset, 2 * length);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
- Debug.Assert(source != null, "null source");
- Debug.Assert(startIndex + length <= source.Length, "source too small");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- Marshal.Copy(source, startIndex, ptr, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal void WriteInt32(int offset, int value)
- {
- offset += BaseOffset;
- ValidateCheck(offset, 4);
- Debug.Assert(0 == offset % 4, "invalid alignment");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- Marshal.WriteInt32(ptr, offset, value);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal void WriteInt32Array(int offset, int[] source, int startIndex, int length)
- {
- offset += BaseOffset;
- Validate(offset, 4 * length);
- Debug.Assert(0 == offset % ADP.s_ptrSize, "invalid alignment");
- Debug.Assert(source != null, "null source");
- Debug.Assert(startIndex + length <= source.Length, "source too small");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset);
- Marshal.Copy(source, startIndex, ptr, length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal void WriteInt64(int offset, long value)
- {
- offset += BaseOffset;
- ValidateCheck(offset, 8);
- Debug.Assert(0 == offset % IntPtr.Size, "invalid alignment");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- Marshal.WriteInt64(ptr, offset, value);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal void WriteIntPtr(int offset, IntPtr value)
- {
- offset += BaseOffset;
- ValidateCheck(offset, IntPtr.Size);
- Debug.Assert(0 == offset % IntPtr.Size, "invalid alignment");
-
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- Marshal.WriteIntPtr(ptr, offset, value);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal unsafe void WriteSingle(int offset, Single value)
- {
- WriteInt32(offset, *(Int32*)&value);
- }
-
- internal void ZeroMemory()
- {
- bool mustRelease = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- DangerousAddRef(ref mustRelease);
-
- IntPtr ptr = DangerousGetHandle();
- SafeNativeMethods.ZeroMemory(ptr, (IntPtr)Length);
- }
- finally
- {
- if (mustRelease)
- {
- DangerousRelease();
- }
- }
- }
-
- internal Guid ReadGuid(int offset)
- {
- // faster than Marshal.PtrToStructure(offset, typeof(Guid))
- byte[] buffer = new byte[16];
- ReadBytes(offset, buffer, 0, 16);
- return new Guid(buffer);
- }
- internal void WriteGuid(int offset, Guid value)
- {
- // faster than Marshal.Copy(value.GetByteArray()
- StructureToPtr(offset, value);
- }
-
- internal DateTime ReadDate(int offset)
- {
- short[] buffer = new short[3];
- ReadInt16Array(offset, buffer, 0, 3);
- return new DateTime(
- unchecked((ushort)buffer[0]), // Year
- unchecked((ushort)buffer[1]), // Month
- unchecked((ushort)buffer[2])); // Day
- }
- internal void WriteDate(int offset, DateTime value)
- {
- short[] buffer = new short[3] {
- unchecked((short)value.Year),
- unchecked((short)value.Month),
- unchecked((short)value.Day),
- };
- WriteInt16Array(offset, buffer, 0, 3);
- }
-
- internal TimeSpan ReadTime(int offset)
- {
- short[] buffer = new short[3];
- ReadInt16Array(offset, buffer, 0, 3);
- return new TimeSpan(
- unchecked((ushort)buffer[0]), // Hours
- unchecked((ushort)buffer[1]), // Minutes
- unchecked((ushort)buffer[2])); // Seconds
- }
- internal void WriteTime(int offset, TimeSpan value)
- {
- short[] buffer = new short[3] {
- unchecked((short)value.Hours),
- unchecked((short)value.Minutes),
- unchecked((short)value.Seconds),
- };
- WriteInt16Array(offset, buffer, 0, 3);
- }
-
- internal DateTime ReadDateTime(int offset)
- {
- short[] buffer = new short[6];
- ReadInt16Array(offset, buffer, 0, 6);
- int ticks = ReadInt32(offset + 12);
- DateTime value = new DateTime(
- unchecked((ushort)buffer[0]), // Year
- unchecked((ushort)buffer[1]), // Month
- unchecked((ushort)buffer[2]), // Day
- unchecked((ushort)buffer[3]), // Hours
- unchecked((ushort)buffer[4]), // Minutes
- unchecked((ushort)buffer[5])); // Seconds
- return value.AddTicks(ticks / 100);
- }
- internal void WriteDateTime(int offset, DateTime value)
- {
- int ticks = (int)(value.Ticks % 10000000L) * 100;
- short[] buffer = new short[6] {
- unchecked((short)value.Year),
- unchecked((short)value.Month),
- unchecked((short)value.Day),
- unchecked((short)value.Hour),
- unchecked((short)value.Minute),
- unchecked((short)value.Second),
- };
- WriteInt16Array(offset, buffer, 0, 6);
- WriteInt32(offset + 12, ticks);
- }
-
- internal Decimal ReadNumeric(int offset)
- {
- byte[] bits = new byte[20];
- ReadBytes(offset, bits, 1, 19);
-
- int[] buffer = new int[4];
- buffer[3] = ((int)bits[2]) << 16; // scale
- if (0 == bits[3])
- {
- buffer[3] |= unchecked((int)0x80000000); //sign
- }
- buffer[0] = BitConverter.ToInt32(bits, 4); // low
- buffer[1] = BitConverter.ToInt32(bits, 8); // mid
- buffer[2] = BitConverter.ToInt32(bits, 12); // high
- if (0 != BitConverter.ToInt32(bits, 16))
- {
- throw ADP.NumericToDecimalOverflow();
- }
- return new Decimal(buffer);
- }
-
- internal void WriteNumeric(int offset, Decimal value, byte precision)
- {
- int[] tmp = Decimal.GetBits(value);
- byte[] buffer = new byte[20];
-
- buffer[1] = precision;
- Buffer.BlockCopy(tmp, 14, buffer, 2, 2); // copy sign and scale
- buffer[3] = (Byte)((0 == buffer[3]) ? 1 : 0); // flip sign for native
- Buffer.BlockCopy(tmp, 0, buffer, 4, 12);
- buffer[16] = 0;
- buffer[17] = 0;
- buffer[18] = 0;
- buffer[19] = 0;
- WriteBytes(offset, buffer, 1, 19);
- }
-
- [ConditionalAttribute("DEBUG")]
- protected void ValidateCheck(int offset, int count)
- {
- Validate(offset, count);
- }
-
- protected void Validate(int offset, int count)
- {
- if ((offset < 0) || (count < 0) || (Length < checked(offset + count)))
- {
- throw ADP.InternalError(ADP.InternalErrorCode.InvalidBuffer);
- }
- }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs
index dc80876cd1..061f60d3f1 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs
@@ -310,9 +310,8 @@ internal void TransactionEnded(Transaction transaction, DbConnectionInternal tra
}
- private sealed class PoolWaitHandles : DbBuffer
+ private sealed class PoolWaitHandles
{
-
private readonly Semaphore _poolSemaphore;
private readonly ManualResetEvent _errorEvent;
@@ -321,63 +320,19 @@ private sealed class PoolWaitHandles : DbBuffer
// Using an AutoResetEvent does not have that complication.
private readonly Semaphore _creationSemaphore;
- private readonly SafeHandle _poolHandle;
- private readonly SafeHandle _errorHandle;
- private readonly SafeHandle _creationHandle;
-
- private readonly int _releaseFlags;
+ private readonly WaitHandle[] _handlesWithCreate;
+ private readonly WaitHandle[] _handlesWithoutCreate;
[ResourceExposure(ResourceScope.None)] // SxS: this method does not create named objects
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
- internal PoolWaitHandles() : base(3 * IntPtr.Size)
+ internal PoolWaitHandles()
{
- bool mustRelease1 = false, mustRelease2 = false, mustRelease3 = false;
-
_poolSemaphore = new Semaphore(0, MAX_Q_SIZE);
_errorEvent = new ManualResetEvent(false);
_creationSemaphore = new Semaphore(1, 1);
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- // because SafeWaitHandle doesn't have reliability contract
- _poolHandle = _poolSemaphore.SafeWaitHandle;
- _errorHandle = _errorEvent.SafeWaitHandle;
- _creationHandle = _creationSemaphore.SafeWaitHandle;
-
- _poolHandle.DangerousAddRef(ref mustRelease1);
- _errorHandle.DangerousAddRef(ref mustRelease2);
- _creationHandle.DangerousAddRef(ref mustRelease3);
-
- Debug.Assert(0 == SEMAPHORE_HANDLE, "SEMAPHORE_HANDLE");
- Debug.Assert(1 == ERROR_HANDLE, "ERROR_HANDLE");
- Debug.Assert(2 == CREATION_HANDLE, "CREATION_HANDLE");
-
- WriteIntPtr(SEMAPHORE_HANDLE * IntPtr.Size, _poolHandle.DangerousGetHandle());
- WriteIntPtr(ERROR_HANDLE * IntPtr.Size, _errorHandle.DangerousGetHandle());
- WriteIntPtr(CREATION_HANDLE * IntPtr.Size, _creationHandle.DangerousGetHandle());
- }
- finally
- {
- if (mustRelease1)
- {
- _releaseFlags |= 1;
- }
- if (mustRelease2)
- {
- _releaseFlags |= 2;
- }
- if (mustRelease3)
- {
- _releaseFlags |= 4;
- }
- }
- }
-
- internal SafeHandle CreationHandle
- {
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- get { return _creationHandle; }
+ _handlesWithCreate = new WaitHandle[] { _poolSemaphore, _errorEvent, _creationSemaphore };
+ _handlesWithoutCreate = new WaitHandle[] { _poolSemaphore, _errorEvent };
}
internal Semaphore CreationSemaphore
@@ -395,23 +350,9 @@ internal Semaphore PoolSemaphore
get { return _poolSemaphore; }
}
- protected override bool ReleaseHandle()
+ internal WaitHandle[] GetHandles(bool withCreate)
{
- // NOTE: The SafeHandle class guarantees this will be called exactly once.
- // we know we can touch these other managed objects because of our original DangerousAddRef
- if (0 != (1 & _releaseFlags))
- {
- _poolHandle.DangerousRelease();
- }
- if (0 != (2 & _releaseFlags))
- {
- _errorHandle.DangerousRelease();
- }
- if (0 != (4 & _releaseFlags))
- {
- _creationHandle.DangerousRelease();
- }
- return base.ReleaseHandle();
+ return withCreate ? _handlesWithCreate : _handlesWithoutCreate;
}
}
@@ -425,10 +366,7 @@ protected override bool ReleaseHandle()
private const int CREATION_HANDLE = (int)0x2;
private const int BOGUS_HANDLE = (int)0x3;
- private const int WAIT_OBJECT_0 = 0;
- private const int WAIT_TIMEOUT = (int)0x102;
private const int WAIT_ABANDONED = (int)0x80;
- private const int WAIT_FAILED = -1;
private const int ERROR_WAIT_DEFAULT = 5 * 1000; // 5 seconds
@@ -1350,36 +1288,23 @@ private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObj
if (obj == null)
{
Interlocked.Increment(ref _waitCount);
- uint waitHandleCount = allowCreate ? 3u : 2u;
do
{
int waitResult = BOGUS_HANDLE;
- int releaseSemaphoreResult = 0;
- bool mustRelease = false;
- int waitForMultipleObjectsExHR = 0;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
- _waitHandles.DangerousAddRef(ref mustRelease);
-
// We absolutely must have the value of waitResult set,
// or we may leak the mutex in async abort cases.
RuntimeHelpers.PrepareConstrainedRegions();
try
{
- Debug.Assert(2 == waitHandleCount || 3 == waitHandleCount, "unexpected waithandle count");
}
finally
{
- waitResult = SafeNativeMethods.WaitForMultipleObjectsEx(waitHandleCount, _waitHandles.DangerousGetHandle(), false, waitForMultipleObjectsTimeout, false);
-
- // VSTFDEVDIV 479551 - call GetHRForLastWin32Error immediately after after the native call
- if (waitResult == WAIT_FAILED)
- {
- waitForMultipleObjectsExHR = Marshal.GetHRForLastWin32Error();
- }
+ waitResult = WaitHandle.WaitAny(_waitHandles.GetHandles(allowCreate), unchecked((int)waitForMultipleObjectsTimeout));
}
// From the WaitAny docs: "If more than one object became signaled during
@@ -1390,14 +1315,13 @@ private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObj
switch (waitResult)
{
- case WAIT_TIMEOUT:
+ case WaitHandle.WaitTimeout:
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Wait timed out.", ObjectID);
Interlocked.Decrement(ref _waitCount);
connection = null;
return false;
case ERROR_HANDLE:
-
// Throw the error that PoolCreateRequest stashed.
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Errors are set.", ObjectID);
Interlocked.Decrement(ref _waitCount);
@@ -1442,7 +1366,7 @@ private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObj
{
// modify handle array not to wait on creation mutex anymore
Debug.Assert(2 == CREATION_HANDLE, "creation handle changed value");
- waitHandleCount = 2;
+ allowCreate = false;
}
}
}
@@ -1487,13 +1411,6 @@ private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObj
}
break;
- case WAIT_FAILED:
- Debug.Assert(waitForMultipleObjectsExHR != 0, "WaitForMultipleObjectsEx failed but waitForMultipleObjectsExHR remained 0");
- SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Wait failed.", ObjectID);
- Interlocked.Decrement(ref _waitCount);
- Marshal.ThrowExceptionForHR(waitForMultipleObjectsExHR);
- goto default; // if ThrowExceptionForHR didn't throw for some reason
-
case (WAIT_ABANDONED + SEMAPHORE_HANDLE):
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Semaphore handle abandonded.", ObjectID);
Interlocked.Decrement(ref _waitCount);
@@ -1519,21 +1436,9 @@ private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObj
{
if (CREATION_HANDLE == waitResult)
{
- int result = SafeNativeMethods.ReleaseSemaphore(_waitHandles.CreationHandle.DangerousGetHandle(), 1, IntPtr.Zero);
- if (0 == result)
- { // failure case
- releaseSemaphoreResult = Marshal.GetHRForLastWin32Error();
- }
- }
- if (mustRelease)
- {
- _waitHandles.DangerousRelease();
+ _waitHandles.CreationSemaphore.Release(1);
}
}
- if (0 != releaseSemaphoreResult)
- {
- Marshal.ThrowExceptionForHR(releaseSemaphoreResult); // will only throw if (hresult < 0)
- }
// Do not use this pooled connection if access token is about to expire soon before we can connect.
if (obj != null && obj.IsAccessTokenExpired)
@@ -1707,15 +1612,11 @@ private void PoolCreateRequest(object state)
{
return;
}
- bool mustRelease = false;
int waitResult = BOGUS_HANDLE;
- uint timeout = (uint)CreationTimeout;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
- _waitHandles.DangerousAddRef(ref mustRelease);
-
// Obtain creation mutex so we're the only one creating objects
// and we must have the wait result
RuntimeHelpers.PrepareConstrainedRegions();
@@ -1723,9 +1624,9 @@ private void PoolCreateRequest(object state)
{ }
finally
{
- waitResult = SafeNativeMethods.WaitForSingleObjectEx(_waitHandles.CreationHandle.DangerousGetHandle(), timeout, false);
+ waitResult = WaitHandle.WaitAny(_waitHandles.GetHandles(withCreate: true), CreationTimeout);
}
- if (WAIT_OBJECT_0 == waitResult)
+ if (CREATION_HANDLE == waitResult)
{
DbConnectionInternal newObj;
@@ -1734,9 +1635,19 @@ private void PoolCreateRequest(object state)
{
while (NeedToReplenish)
{
- // Don't specify any user options because there is no outer connection associated with the new connection
- newObj = CreateObject(owningObject: null, userOptions: null, oldConnection: null);
-
+ try
+ {
+ // Don't specify any user options because there is no outer connection associated with the new connection
+ newObj = CreateObject(owningObject: null, userOptions: null, oldConnection: null);
+ }
+ catch
+ {
+ // Catch all the exceptions occuring during CreateObject so that they
+ // don't emerge as unhandled on the thread pool and don't crash applications
+ // The error is handled in CreateObject and surfaced to the caller of the Connection Pool
+ // using the ErrorEvent. Hence it is OK to swallow all exceptions here.
+ break;
+ }
// We do not need to check error flag here, since we know if
// CreateObject returned null, we are in error case.
if (newObj != null)
@@ -1750,7 +1661,7 @@ private void PoolCreateRequest(object state)
}
}
}
- else if (WAIT_TIMEOUT == waitResult)
+ else if (WaitHandle.WaitTimeout == waitResult)
{
// do not wait forever and potential block this worker thread
// instead wait for a period of time and just requeue to try again
@@ -1777,14 +1688,10 @@ private void PoolCreateRequest(object state)
}
finally
{
- if (WAIT_OBJECT_0 == waitResult)
+ if (CREATION_HANDLE == waitResult)
{
// reuse waitResult and ignore its value
- waitResult = SafeNativeMethods.ReleaseSemaphore(_waitHandles.CreationHandle.DangerousGetHandle(), 1, IntPtr.Zero);
- }
- if (mustRelease)
- {
- _waitHandles.DangerousRelease();
+ _waitHandles.CreationSemaphore.Release(1);
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.cs
deleted file mode 100644
index ef79538a0e..0000000000
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.cs
+++ /dev/null
@@ -1,240 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace Microsoft.Data.ProviderBase
-{
-
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Security.Permissions;
- using System.Security.Principal;
- using Microsoft.Data.Common;
-
- [Serializable] // Serializable so SqlDependencyProcessDispatcher can marshall cross domain to SqlDependency.
- sealed internal class DbConnectionPoolIdentity
- {
- private const int E_NotImpersonationToken = unchecked((int)0x8007051D);
- private const int Win32_CheckTokenMembership = 1;
- private const int Win32_GetTokenInformation_1 = 2;
- private const int Win32_GetTokenInformation_2 = 3;
- private const int Win32_ConvertSidToStringSidW = 4;
- private const int Win32_CreateWellKnownSid = 5;
-
- static public readonly DbConnectionPoolIdentity NoIdentity = new DbConnectionPoolIdentity(String.Empty, false, true);
- static private readonly byte[] NetworkSid = (ADP.s_isWindowsNT ? CreateWellKnownSid(WellKnownSidType.NetworkSid) : null);
- static private DbConnectionPoolIdentity _lastIdentity = null;
-
- private readonly string _sidString;
- private readonly bool _isRestricted;
- private readonly bool _isNetwork;
- private readonly int _hashCode;
-
- private DbConnectionPoolIdentity(string sidString, bool isRestricted, bool isNetwork)
- {
- _sidString = sidString;
- _isRestricted = isRestricted;
- _isNetwork = isNetwork;
- _hashCode = sidString == null ? 0 : sidString.GetHashCode();
- }
-
- internal bool IsRestricted
- {
- get { return _isRestricted; }
- }
-
- internal bool IsNetwork
- {
- get { return _isNetwork; }
- }
-
- static private byte[] CreateWellKnownSid(WellKnownSidType sidType)
- {
- // Passing an array as big as it can ever be is a small price to pay for
- // not having to P/Invoke twice (once to get the buffer, once to get the data)
-
- uint length = (uint)SecurityIdentifier.MaxBinaryLength;
- byte[] resultSid = new byte[length];
-
- // NOTE - We copied this code from System.Security.Principal.Win32.CreateWellKnownSid...
-
- if (0 == UnsafeNativeMethods.CreateWellKnownSid((int)sidType, null, resultSid, ref length))
- {
- IntegratedSecurityError(Win32_CreateWellKnownSid);
- }
- return resultSid;
- }
-
- override public bool Equals(object value)
- {
- bool result = ((this == NoIdentity) || (this == value));
- if (!result && value != null)
- {
- DbConnectionPoolIdentity that = ((DbConnectionPoolIdentity)value);
- result = ((this._sidString == that._sidString) && (this._isRestricted == that._isRestricted) && (this._isNetwork == that._isNetwork));
- }
- return result;
- }
-
- [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.ControlPrincipal)]
- static internal WindowsIdentity GetCurrentWindowsIdentity()
- {
- return WindowsIdentity.GetCurrent();
- }
-
- [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)]
- static private IntPtr GetWindowsIdentityToken(WindowsIdentity identity)
- {
- return identity.Token;
- }
-
- [ResourceExposure(ResourceScope.None)] // SxS: this method does not create named objects
- [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
- static internal DbConnectionPoolIdentity GetCurrent()
- {
-
- // DEVNOTE: GetTokenInfo and EqualSID do not work on 9x. WindowsIdentity does not
- // work either on 9x. In fact, after checking with native there is no way
- // to validate the user on 9x, so simply don't. It is a known issue in
- // native, and we will handle this the same way.
-
- if (!ADP.s_isWindowsNT)
- {
- return NoIdentity;
- }
-
- WindowsIdentity identity = GetCurrentWindowsIdentity();
- IntPtr token = GetWindowsIdentityToken(identity); // Free'd by WindowsIdentity.
- uint bufferLength = 2048; // Suggested default given by Greg Fee.
- uint lengthNeeded = 0;
-
- IntPtr tokenStruct = IntPtr.Zero;
- IntPtr SID;
- IntPtr sidStringBuffer = IntPtr.Zero;
- bool isNetwork;
-
- // Win32NativeMethods.IsTokenRestricted will raise exception if the native call fails
- bool isRestricted = Win32NativeMethods.IsTokenRestrictedWrapper(token);
-
- DbConnectionPoolIdentity current = null;
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- if (!UnsafeNativeMethods.CheckTokenMembership(token, NetworkSid, out isNetwork))
- {
- // will always fail with 0x8007051D if token is not an impersonation token
- IntegratedSecurityError(Win32_CheckTokenMembership);
- }
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- { }
- finally
- {
- // allocating memory and assigning to tokenStruct must happen
- tokenStruct = SafeNativeMethods.LocalAlloc(DbBuffer.LMEM_FIXED, (IntPtr)bufferLength);
- }
- if (IntPtr.Zero == tokenStruct)
- {
- throw new OutOfMemoryException();
- }
- if (!UnsafeNativeMethods.GetTokenInformation(token, 1, tokenStruct, bufferLength, ref lengthNeeded))
- {
- if (lengthNeeded > bufferLength)
- {
- bufferLength = lengthNeeded;
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- { }
- finally
- {
- // freeing token struct and setting tokenstruct to null must happen together
- // allocating memory and assigning to tokenStruct must happen
- SafeNativeMethods.LocalFree(tokenStruct);
- tokenStruct = IntPtr.Zero; // protect against LocalAlloc throwing an exception
- tokenStruct = SafeNativeMethods.LocalAlloc(DbBuffer.LMEM_FIXED, (IntPtr)bufferLength);
- }
- if (IntPtr.Zero == tokenStruct)
- {
- throw new OutOfMemoryException();
- }
-
- if (!UnsafeNativeMethods.GetTokenInformation(token, 1, tokenStruct, bufferLength, ref lengthNeeded))
- {
- IntegratedSecurityError(Win32_GetTokenInformation_1);
- }
- }
- else
- {
- IntegratedSecurityError(Win32_GetTokenInformation_2);
- }
- }
-
- identity.Dispose(); // Keep identity variable alive until after GetTokenInformation calls.
-
-
- SID = Marshal.ReadIntPtr(tokenStruct, 0);
-
- if (!UnsafeNativeMethods.ConvertSidToStringSidW(SID, out sidStringBuffer))
- {
- IntegratedSecurityError(Win32_ConvertSidToStringSidW);
- }
-
- if (IntPtr.Zero == sidStringBuffer)
- {
- throw ADP.InternalError(ADP.InternalErrorCode.ConvertSidToStringSidWReturnedNull);
- }
-
- string sidString = Marshal.PtrToStringUni(sidStringBuffer);
-
- var lastIdentity = _lastIdentity;
- if ((lastIdentity != null) && (lastIdentity._sidString == sidString) && (lastIdentity._isRestricted == isRestricted) && (lastIdentity._isNetwork == isNetwork))
- {
- current = lastIdentity;
- }
- else
- {
- current = new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork);
- }
- }
- finally
- {
- // Marshal.FreeHGlobal does not have a ReliabilityContract
- if (IntPtr.Zero != tokenStruct)
- {
- SafeNativeMethods.LocalFree(tokenStruct);
- tokenStruct = IntPtr.Zero;
- }
- if (IntPtr.Zero != sidStringBuffer)
- {
- SafeNativeMethods.LocalFree(sidStringBuffer);
- sidStringBuffer = IntPtr.Zero;
- }
- }
- _lastIdentity = current;
- return current;
- }
-
- override public int GetHashCode()
- {
- return _hashCode;
- }
-
- static private void IntegratedSecurityError(int caller)
- {
- // passing 1,2,3,4,5 instead of true/false so that with a debugger
- // we could determine more easily which Win32 method call failed
- int lastError = Marshal.GetHRForLastWin32Error();
- if ((Win32_CheckTokenMembership != caller) || (E_NotImpersonationToken != lastError))
- {
- Marshal.ThrowExceptionForHR(lastError); // will only throw if (hresult < 0)
- }
- }
-
- }
-}
-
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Unix.cs
similarity index 100%
rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Unix.cs
rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Unix.cs
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Windows.cs
similarity index 73%
rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Windows.cs
rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Windows.cs
index 93d2b0f329..62fbc34aed 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Windows.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.Windows.cs
@@ -3,6 +3,8 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Runtime.Versioning;
+using System.Security.Permissions;
using System.Security.Principal;
using Microsoft.Data.SqlClient;
@@ -10,12 +12,25 @@ namespace Microsoft.Data.ProviderBase
{
partial class DbConnectionPoolIdentity
{
- private static DbConnectionPoolIdentity s_lastIdentity = null;
+#if NETFRAMEWORK
+ [ResourceExposure(ResourceScope.None)] // SxS: this method does not create named objects
+ [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
+ internal static DbConnectionPoolIdentity GetCurrent()
+ {
+ return GetCurrentNative();
+ }
+ [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.ControlPrincipal)]
+ internal static WindowsIdentity GetCurrentWindowsIdentity()
+ {
+ return WindowsIdentity.GetCurrent();
+ }
+#else
internal static DbConnectionPoolIdentity GetCurrent()
{
return TdsParserStateObjectFactory.UseManagedSNI ? GetCurrentManaged() : GetCurrentNative();
}
+#endif
private static DbConnectionPoolIdentity GetCurrentNative()
{
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.cs
similarity index 73%
rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.cs
rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.cs
index 7b650bd6f7..e97f55a7ad 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolIdentity.cs
@@ -7,6 +7,7 @@ namespace Microsoft.Data.ProviderBase
sealed internal partial class DbConnectionPoolIdentity
{
public static readonly DbConnectionPoolIdentity NoIdentity = new DbConnectionPoolIdentity(string.Empty, false, true);
+ private static DbConnectionPoolIdentity s_lastIdentity = null;
private readonly string _sidString;
private readonly bool _isRestricted;
@@ -43,13 +44,26 @@ override public int GetHashCode()
return _hashCode;
}
- internal static DbConnectionPoolIdentity GetCurrentManaged()
+ private static DbConnectionPoolIdentity GetCurrentManaged()
{
+ DbConnectionPoolIdentity current;
string domainString = System.Environment.UserDomainName;
string sidString = (!string.IsNullOrWhiteSpace(domainString) ? domainString + "\\" : "") + System.Environment.UserName;
bool isNetwork = false;
bool isRestricted = false;
- return new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork);
+
+ var lastIdentity = s_lastIdentity;
+
+ if ((lastIdentity != null) && (lastIdentity._sidString == sidString) && (lastIdentity._isRestricted == isRestricted) && (lastIdentity._isNetwork == isNetwork))
+ {
+ current = lastIdentity;
+ }
+ else
+ {
+ current = new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork);
+ }
+ s_lastIdentity = current;
+ return current;
}
}
}