internal IdentityUserNamePair(DbConnectionPoolIdentity identity, string userName) { Debug.Assert((identity == null && userName != null) || (identity != null && userName == null), "Unexpected arguments!"); _identity = identity; _userName = userName; }
protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection) { string instanceName; SqlConnectionString str = (SqlConnectionString)options; if (str.ContextConnection) { return(this.GetContextConnection(str, poolGroupProviderInfo, owningConnection)); } bool redirectedUserInstance = false; DbConnectionPoolIdentity current = null; if (str.IntegratedSecurity) { if (pool != null) { current = pool.Identity; } else { current = DbConnectionPoolIdentity.GetCurrent(); } } if (!str.UserInstance) { goto Label_00F1; } redirectedUserInstance = true; if ((pool == null) || ((pool != null) && (pool.Count <= 0))) { using (SqlInternalConnectionTds tds = null) { SqlConnectionString connectionOptions = new SqlConnectionString(str, str.DataSource, true, false); tds = new SqlInternalConnectionTds(current, connectionOptions, null, "", null, false); instanceName = tds.InstanceName; if (!instanceName.StartsWith(@"\\.\", StringComparison.Ordinal)) { throw SQL.NonLocalSSEInstance(); } if (pool != null) { SqlConnectionPoolProviderInfo info2 = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; info2.InstanceName = instanceName; } goto Label_00DB; } } SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; instanceName = providerInfo.InstanceName; Label_00DB: str = new SqlConnectionString(str, instanceName, false, null); poolGroupProviderInfo = null; Label_00F1: return(new SqlInternalConnectionTds(current, str, poolGroupProviderInfo, "", (SqlConnection)owningConnection, redirectedUserInstance)); }
override public bool Equals(object value) { bool result = ((this == NoIdentity) || (this == value)); if (!result && (null != value)) { DbConnectionPoolIdentity that = ((DbConnectionPoolIdentity)value); result = ((_sidString == that._sidString) && (_isRestricted == that._isRestricted) && (_isNetwork == that._isNetwork)); } return(result); }
internal SqlInternalConnectionTds(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, object providerInfo, string newPassword, SqlConnection owningObject, bool redirectedUserInstance) : base(connectionOptions) { this._instanceName = string.Empty; if (connectionOptions.UserInstance && InOutOfProcHelper.InProc) { throw SQL.UserInstanceNotAvailableInProc(); } this._identity = identity; this._poolGroupProviderInfo = (SqlConnectionPoolGroupProviderInfo)providerInfo; this._fResetConnection = connectionOptions.ConnectionReset; if (this._fResetConnection) { this._originalDatabase = connectionOptions.InitialCatalog; this._originalLanguage = connectionOptions.CurrentLanguage; } RuntimeHelpers.PrepareConstrainedRegions(); try { TimeoutTimer timeout = TimeoutTimer.StartSecondsTimeout(connectionOptions.ConnectTimeout); this.OpenLoginEnlist(owningObject, timeout, connectionOptions, newPassword, redirectedUserInstance); } catch (OutOfMemoryException) { base.DoomThisConnection(); throw; } catch (StackOverflowException) { base.DoomThisConnection(); throw; } catch (ThreadAbortException) { base.DoomThisConnection(); throw; } if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.ctor|ADV> %d#, constructed new TDS internal connection\n", base.ObjectID); } }
protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) { SqlConnectionString opt = (SqlConnectionString)options; SqlConnectionPoolKey key = (SqlConnectionPoolKey)poolKey; SqlInternalConnection result = null; SessionData recoverySessionData = null; SqlConnection sqlOwningConnection = (SqlConnection)owningConnection; bool applyTransientFaultHandling = sqlOwningConnection != null ? sqlOwningConnection._applyTransientFaultHandling : false; SqlConnectionString userOpt = null; if (userOptions != null) { userOpt = (SqlConnectionString)userOptions; } else if (sqlOwningConnection != null) { userOpt = (SqlConnectionString)(sqlOwningConnection.UserConnectionOptions); } if (sqlOwningConnection != null) { recoverySessionData = sqlOwningConnection._recoverySessionData; } bool redirectedUserInstance = false; DbConnectionPoolIdentity identity = null; // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security. // Used by notifications. if (opt.IntegratedSecurity) { if (pool != null) { identity = pool.Identity; } else { identity = DbConnectionPoolIdentity.GetCurrent(); } } // FOLLOWING IF BLOCK IS ENTIRELY FOR SSE USER INSTANCES // If "user instance=true" is in the connection string, we're using SSE user instances if (opt.UserInstance) { // opt.DataSource is used to create the SSE connection redirectedUserInstance = true; string instanceName; if ((null == pool) || (null != pool && pool.Count <= 0)) { // Non-pooled or pooled and no connections in the pool. SqlInternalConnectionTds sseConnection = null; try { // We throw an exception in case of a failure // NOTE: Cloning connection option opt to set 'UserInstance=True' and 'Enlist=False' // This first connection is established to SqlExpress to get the instance name // of the UserInstance. SqlConnectionString sseopt = new SqlConnectionString(opt, opt.DataSource, userInstance: true, setEnlistValue: false); sseConnection = new SqlInternalConnectionTds(identity, sseopt, key.Credential, null, "", null, false, applyTransientFaultHandling: applyTransientFaultHandling); // NOTE: Retrieve <UserInstanceName> here. This user instance name will be used below to connect to the Sql Express User Instance. instanceName = sseConnection.InstanceName; if (!instanceName.StartsWith("\\\\.\\", StringComparison.Ordinal)) { throw SQL.NonLocalSSEInstance(); } if (null != pool) { // Pooled connection - cache result SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; // No lock since we are already in creation mutex providerInfo.InstanceName = instanceName; } } finally { if (null != sseConnection) { sseConnection.Dispose(); } } } else { // Cached info from pool. SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; // No lock since we are already in creation mutex instanceName = providerInfo.InstanceName; } // NOTE: Here connection option opt is cloned to set 'instanceName=<UserInstanceName>' that was // retrieved from the previous SSE connection. For this UserInstance connection 'Enlist=True'. // options immutable - stored in global hash - don't modify opt = new SqlConnectionString(opt, instanceName, userInstance: false, setEnlistValue: null); poolGroupProviderInfo = null; // null so we do not pass to constructor below... } result = new SqlInternalConnectionTds(identity, opt, key.Credential, poolGroupProviderInfo, "", null, redirectedUserInstance, userOpt, recoverySessionData, applyTransientFaultHandling: applyTransientFaultHandling, key.AccessToken); return(result); }
override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) { SqlConnectionString opt = (SqlConnectionString)options; SqlConnectionPoolKey key = (SqlConnectionPoolKey)poolKey; SqlInternalConnection result = null; SessionData recoverySessionData = null; SqlConnectionString userOpt = null; if (userOptions != null) { userOpt = (SqlConnectionString)userOptions; } else if (owningConnection != null) { userOpt = (SqlConnectionString)(((SqlConnection)owningConnection).UserConnectionOptions); } if (owningConnection != null) { recoverySessionData = ((SqlConnection)owningConnection)._recoverySessionData; } if (opt.ContextConnection) { result = GetContextConnection(opt, poolGroupProviderInfo); } else { bool redirectedUserInstance = false; DbConnectionPoolIdentity identity = null; // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security. // Used by notifications. if (opt.IntegratedSecurity) { if (pool != null) { identity = pool.Identity; } else { identity = DbConnectionPoolIdentity.GetCurrent(); } } // FOLLOWING IF BLOCK IS ENTIRELY FOR SSE USER INSTANCES // If "user instance=true" is in the connection string, we're using SSE user instances if (opt.UserInstance) { // opt.DataSource is used to create the SSE connection redirectedUserInstance = true; string instanceName; if ((null == pool) || (null != pool && pool.Count <= 0)) // Non-pooled or pooled and no connections in the pool. { SqlInternalConnectionTds sseConnection = null; try { // What about a failure - throw? YES! // SqlConnectionString sseopt = new SqlConnectionString(opt, opt.DataSource, true /* user instance=true */, false /* set Enlist = false */); sseConnection = new SqlInternalConnectionTds(identity, sseopt, key.Credential, null, "", null, false); // NOTE: Retrieve <UserInstanceName> here. This user instance name will be used below to connect to the Sql Express User Instance. instanceName = sseConnection.InstanceName; if (!instanceName.StartsWith("\\\\.\\", StringComparison.Ordinal)) { throw SQL.NonLocalSSEInstance(); } if (null != pool) // Pooled connection - cache result { SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; // No lock since we are already in creation mutex providerInfo.InstanceName = instanceName; } } finally { if (null != sseConnection) { sseConnection.Dispose(); } } } else // Cached info from pool. { SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; // No lock since we are already in creation mutex instanceName = providerInfo.InstanceName; } // NOTE: Here connection option opt is cloned to set 'instanceName=<UserInstanceName>' that was // retrieved from the previous SSE connection. For this UserInstance connection 'Enlist=True'. // options immutable - stored in global hash - don't modify opt = new SqlConnectionString(opt, instanceName, false /* user instance=false */, null /* do not modify the Enlist value */); poolGroupProviderInfo = null; // null so we do not pass to constructor below... } result = new SqlInternalConnectionTds(identity, opt, key.Credential, poolGroupProviderInfo, "", null, redirectedUserInstance, userOpt, recoverySessionData); } return(result); }
override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) { SqlConnectionString opt = (SqlConnectionString)options; SqlConnectionPoolKey key = (SqlConnectionPoolKey)poolKey; SqlInternalConnection result = null; SessionData recoverySessionData = null; SqlConnection sqlOwningConnection = owningConnection as SqlConnection; bool applyTransientFaultHandling = sqlOwningConnection != null ? sqlOwningConnection._applyTransientFaultHandling : false; SqlConnectionString userOpt = null; if (userOptions != null) { userOpt = (SqlConnectionString)userOptions; } else if (sqlOwningConnection != null) { userOpt = (SqlConnectionString)(sqlOwningConnection.UserConnectionOptions); } if (sqlOwningConnection != null) { recoverySessionData = sqlOwningConnection._recoverySessionData; } if (opt.ContextConnection) { result = GetContextConnection(opt, poolGroupProviderInfo); } else { bool redirectedUserInstance = false; DbConnectionPoolIdentity identity = null; // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security. // Used by notifications. if (opt.IntegratedSecurity || opt.UsesCertificate || opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryIntegrated) { if (pool != null) { identity = pool.Identity; } else { identity = DbConnectionPoolIdentity.GetCurrent(); } } // FOLLOWING IF BLOCK IS ENTIRELY FOR SSE USER INSTANCES // If "user instance=true" is in the connection string, we're using SSE user instances if (opt.UserInstance) { // opt.DataSource is used to create the SSE connection redirectedUserInstance = true; string instanceName; if ((null == pool) || (null != pool && pool.Count <= 0)) // Non-pooled or pooled and no connections in the pool. { SqlInternalConnectionTds sseConnection = null; try { // What about a failure - throw? YES! // BUG (VSTFDevDiv) 479687: Using TransactionScope with Linq2SQL against user instances fails with "connection has been broken" message // NOTE: Cloning connection option opt to set 'UserInstance=True' and 'Enlist=False' // This first connection is established to SqlExpress to get the instance name // of the UserInstance. SqlConnectionString sseopt = new SqlConnectionString(opt, opt.DataSource, true /* user instance=true */, false /* set Enlist = false */); sseConnection = new SqlInternalConnectionTds(identity, sseopt, key.Credential, null, "", null, false, applyTransientFaultHandling: applyTransientFaultHandling); // NOTE: Retrieve <UserInstanceName> here. This user instance name will be used below to connect to the Sql Express User Instance. instanceName = sseConnection.InstanceName; if (!instanceName.StartsWith("\\\\.\\", StringComparison.Ordinal)) { throw SQL.NonLocalSSEInstance(); } if (null != pool) // Pooled connection - cache result { SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; // No lock since we are already in creation mutex providerInfo.InstanceName = instanceName; } } finally { if (null != sseConnection) { sseConnection.Dispose(); } } } else // Cached info from pool. { SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; // No lock since we are already in creation mutex instanceName = providerInfo.InstanceName; } // NOTE: Here connection option opt is cloned to set 'instanceName=<UserInstanceName>' that was // retrieved from the previous SSE connection. For this UserInstance connection 'Enlist=True'. // options immutable - stored in global hash - don't modify opt = new SqlConnectionString(opt, instanceName, false /* user instance=false */, null /* do not modify the Enlist value */); poolGroupProviderInfo = null; // null so we do not pass to constructor below... } result = new SqlInternalConnectionTds(identity, opt, key.Credential, poolGroupProviderInfo, "", null, redirectedUserInstance, userOpt, recoverySessionData, key.ServerCertificateValidationCallback, key.ClientCertificateRetrievalCallback, pool, key.AccessToken, key.OriginalNetworkAddressInfo, applyTransientFaultHandling: applyTransientFaultHandling); } return(result); }
internal static bool Stop(string connectionString, string queue, bool useDefaults, bool startFailed) { if (string.IsNullOrEmpty(connectionString)) { if (null == connectionString) { throw ADP.ArgumentNull(nameof(connectionString)); } else { throw ADP.Argument(nameof(connectionString)); } } if (!useDefaults && string.IsNullOrEmpty(queue)) { // If specified but null or empty, use defaults. useDefaults = true; queue = null; // Force to null - for proper hashtable comparison for default case. } // End duplicate Start/Stop logic. bool result = false; lock (s_startStopLock) { if (null != s_processDispatcher) { // If _processDispatcher null, no Start has been called. try { string server = null; DbConnectionPoolIdentity identity = null; string user = null; string database = null; string service = null; if (useDefaults) { bool appDomainStop = false; RuntimeHelpers.PrepareConstrainedRegions(); try { // CER to ensure that if Stop succeeds we remove from hash completing teardown. // Start using process wide default service/queue & database from connection string. result = s_processDispatcher.Stop( connectionString, out server, out identity, out user, out database, ref service, s_appDomainKey, out appDomainStop); } finally { if (appDomainStop && !startFailed) { // If success, remove from hashtable. Debug.Assert(!string.IsNullOrEmpty(server) && !string.IsNullOrEmpty(database), "Server or Database null/Empty upon successfull Stop()!"); IdentityUserNamePair identityUser = new IdentityUserNamePair(identity, user); DatabaseServicePair databaseService = new DatabaseServicePair(database, service); RemoveFromServerUserHash(server, identityUser, databaseService); } } } else { result = s_processDispatcher.Stop( connectionString, out server, out identity, out user, out database, ref queue, s_appDomainKey, out bool ignored); // No need to call RemoveFromServerDatabaseHash since if not using default queue user is required // to provide options themselves. } } catch (Exception e) { if (!ADP.IsCatchableExceptionType(e)) { throw; } ADP.TraceExceptionWithoutRethrow(e); // Discard failure, but trace for now. } } } return(result); }
internal static bool Start(string connectionString, string queue, bool useDefaults) { if (string.IsNullOrEmpty(connectionString)) { if (null == connectionString) { throw ADP.ArgumentNull(nameof(connectionString)); } else { throw ADP.Argument(nameof(connectionString)); } } if (!useDefaults && string.IsNullOrEmpty(queue)) { // If specified but null or empty, use defaults. useDefaults = true; queue = null; // Force to null - for proper hashtable comparison for default case. } // End duplicate Start/Stop logic. bool errorOccurred = false; bool result = false; lock (s_startStopLock) { try { if (null == s_processDispatcher) { // Ensure _processDispatcher reference is present - inside lock. s_processDispatcher = SqlDependencyProcessDispatcher.SingletonProcessDispatcher; } if (useDefaults) { // Default listener. string server = null; DbConnectionPoolIdentity identity = null; string user = null; string database = null; string service = null; bool appDomainStart = false; RuntimeHelpers.PrepareConstrainedRegions(); try { // CER to ensure that if Start succeeds we add to hash completing setup. // Start using process wide default service/queue & database from connection string. result = s_processDispatcher.StartWithDefault( connectionString, out server, out identity, out user, out database, ref service, s_appDomainKey, SqlDependencyPerAppDomainDispatcher.SingletonInstance, out errorOccurred, out appDomainStart); } finally { if (appDomainStart && !errorOccurred) { // If success, add to hashtable. IdentityUserNamePair identityUser = new IdentityUserNamePair(identity, user); DatabaseServicePair databaseService = new DatabaseServicePair(database, service); if (!AddToServerUserHash(server, identityUser, databaseService)) { try { Stop(connectionString, queue, useDefaults, true); } catch (Exception e) { // Discard stop failure! if (!ADP.IsCatchableExceptionType(e)) { throw; } ADP.TraceExceptionWithoutRethrow(e); // Discard failure, but trace for now. } throw SQL.SqlDependencyDuplicateStart(); } } } } else { // Start with specified service/queue & database. result = s_processDispatcher.Start( connectionString, queue, s_appDomainKey, SqlDependencyPerAppDomainDispatcher.SingletonInstance); // No need to call AddToServerDatabaseHash since if not using default queue user is required // to provide options themselves. } } catch (Exception e) { if (!ADP.IsCatchableExceptionType(e)) { throw; } ADP.TraceExceptionWithoutRethrow(e); // Discard failure, but trace for now. throw; } } return(result); }
internal static bool Stop(string connectionString, string queue, bool useDefaults, bool startFailed) { bool flag2; IntPtr ptr; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependency.Stop|DEP> AppDomainKey: '%ls', queue: '%ls'", AppDomainKey, queue); try { if (InOutOfProcHelper.InProc) { throw SQL.SqlDepCannotBeCreatedInProc(); } if (ADP.IsEmpty(connectionString)) { if (connectionString == null) { throw ADP.ArgumentNull("connectionString"); } throw ADP.Argument("connectionString"); } if (!useDefaults && ADP.IsEmpty(queue)) { useDefaults = true; queue = null; } new SqlConnectionString(connectionString).DemandPermission(); bool flag = false; lock (_startStopLock) { if (_processDispatcher != null) { try { string server = null; DbConnectionPoolIdentity identity = null; string user = null; string database = null; string queueService = null; if (useDefaults) { bool flag3 = false; RuntimeHelpers.PrepareConstrainedRegions(); try { flag = _processDispatcher.Stop(connectionString, out server, out identity, out user, out database, ref queueService, _appDomainKey, out flag3); goto Label_0121; } finally { if (flag3 && !startFailed) { IdentityUserNamePair identityUser = new IdentityUserNamePair(identity, user); DatabaseServicePair databaseService = new DatabaseServicePair(database, queueService); RemoveFromServerUserHash(server, identityUser, databaseService); } } } bool appDomainStop = false; flag = _processDispatcher.Stop(connectionString, out server, out identity, out user, out database, ref queue, _appDomainKey, out appDomainStop); } catch (Exception exception) { if (!ADP.IsCatchableExceptionType(exception)) { throw; } ADP.TraceExceptionWithoutRethrow(exception); } } Label_0121 :; } flag2 = flag; } finally { Bid.ScopeLeave(ref ptr); } return(flag2); }
internal static bool Start(string connectionString, string queue, bool useDefaults) { bool flag2; IntPtr ptr; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependency.Start|DEP> AppDomainKey: '%ls', queue: '%ls'", AppDomainKey, queue); try { if (InOutOfProcHelper.InProc) { throw SQL.SqlDepCannotBeCreatedInProc(); } if (ADP.IsEmpty(connectionString)) { if (connectionString == null) { throw ADP.ArgumentNull("connectionString"); } throw ADP.Argument("connectionString"); } if (!useDefaults && ADP.IsEmpty(queue)) { useDefaults = true; queue = null; } new SqlConnectionString(connectionString).DemandPermission(); bool errorOccurred = false; bool flag = false; lock (_startStopLock) { try { if (_processDispatcher == null) { ObtainProcessDispatcher(); } if (useDefaults) { string server = null; DbConnectionPoolIdentity identity = null; string user = null; string database = null; string service = null; bool appDomainStart = false; RuntimeHelpers.PrepareConstrainedRegions(); try { flag = _processDispatcher.StartWithDefault(connectionString, out server, out identity, out user, out database, ref service, _appDomainKey, SqlDependencyPerAppDomainDispatcher.SingletonInstance, out errorOccurred, out appDomainStart); Bid.NotificationsTrace("<sc.SqlDependency.Start|DEP> Start (defaults) returned: '%d', with service: '%ls', server: '%ls', database: '%ls'\n", flag, service, server, database); goto Label_0183; } finally { if (appDomainStart && !errorOccurred) { IdentityUserNamePair identityUser = new IdentityUserNamePair(identity, user); DatabaseServicePair databaseService = new DatabaseServicePair(database, service); if (!AddToServerUserHash(server, identityUser, databaseService)) { try { Stop(connectionString, queue, useDefaults, true); } catch (Exception exception2) { if (!ADP.IsCatchableExceptionType(exception2)) { throw; } ADP.TraceExceptionWithoutRethrow(exception2); Bid.NotificationsTrace("<sc.SqlDependency.Start|DEP|ERR> Exception occurred from Stop() after duplicate was found on Start().\n"); } throw SQL.SqlDependencyDuplicateStart(); } } } } flag = _processDispatcher.Start(connectionString, queue, _appDomainKey, SqlDependencyPerAppDomainDispatcher.SingletonInstance); Bid.NotificationsTrace("<sc.SqlDependency.Start|DEP> Start (user provided queue) returned: '%d'\n", flag); } catch (Exception exception) { if (!ADP.IsCatchableExceptionType(exception)) { throw; } ADP.TraceExceptionWithoutRethrow(exception); Bid.NotificationsTrace("<sc.SqlDependency.Start|DEP|ERR> Exception occurred from _processDispatcher.Start(...), calling Invalidate(...).\n"); throw; } Label_0183 :; } flag2 = flag; } finally { Bid.ScopeLeave(ref ptr); } return(flag2); }
internal IdentityUserNamePair(DbConnectionPoolIdentity identity, string userName) { this._identity = identity; this._userName = userName; }