/// <summary> /// release resources. /// </summary> /// <param name="dispose">a value indicating whether release the resources.</param> protected virtual void Dispose(bool dispose) { if (dispose) { if (this.brokerNodeTimer != null) { this.brokerNodeTimer.Dispose(); this.brokerNodeTimer = null; } if (this.schedulerField != null) { this.schedulerField.Close(); this.schedulerField.Dispose(); this.schedulerField = null; } if (this.failoverClusterConnections != null) { lock (this.failoverClusterConnections) { foreach (KeyValuePair <string, IntPtr> connection in this.failoverClusterConnections) { try { Win32API.CloseCluster(connection.Value); } catch (Exception ex) { TraceHelper.TraceEvent(TraceEventType.Warning, "[BrokerNodesManager].Dispose: Exception {0}", ex); } // Shutting down so just swallow exceptions } } this.failoverClusterConnections = null; } } }
/// <summary> /// Get broker's identity. If on a failover cluster, get resoruce group network name /// computer account login token /// Notice: This method returns null if it is not failover cluster or it is Azure cluster. /// </summary> /// <returns></returns> private static WindowsIdentity GetBrokerIdentity() { if (SoaHelper.IsOnAzure()) { // Skip following logic if it is on Azure. return(null); } int clusterState = (int)ClusterState.ClusterStateNotInstalled; uint ret = Win32API.GetNodeClusterState(null, out clusterState); if (ret != 0) { TraceHelper.TraceEvent(TraceEventType.Error, "Cannot access local failover cluster state. Error = {0}", ret); return(null); } if (clusterState == (int)ClusterState.ClusterStateNotConfigured || clusterState == (int)ClusterState.ClusterStateNotInstalled) { TraceHelper.TraceEvent(TraceEventType.Information, "Cannot access local failover cluster state. Error = {0}", ret); return(null); } IntPtr hCluster = IntPtr.Zero; IntPtr hResource = IntPtr.Zero; try { // Get handle to local failover cluster hCluster = Win32API.OpenCluster(null); if (hCluster == IntPtr.Zero) { TraceHelper.TraceEvent(TraceEventType.Error, "Cannot connect to local failover cluster. Error = {0}", Marshal.GetLastWin32Error()); return(null); } // Get handle to this broker's network name resource hResource = Win32API.OpenClusterResource(hCluster, Environment.MachineName); if (hResource == IntPtr.Zero) { TraceHelper.TraceEvent(TraceEventType.Error, "Cannot connect to local failover cluster. Error = {0}", Marshal.GetLastWin32Error()); return(null); } // Get the login token of the network name for the broker's resource group's network name. This // is a computer account login token and is use to impersonate all calls to the services. The services // then ensure calls are only from broker nodes or resource groups. IntPtr loginToken = IntPtr.Zero; try { loginToken = GetNetworkNameLoginToken(hCluster, hResource); if (loginToken != IntPtr.Zero) { // Put login token in a WindowsIdentity object // WindowsIdentity calls DuplicateToken and it is fine to close the handle later return(new WindowsIdentity(loginToken)); } else { return(null); } } finally { if (loginToken != IntPtr.Zero) { Win32API.CloseHandle(loginToken); } } } finally { if (hResource != IntPtr.Zero) { Win32API.CloseClusterResource(hResource); } if (hCluster != IntPtr.Zero) { Win32API.CloseCluster(hCluster); } } }