public static SqlInternalConnection GetPooledConnection(SqlConnectionString options, out bool isInTransaction) { // If Init() has not been called, call it and set up the cached members if (null == _manager) { Init(); } ConnectionPool pool = null; SqlConnectionPoolControl poolControl = null; SqlInternalConnection con = null; IntPtr SID = IntPtr.Zero; // Actual SID IntPtr tokenStruct = IntPtr.Zero; // Struct in memory containing SID string encryptedConnectionString = options.EncryptedActualConnectionString; try { // 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. _txPool is not created on 9x, so if that is not null then we // know we are not on 9x so go ahead do security check. if (options.IntegratedSecurity && !_isWindows9x) { // If using integrated security, find the pool based on the connection string. Then, // compare the SIDs of all pools to find a match. If no match found, create a new pool. // This will guarantee anyone using integrated security will always be sent to the // appropriate pool. DefaultPoolControl.ObtainSidInfo(out SID, out tokenStruct); pool = _manager.FindPool(encryptedConnectionString, SID); // If we found a pool, then we no longer need this SID - free it's token struct! // However, if we did not find a pool then we will create a new one and it will be up // to that pool to free the tokenStruct memory. if (null != pool) { Marshal.FreeHGlobal(tokenStruct); } } else { pool = _manager.FindPool(encryptedConnectionString); } if (pool == null) { // If pool is null, then we need to create a new pool - based on the connection string // and userid. SID and tokenStruct are included for integrated security connections. if (options.IntegratedSecurity && !_isWindows9x) { poolControl = new SqlConnectionPoolControl(encryptedConnectionString, true, SID, tokenStruct, options); pool = _manager.FindOrCreatePool(poolControl, SID); // MDAC 81288 } else { poolControl = new SqlConnectionPoolControl(encryptedConnectionString, false, IntPtr.Zero, IntPtr.Zero, options); pool = _manager.FindOrCreatePool(poolControl); // MDAC 81288 } } } catch { // If an exception is thrown and the pool was not created or found, then we need to free the memory for // the token struct. if (null == poolControl) { Marshal.FreeHGlobal(tokenStruct); } throw; } con = pool.GetConnection(out isInTransaction); // If GetObject() failed, the pool timeout occurred. if (con == null) { throw SQL.PooledOpenTimeout(); } return(con); }
private void PoolCreateRequest(object state) { // called by pooler to ensure pool requests are currently being satisfied - // creation mutex has not been obtained // Before creating any new connections, reclaim any released connections that // were not closed. CheckForDeadConnections(); Counter comp = _poolCounter.Clone(); if (comp.IsInError) { return; } int nFree = comp.FreeCount; int nWait = comp.WaitCount; int nTotal = comp.TotalCount; if ((nTotal < _ctrl.MaxPool) && (((nFree == nWait) && (nTotal > 0)) || (nFree < nWait) || (nTotal < _ctrl.MinPool))) { // Check to see if pool was created using integrated security. If so, check to make // sure identity of current user matches that of user that created pool. If it doesn't match, // do not create any connections on the ThreadPool thread, since either Open will fail or we // will open a connection for this pool that does not belong in this pool. The side effect of this // is that if using integrated security min pool size cannot be guaranteed. // Also - 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 (_ctrl.IntegratedSecurity && !SQL.IsPlatformWin9x()) { IntPtr SID = IntPtr.Zero; IntPtr tokenStruct = IntPtr.Zero; try { DefaultPoolControl.ObtainSidInfo(out SID, out tokenStruct); if (!_ctrl.EqualSid(SID)) { return; } } finally { Marshal.FreeHGlobal(tokenStruct); } } try { try { // obtain creation mutex _creationMutex.WaitOne(); SqlInternalConnection newCon; comp = _poolCounter.Clone(); nFree = comp.FreeCount; nWait = comp.WaitCount; nTotal = comp.TotalCount; // Check IsInError again after obtaining mutex if (!comp.IsInError) { while ((nTotal < _ctrl.MaxPool) && (((nFree == nWait) && (nTotal > 0)) || (nFree < nWait) || (nTotal < _ctrl.MinPool))) { newCon = CreateConnection(); // We do not need to check error flag here, since we know if // CreateConnection returned null, we are in error case. if (null != newCon) { PutNewConnection(newCon); comp = _poolCounter.Clone(); nFree = comp.FreeCount; nWait = comp.WaitCount; nTotal = comp.TotalCount; } else { break; } } } } finally { // ReleaseMutex // always release _creationMutex.ReleaseMutex(); } } catch { // MDAC 80973 throw; } } }