public override bool Equals(object value) { IdentityUserNamePair temp = (IdentityUserNamePair)value; bool result = false; if (null == temp) { // If passed value null - false. result = false; } else if (this == temp) { // If instances equal - true. result = true; } else { if (_identity != null) { if (_identity.Equals(temp._identity)) { result = true; } } else if (_userName == temp._userName) { result = true; } } return(result); }
private static void RemoveFromServerUserHash(string server, IdentityUserNamePair identityUser, DatabaseServicePair databaseService) { IntPtr ptr; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependency.RemoveFromServerUserHash|DEP> server: '%ls', database: '%ls', service: '%ls'", server, databaseService.Database, databaseService.Service); try { lock (_serverUserHash) { if (_serverUserHash.ContainsKey(server)) { Dictionary <IdentityUserNamePair, List <DatabaseServicePair> > dictionary = _serverUserHash[server]; if (dictionary.ContainsKey(identityUser)) { List <DatabaseServicePair> list = dictionary[identityUser]; int index = list.IndexOf(databaseService); if (index >= 0) { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP> Hash contained server, user, and database - removing database.\n"); list.RemoveAt(index); if (list.Count == 0) { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP> databaseServiceList count 0, removing the list for this server and user.\n"); dictionary.Remove(identityUser); if (dictionary.Count == 0) { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP> identityDatabaseHash count 0, removing the hash for this server.\n"); _serverUserHash.Remove(server); } } } else { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP|ERR> ERROR - hash contained server and user but not database!\n"); } } else { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP|ERR> ERROR - hash contained server but not user!\n"); } } else { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP|ERR> ERROR - hash did not contain server!\n"); } } } finally { Bid.ScopeLeave(ref ptr); } }
private static bool AddToServerUserHash(string server, IdentityUserNamePair identityUser, DatabaseServicePair databaseService) { bool flag2; IntPtr ptr; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependency.AddToServerUserHash|DEP> server: '%ls', database: '%ls', service: '%ls'", server, databaseService.Database, databaseService.Service); try { bool flag = false; lock (_serverUserHash) { Dictionary <IdentityUserNamePair, List <DatabaseServicePair> > dictionary; List <DatabaseServicePair> list; if (!_serverUserHash.ContainsKey(server)) { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP> Hash did not contain server, adding.\n"); dictionary = new Dictionary <IdentityUserNamePair, List <DatabaseServicePair> >(); _serverUserHash.Add(server, dictionary); } else { dictionary = _serverUserHash[server]; } if (!dictionary.ContainsKey(identityUser)) { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP> Hash contained server but not user, adding user.\n"); list = new List <DatabaseServicePair>(); dictionary.Add(identityUser, list); } else { list = dictionary[identityUser]; } if (!list.Contains(databaseService)) { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP> Adding database.\n"); list.Add(databaseService); flag = true; } else { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP|ERR> ERROR - hash already contained server, user, and database - we will throw!.\n"); } } flag2 = flag; } finally { Bid.ScopeLeave(ref ptr); } return(flag2); }
private static void RemoveFromServerUserHash(string server, IdentityUserNamePair identityUser, DatabaseServicePair databaseService) { lock (s_serverUserHash) { Dictionary <IdentityUserNamePair, List <DatabaseServicePair> > identityDatabaseHash; if (s_serverUserHash.ContainsKey(server)) { identityDatabaseHash = s_serverUserHash[server]; List <DatabaseServicePair> databaseServiceList; if (identityDatabaseHash.ContainsKey(identityUser)) { databaseServiceList = identityDatabaseHash[identityUser]; int index = databaseServiceList.IndexOf(databaseService); if (index >= 0) { databaseServiceList.RemoveAt(index); if (databaseServiceList.Count == 0) { identityDatabaseHash.Remove(identityUser); if (identityDatabaseHash.Count == 0) { s_serverUserHash.Remove(server); } } } else { Debug.Fail("Unexpected state - hash did not contain database!"); } } else { Debug.Fail("Unexpected state - hash did not contain user!"); } } else { Debug.Fail("Unexpected state - hash did not contain server!"); } } }
// General static utility functions private static bool AddToServerUserHash(string server, IdentityUserNamePair identityUser, DatabaseServicePair databaseService) { bool result = false; lock (s_serverUserHash) { Dictionary <IdentityUserNamePair, List <DatabaseServicePair> > identityDatabaseHash; if (!s_serverUserHash.ContainsKey(server)) { identityDatabaseHash = new Dictionary <IdentityUserNamePair, List <DatabaseServicePair> >(); s_serverUserHash.Add(server, identityDatabaseHash); } else { identityDatabaseHash = s_serverUserHash[server]; } List <DatabaseServicePair> databaseServiceList; if (!identityDatabaseHash.ContainsKey(identityUser)) { databaseServiceList = new List <DatabaseServicePair>(); identityDatabaseHash.Add(identityUser, databaseServiceList); } else { databaseServiceList = identityDatabaseHash[identityUser]; } if (!databaseServiceList.Contains(databaseService)) { databaseServiceList.Add(databaseService); result = true; } } return(result); }
private static void RemoveFromServerUserHash(string server, IdentityUserNamePair identityUser, DatabaseServicePair databaseService) { IntPtr ptr; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependency.RemoveFromServerUserHash|DEP> server: '%ls', database: '%ls', service: '%ls'", server, databaseService.Database, databaseService.Service); try { lock (_serverUserHash) { if (_serverUserHash.ContainsKey(server)) { Dictionary<IdentityUserNamePair, List<DatabaseServicePair>> dictionary = _serverUserHash[server]; if (dictionary.ContainsKey(identityUser)) { List<DatabaseServicePair> list = dictionary[identityUser]; int index = list.IndexOf(databaseService); if (index >= 0) { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP> Hash contained server, user, and database - removing database.\n"); list.RemoveAt(index); if (list.Count == 0) { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP> databaseServiceList count 0, removing the list for this server and user.\n"); dictionary.Remove(identityUser); if (dictionary.Count == 0) { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP> identityDatabaseHash count 0, removing the hash for this server.\n"); _serverUserHash.Remove(server); } } } else { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP|ERR> ERROR - hash contained server and user but not database!\n"); } } else { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP|ERR> ERROR - hash contained server but not user!\n"); } } else { Bid.NotificationsTrace("<sc.SqlDependency.RemoveFromServerUserHash|DEP|ERR> ERROR - hash did not contain server!\n"); } } } finally { Bid.ScopeLeave(ref ptr); } }
internal static string GetDefaultComposedOptions(string server, string failoverServer, IdentityUserNamePair identityUser, string database) { string str2; IntPtr ptr; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependency.GetDefaultComposedOptions|DEP> server: '%ls', failoverServer: '%ls', database: '%ls'", server, failoverServer, database); try { string str; lock (_serverUserHash) { if (!_serverUserHash.ContainsKey(server)) { if (_serverUserHash.Count == 0) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - no start calls have been made, about to throw.\n"); throw SQL.SqlDepDefaultOptionsButNoStart(); } if (ADP.IsEmpty(failoverServer) || !_serverUserHash.ContainsKey(failoverServer)) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - not listening to this server, about to throw.\n"); throw SQL.SqlDependencyNoMatchingServerStart(); } Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP> using failover server instead\n"); server = failoverServer; } Dictionary<IdentityUserNamePair, List<DatabaseServicePair>> dictionary = _serverUserHash[server]; List<DatabaseServicePair> list = null; if (!dictionary.ContainsKey(identityUser)) { if (dictionary.Count > 1) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - not listening for this user, but listening to more than one other user, about to throw.\n"); throw SQL.SqlDependencyNoMatchingServerStart(); } foreach (KeyValuePair<IdentityUserNamePair, List<DatabaseServicePair>> pair3 in dictionary) { list = pair3.Value; break; } } else { list = dictionary[identityUser]; } DatabaseServicePair item = new DatabaseServicePair(database, null); DatabaseServicePair pair = null; int index = list.IndexOf(item); if (index != -1) { pair = list[index]; } if (pair == null) { if (list.Count != 1) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - SqlDependency.Start called multiple times for this server/user, but no matching database.\n"); throw SQL.SqlDependencyNoMatchingServerDatabaseStart(); } pair = list.ToArray()[0]; string str4 = FixupServiceOrDatabaseName(pair.Database); string str3 = FixupServiceOrDatabaseName(pair.Service); str = "Service=" + str3 + ";Local Database=" + str4; } else { database = FixupServiceOrDatabaseName(pair.Database); string str5 = FixupServiceOrDatabaseName(pair.Service); str = "Service=" + str5 + ";Local Database=" + database; } } Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP> resulting options: '%ls'.\n", str); str2 = str; } finally { Bid.ScopeLeave(ref ptr); } return str2; }
private static bool AddToServerUserHash(string server, IdentityUserNamePair identityUser, DatabaseServicePair databaseService) { bool flag2; IntPtr ptr; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependency.AddToServerUserHash|DEP> server: '%ls', database: '%ls', service: '%ls'", server, databaseService.Database, databaseService.Service); try { bool flag = false; lock (_serverUserHash) { Dictionary<IdentityUserNamePair, List<DatabaseServicePair>> dictionary; List<DatabaseServicePair> list; if (!_serverUserHash.ContainsKey(server)) { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP> Hash did not contain server, adding.\n"); dictionary = new Dictionary<IdentityUserNamePair, List<DatabaseServicePair>>(); _serverUserHash.Add(server, dictionary); } else { dictionary = _serverUserHash[server]; } if (!dictionary.ContainsKey(identityUser)) { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP> Hash contained server but not user, adding user.\n"); list = new List<DatabaseServicePair>(); dictionary.Add(identityUser, list); } else { list = dictionary[identityUser]; } if (!list.Contains(databaseService)) { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP> Adding database.\n"); list.Add(databaseService); flag = true; } else { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP|ERR> ERROR - hash already contained server, user, and database - we will throw!.\n"); } } flag2 = flag; } finally { Bid.ScopeLeave(ref ptr); } return flag2; }
internal static string GetDefaultComposedOptions(string server, string failoverServer, IdentityUserNamePair identityUser, string database) { // Server must be an exact match, but user and database only needs to match exactly if there is more than one // for the given user or database passed. That is ambiguious and we must fail. string result; lock (s_serverUserHash) { if (!s_serverUserHash.ContainsKey(server)) { if (0 == s_serverUserHash.Count) { // Special error for no calls to start. throw SQL.SqlDepDefaultOptionsButNoStart(); } else if (!string.IsNullOrEmpty(failoverServer) && s_serverUserHash.ContainsKey(failoverServer)) { server = failoverServer; } else { throw SQL.SqlDependencyNoMatchingServerStart(); } } Dictionary <IdentityUserNamePair, List <DatabaseServicePair> > identityDatabaseHash = s_serverUserHash[server]; List <DatabaseServicePair> databaseList = null; if (!identityDatabaseHash.ContainsKey(identityUser)) { if (identityDatabaseHash.Count > 1) { throw SQL.SqlDependencyNoMatchingServerStart(); } else { // Since only one user, - use that. // Foreach - but only one value present. foreach (KeyValuePair <IdentityUserNamePair, List <DatabaseServicePair> > entry in identityDatabaseHash) { databaseList = entry.Value; break; // Only iterate once. } } } else { databaseList = identityDatabaseHash[identityUser]; } DatabaseServicePair pair = new DatabaseServicePair(database, null); DatabaseServicePair resultingPair = null; int index = databaseList.IndexOf(pair); if (index != -1) { // Exact match found, use it. resultingPair = databaseList[index]; } if (null != resultingPair) { // Exact database match. database = FixupServiceOrDatabaseName(resultingPair.Database); // Fixup in place. string quotedService = FixupServiceOrDatabaseName(resultingPair.Service); result = "Service=" + quotedService + ";Local Database=" + database; } else { // No exact database match found. if (databaseList.Count == 1) { // If only one database for this server/user, use it. object[] temp = databaseList.ToArray(); // Must copy, no other choice but foreach. resultingPair = (DatabaseServicePair)temp[0]; Debug.Assert(temp.Length == 1, "If databaseList.Count==1, why does copied array have length other than 1?"); string quotedDatabase = FixupServiceOrDatabaseName(resultingPair.Database); string quotedService = FixupServiceOrDatabaseName(resultingPair.Service); result = "Service=" + quotedService + ";Local Database=" + quotedDatabase; } else { // More than one database for given server, ambiguous - fail the default case! throw SQL.SqlDependencyNoMatchingServerDatabaseStart(); } } } Debug.Assert(!string.IsNullOrEmpty(result), "GetDefaultComposedOptions should never return null or empty string!"); return(result); }
internal static string GetDefaultComposedOptions(string server, string failoverServer, IdentityUserNamePair identityUser, string database) { string str2; IntPtr ptr; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependency.GetDefaultComposedOptions|DEP> server: '%ls', failoverServer: '%ls', database: '%ls'", server, failoverServer, database); try { string str; lock (_serverUserHash) { if (!_serverUserHash.ContainsKey(server)) { if (_serverUserHash.Count == 0) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - no start calls have been made, about to throw.\n"); throw SQL.SqlDepDefaultOptionsButNoStart(); } if (ADP.IsEmpty(failoverServer) || !_serverUserHash.ContainsKey(failoverServer)) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - not listening to this server, about to throw.\n"); throw SQL.SqlDependencyNoMatchingServerStart(); } Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP> using failover server instead\n"); server = failoverServer; } Dictionary <IdentityUserNamePair, List <DatabaseServicePair> > dictionary = _serverUserHash[server]; List <DatabaseServicePair> list = null; if (!dictionary.ContainsKey(identityUser)) { if (dictionary.Count > 1) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - not listening for this user, but listening to more than one other user, about to throw.\n"); throw SQL.SqlDependencyNoMatchingServerStart(); } foreach (KeyValuePair <IdentityUserNamePair, List <DatabaseServicePair> > pair3 in dictionary) { list = pair3.Value; break; } } else { list = dictionary[identityUser]; } DatabaseServicePair item = new DatabaseServicePair(database, null); DatabaseServicePair pair = null; int index = list.IndexOf(item); if (index != -1) { pair = list[index]; } if (pair == null) { if (list.Count != 1) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - SqlDependency.Start called multiple times for this server/user, but no matching database.\n"); throw SQL.SqlDependencyNoMatchingServerDatabaseStart(); } pair = list.ToArray()[0]; string str4 = FixupServiceOrDatabaseName(pair.Database); string str3 = FixupServiceOrDatabaseName(pair.Service); str = "Service=" + str3 + ";Local Database=" + str4; } else { database = FixupServiceOrDatabaseName(pair.Database); string str5 = FixupServiceOrDatabaseName(pair.Service); str = "Service=" + str5 + ";Local Database=" + database; } } Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP> resulting options: '%ls'.\n", str); str2 = str; } finally { Bid.ScopeLeave(ref ptr); } return(str2); }
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 string GetDefaultComposedOptions(string server, string failoverServer, IdentityUserNamePair identityUser, string database) { // Server must be an exact match, but user and database only needs to match exactly if there is more than one // for the given user or database passed. That is ambiguious and we must fail. IntPtr hscp; Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependency.GetDefaultComposedOptions|DEP> server: '%ls', failoverServer: '%ls', database: '%ls'", server, failoverServer, database); try { string result; lock (_serverUserHash) { if (!_serverUserHash.ContainsKey(server)) { if (0 == _serverUserHash.Count) { // Special error for no calls to start. Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - no start calls have been made, about to throw.\n"); throw SQL.SqlDepDefaultOptionsButNoStart(); } else if (!ADP.IsEmpty(failoverServer) && _serverUserHash.ContainsKey(failoverServer)) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP> using failover server instead\n"); server = failoverServer; } else { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - not listening to this server, about to throw.\n"); throw SQL.SqlDependencyNoMatchingServerStart(); } } Dictionary<IdentityUserNamePair, List<DatabaseServicePair>> identityDatabaseHash = _serverUserHash[server]; List<DatabaseServicePair> databaseList = null; if (!identityDatabaseHash.ContainsKey(identityUser)) { if (identityDatabaseHash.Count > 1) { Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - not listening for this user, but listening to more than one other user, about to throw.\n"); throw SQL.SqlDependencyNoMatchingServerStart(); } else { // Since only one user, - use that. // Foreach - but only one value present. foreach (KeyValuePair<IdentityUserNamePair, List<DatabaseServicePair>> entry in identityDatabaseHash) { databaseList = entry.Value; break; // Only iterate once. } } } else { databaseList = identityDatabaseHash[identityUser]; } DatabaseServicePair pair = new DatabaseServicePair(database, null); DatabaseServicePair resultingPair = null; int index = databaseList.IndexOf(pair); if (index != -1) { // Exact match found, use it. resultingPair = databaseList[index]; } if (null != resultingPair) { // Exact database match. database = FixupServiceOrDatabaseName(resultingPair.Database); // Fixup in place. string quotedService = FixupServiceOrDatabaseName(resultingPair.Service); result = "Service="+quotedService+";Local Database="+database; } else { // No exact database match found. if (databaseList.Count == 1) { // If only one database for this server/user, use it. object[] temp = databaseList.ToArray(); // Must copy, no other choice but foreach. resultingPair = (DatabaseServicePair) temp[0]; Debug.Assert(temp.Length == 1, "If databaseList.Count==1, why does copied array have length other than 1?"); string quotedDatabase = FixupServiceOrDatabaseName(resultingPair.Database); string quotedService = FixupServiceOrDatabaseName(resultingPair.Service); result = "Service="+quotedService+";Local Database="+quotedDatabase; } else { // More than one database for given server, ambiguous - fail the default case! Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP|ERR> ERROR - SqlDependency.Start called multiple times for this server/user, but no matching database.\n"); throw SQL.SqlDependencyNoMatchingServerDatabaseStart(); } } } Debug.Assert(!ADP.IsEmpty(result), "GetDefaultComposedOptions should never return null or empty string!"); Bid.NotificationsTrace("<sc.SqlDependency.GetDefaultComposedOptions|DEP> resulting options: '%ls'.\n", result); return result; } finally { Bid.ScopeLeave(ref hscp); } }
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); }
// -------------------------------- // General static utility functions // -------------------------------- private static bool AddToServerUserHash(string server, IdentityUserNamePair identityUser, DatabaseServicePair databaseService) { IntPtr hscp; Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependency.AddToServerUserHash|DEP> server: '%ls', database: '%ls', service: '%ls'", server, databaseService.Database, databaseService.Service); try { bool result = false; lock (_serverUserHash) { Dictionary<IdentityUserNamePair, List<DatabaseServicePair>> identityDatabaseHash; if (!_serverUserHash.ContainsKey(server)) { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP> Hash did not contain server, adding.\n"); identityDatabaseHash = new Dictionary<IdentityUserNamePair, List<DatabaseServicePair>>(); _serverUserHash.Add(server, identityDatabaseHash); } else { identityDatabaseHash = _serverUserHash[server]; } List<DatabaseServicePair> databaseServiceList; if (!identityDatabaseHash.ContainsKey(identityUser)) { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP> Hash contained server but not user, adding user.\n"); databaseServiceList = new List<DatabaseServicePair>(); identityDatabaseHash.Add(identityUser, databaseServiceList); } else { databaseServiceList = identityDatabaseHash[identityUser]; } if (!databaseServiceList.Contains(databaseService)) { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP> Adding database.\n"); databaseServiceList.Add(databaseService); result = true; } else { Bid.NotificationsTrace("<sc.SqlDependency.AddToServerUserHash|DEP|ERR> ERROR - hash already contained server, user, and database - we will throw!.\n"); } } return result; } finally { Bid.ScopeLeave(ref hscp); } }
internal static bool Stop(string connectionString, string queue, bool useDefaults, bool startFailed) { IntPtr hscp; Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependency.Stop|DEP> AppDomainKey: '%ls', queue: '%ls'", AppDomainKey, queue); try { // The following code exists in Stop as well. It exists here to demand permissions as high in the stack // as possible. if (InOutOfProcHelper.InProc) { throw SQL.SqlDepCannotBeCreatedInProc(); } if (ADP.IsEmpty(connectionString)) { if (null == connectionString) { throw ADP.ArgumentNull("connectionString"); } else { throw ADP.Argument("connectionString"); } } if (!useDefaults && ADP.IsEmpty(queue)) { // If specified but null or empty, use defaults. useDefaults = true; queue = null; // Force to null - for proper hashtable comparison for default case. } // Create new connection options for demand on their connection string. We modify the connection string // and assert on our modified string when we create the container. SqlConnectionString connectionStringObject = new SqlConnectionString(connectionString); connectionStringObject.DemandPermission(); if (connectionStringObject.LocalDBInstance!=null) { LocalDBAPI.DemandLocalDBPermissions(); } // End duplicate Start/Stop logic. bool result = false; lock (_startStopLock) { if (null != _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 = _processDispatcher.Stop( connectionString, out server, out identity, out user, out database, ref service, _appDomainKey, out appDomainStop); } finally { if (appDomainStop && !startFailed) { // If success, remove from hashtable. Debug.Assert(!ADP.IsEmpty(server) && !ADP.IsEmpty(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 { bool ignored = false; result = _processDispatcher.Stop( connectionString, out server, out identity, out user, out database, ref queue, _appDomainKey, out 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; } finally { Bid.ScopeLeave(ref hscp); } }
internal static bool Start(string connectionString, string queue, bool useDefaults) { IntPtr hscp; Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependency.Start|DEP> AppDomainKey: '%ls', queue: '%ls'", AppDomainKey, queue); try { // The following code exists in Stop as well. It exists here to demand permissions as high in the stack // as possible. if (InOutOfProcHelper.InProc) { throw SQL.SqlDepCannotBeCreatedInProc(); } if (ADP.IsEmpty(connectionString)) { if (null == connectionString) { throw ADP.ArgumentNull("connectionString"); } else { throw ADP.Argument("connectionString"); } } if (!useDefaults && ADP.IsEmpty(queue)) { // If specified but null or empty, use defaults. useDefaults = true; queue = null; // Force to null - for proper hashtable comparison for default case. } // Create new connection options for demand on their connection string. We modify the connection string // and assert on our modified string when we create the container. SqlConnectionString connectionStringObject = new SqlConnectionString(connectionString); connectionStringObject.DemandPermission(); if (connectionStringObject.LocalDBInstance!=null) { LocalDBAPI.DemandLocalDBPermissions(); } // End duplicate Start/Stop logic. bool errorOccurred = false; bool result = false; lock (_startStopLock) { try { if (null == _processDispatcher) { // Ensure _processDispatcher reference is present - inside lock. ObtainProcessDispatcher(); } 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 = _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", result, service, server, database); } 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. Bid.NotificationsTrace("<sc.SqlDependency.Start|DEP|ERR> Exception occurred from Stop() after duplicate was found on Start().\n"); } throw SQL.SqlDependencyDuplicateStart(); } } } } else { // Start with specified service/queue & database. result = _processDispatcher.Start(connectionString, queue, _appDomainKey, SqlDependencyPerAppDomainDispatcher.SingletonInstance); Bid.NotificationsTrace("<sc.SqlDependency.Start|DEP> Start (user provided queue) returned: '%d'\n", result); // 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. Bid.NotificationsTrace("<sc.SqlDependency.Start|DEP|ERR> Exception occurred from _processDispatcher.Start(...), calling Invalidate(...).\n"); throw; } } return result; } finally { Bid.ScopeLeave(ref hscp); } }
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 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 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); }