Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Tools / comsvcutil / EndpointConfigContainer.cs / 1305376 / EndpointConfigContainer.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace Microsoft.Tools.ServiceModel.ComSvcConfig { using System; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.Diagnostics; using System.Configuration; using System.Collections; using System.Collections.Specialized; using System.Collections.Generic; using System.IO; using System.Globalization; using System.Text; using System.Threading; using System.Reflection; using System.Runtime.InteropServices; using System.Security; using System.ServiceModel; using System.ServiceModel.Configuration; using Microsoft.Tools.ServiceModel; using System.Xml; class EndpointConfig { Guid appid; Guid clsid; Guid iid; string bindingType; string bindingName; Uri address; bool isMexEndpoint; Listmethods; EndpointConfigContainer container; public static readonly string TempURI = "http://tempuri.org/"; public static readonly string MexEndpointSuffix = "mex"; public Guid Appid { get { return this.appid; } set { this.appid = value; } } public Guid Clsid { get { return this.clsid; } } public Guid Iid { get { return this.iid; } } public string BindingType { get { return this.bindingType; } } public string BindingName { get { return this.bindingName; } } public Uri Address { get { return this.address; } } public bool IsMexEndpoint { get { return isMexEndpoint; } } public EndpointConfigContainer Container { get { return container; } set { container = value; } } public IList Methods { get { return methods; } set { methods = (List )value ; } } public string ContractType { get { if (isMexEndpoint) return ServiceMetadataBehavior.MexContractName; else return iid.ToString("B").ToUpperInvariant (); } } public bool MatchServiceType (string serviceType) { string[] serviceParams = serviceType.Split(','); if (serviceParams.Length != 2) { return false; } try { Guid guid = new Guid(serviceParams[0]); if (guid != Appid) return false; guid = new Guid(serviceParams[1]); if (guid != Clsid) return false; return true; } catch (FormatException) { } return false; } public bool MatchContract (string contract) { if (isMexEndpoint) { if (ContractType == contract) return true; else return false; } else { try { Guid guid = new Guid (contract); if (guid == Iid) return true; } catch (FormatException) { } return false; } } public string ServiceType { get { return Appid.ToString("B").ToUpperInvariant() + "," + Clsid.ToString("B").ToUpperInvariant(); } } public string ApplicationName { get { ComAdminAppInfo appInfo = ComAdminWrapper.GetAppInfo (appid.ToString ("B")); if (null == appInfo) return null; return appInfo.Name; } } public string ComponentProgID { get { ComAdminAppInfo appInfo = ComAdminWrapper.GetAppInfo (appid.ToString ("B")); if (null == appInfo) return null; ComAdminClassInfo classInfo = appInfo.FindClass (clsid.ToString ("B")); if (null == classInfo) return null; return classInfo.Name; } } public string InterfaceName { get { if (!isMexEndpoint) { ComAdminAppInfo appInfo = ComAdminWrapper.GetAppInfo (appid.ToString ("B")); if (null == appInfo) return null; ComAdminClassInfo classInfo = appInfo.FindClass (clsid.ToString ("B")); if (null == classInfo) return null; ComAdminInterfaceInfo interfaceInfo = classInfo.FindInterface (iid.ToString ("B")); if (null == interfaceInfo) return null; return interfaceInfo.Name; } else { return ContractType; } } } public EndpointConfig(Guid appid, Guid clsid, Guid iid, string bindingType, string bindingName, Uri address, bool isMexEndpoint, List methods) { this.appid = appid; this.clsid = clsid; this.iid = iid; this.bindingType = bindingType; this.bindingName = bindingName; this.address = address; this.isMexEndpoint = isMexEndpoint; this.methods = methods; this.container = null; } } abstract class EndpointConfigContainer { public abstract List GetEndpointConfigs(); public virtual bool HasEndpointsForApplication(Guid appid) { // This is a default (but kind of inefficient) implementation of this function List endpointConfigs = GetEndpointConfigs(appid); return (endpointConfigs.Count > 0); } public virtual List GetEndpointConfigs(Guid appid) { // A default implementation, kind of inefficient, but subclasses can override if they want.. List endpointConfigs = new List (); foreach (EndpointConfig endpointConfig in GetEndpointConfigs()) { if (endpointConfig.Appid == appid) { endpointConfigs.Add(endpointConfig); } } return endpointConfigs; } public abstract void Add(IList endpointConfigs); public abstract void PrepareChanges(); public abstract void AbortChanges(); // this can be called at any point prior to Commit public abstract void CommitChanges(); public abstract string DefaultEndpointAddress(Guid appId, Guid clsid, Guid iid); public abstract string DefaultMexAddress (Guid appId, Guid clsid); public abstract string DefaultBindingType { get ;} public abstract string DefaultBindingName { get ;} public abstract string DefaultTransactionalBindingType { get;} public abstract string DefaultTransactionalBindingName { get;} public abstract string DefaultMexBindingType { get;} public abstract string DefaultMexBindingName { get;} public abstract bool WasModified { get; set; } public abstract Configuration GetConfiguration(bool readOnly); public abstract string BaseServiceAddress(Guid appId, Guid clsid, Guid iid); public abstract List GetBaseAddresses(EndpointConfig config); public abstract void Remove(IList endpointConfigs); protected abstract void RemoveBinding (Configuration config); protected abstract void AddBinding (Configuration config); // returns true if added successfully, or false if didnt add due to duplicate. protected bool BaseAddEndpointConfig(Configuration config, EndpointConfig endpointConfig) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl = sg.Services.Services; ServiceElement serviceElement = null; // Find serviceElement foreach (ServiceElement el in serviceColl) { if (endpointConfig.MatchServiceType(el.Name)) { serviceElement = el; break; } } if (serviceElement == null) { // Didn't find one, create new element for this clsid serviceElement = new ServiceElement(endpointConfig.ServiceType); string baseServiceAddress = BaseServiceAddress(endpointConfig.Appid, endpointConfig.Clsid, endpointConfig.Iid); if (!String.IsNullOrEmpty(baseServiceAddress)) { BaseAddressElement bae = new BaseAddressElement(); bae.BaseAddress = baseServiceAddress; serviceElement.Host.BaseAddresses.Add(bae); } sg.Services.Services.Add(serviceElement); } if (endpointConfig.IsMexEndpoint) { EnsureComMetaDataExchangeBehaviorAdded(config); serviceElement.BehaviorConfiguration = comServiceBehavior; } bool methodsAdded = false; if (!endpointConfig.IsMexEndpoint) { methodsAdded = AddComContractToConfig(config, endpointConfig.InterfaceName, endpointConfig.Iid.ToString("B"), endpointConfig.Methods); } // Now, check if endpoint already exists.. foreach (ServiceEndpointElement ee in serviceElement.Endpoints) { bool listenerExists = true; if (this is ComplusEndpointConfigContainer) listenerExists = ((ComplusEndpointConfigContainer)this).ListenerComponentExists; if (endpointConfig.MatchContract(ee.Contract)) { if (listenerExists) return methodsAdded; // didn't add due to duplicate else serviceElement.Endpoints.Remove(ee); } } // All right, add the new endpoint now ServiceEndpointElement endpointElement = new ServiceEndpointElement(endpointConfig.Address, endpointConfig.ContractType); endpointElement.Binding = endpointConfig.BindingType; endpointElement.BindingConfiguration = endpointConfig.BindingName; serviceElement.Endpoints.Add(endpointElement); AddBinding(config); return true; } protected bool RemoveComContractMethods (Configuration config, string interfaceID, IList methods) { Guid iidInterface = new Guid (interfaceID); ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ComContractElementCollection contractCollection = sg.ComContracts.ComContracts; foreach (ComContractElement contractElement in contractCollection) { try { Guid contract = new Guid (contractElement.Contract); if (contract == iidInterface) { foreach (string methodName in methods) { foreach (ComMethodElement methodElement in contractElement.ExposedMethods) { if (methodElement.ExposedMethod == methodName) { contractElement.ExposedMethods.Remove(methodElement); break; } } } if (contractElement.ExposedMethods.Count == 0) { sg.ComContracts.ComContracts.Remove (contractElement); return true; } } } catch (FormatException) { } } return false; } protected bool RemoveComContractIfNotUsedByAnyService (Configuration config, string interfaceID) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl = sg.Services.Services; Guid iidInterface = new Guid (interfaceID); // Find serviceElement foreach (ServiceElement el in serviceColl) { // Now, check if endpoint already exists.. foreach (ServiceEndpointElement ee in el.Endpoints) { try { if (!IsMetaDataEndpoint (ee)) { Guid Iid = new Guid (ee.Contract); if (iidInterface == Iid) return false; } } catch (FormatException) { } } } ComContractElementCollection contractCollection = sg.ComContracts.ComContracts; foreach (ComContractElement element in contractCollection) { try { Guid contract = new Guid (element.Contract); if (contract == iidInterface) { contractCollection.Remove (element); return true; } } catch (FormatException) { } } return false; } protected bool AddComContractToConfig (Configuration config, string name, string contractType, IList methods) { Guid contractIID = new Guid (contractType); ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ComContractElementCollection contractCollection = sg.ComContracts.ComContracts; foreach (ComContractElement comContract in contractCollection) { try { Guid contractFound = new Guid (comContract.Contract); if (contractIID == contractFound) { bool methodsAdded = false; bool found = false; foreach (string methodName in methods) { found = false; foreach (ComMethodElement methodElement in comContract.ExposedMethods) { if (methodElement.ExposedMethod == methodName) found = true; } if (!found) { comContract.ExposedMethods.Add(new ComMethodElement(methodName)); methodsAdded = true; } } if (comContract.PersistableTypes.Count == 0 && Tool.Options.AllowReferences && methodsAdded) { comContract.PersistableTypes.EmitClear = true; } return methodsAdded; } } catch (FormatException) { } } // The contract does not exists // so we are going to add it ComContractElement newComContract = new ComContractElement (contractIID.ToString ("B").ToUpperInvariant ()); newComContract.Name = name; newComContract.Namespace = EndpointConfig.TempURI + contractIID.ToString ().ToUpperInvariant (); foreach (string methodName in methods) newComContract.ExposedMethods.Add(new ComMethodElement(methodName)); if (newComContract.PersistableTypes.Count == 0 && Tool.Options.AllowReferences) { newComContract.PersistableTypes.EmitClear = true; } newComContract.RequiresSession = true; contractCollection.Add (newComContract); return true; } protected bool IsMetaDataEndpoint (ServiceEndpointElement ee) { if (ee.Contract == ServiceMetadataBehavior.MexContractName) return true; else return false; } // NOTE that all EndpointConfigs returned by this guy have Guid.Empty as the appid, caller needs to fix that up protected Dictionary > BaseGetEndpointsFromConfiguration(Configuration config) { Dictionary > endpointConfigs = new Dictionary >(); ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl; try { serviceColl = sg.Services.Services; } catch (System.Configuration.ConfigurationErrorsException e) { ToolConsole.WriteWarning(e.Message); ToolConsole.WriteWarning(SR.GetString(SR.ConfigFileSkipped, e.Filename)); return endpointConfigs; } foreach (ServiceElement se in serviceColl) { string serviceType = se.Name; Guid clsid = Guid.Empty; Guid appId = Guid.Empty; string[] serviceParams = serviceType.Split(','); if (serviceParams.Length != 2) { continue; } try { appId = new Guid(serviceParams[0]); clsid = new Guid(serviceParams[1]); } catch (FormatException) { // Only Guid serviceTypes are of interest to us - those are the ones our listener picks up continue; } List list = null; if (endpointConfigs.ContainsKey(serviceType)) { list = endpointConfigs[serviceType]; } else { list = new List (); endpointConfigs[serviceType] = list; } foreach (ServiceEndpointElement ee in se.Endpoints) { EndpointConfig ec = null; if (!IsMetaDataEndpoint (ee)) { Guid contractType; try { contractType = new Guid(ee.Contract); } catch (FormatException) { continue; } ec = new EndpointConfig(Guid.Empty, clsid, contractType, ee.Binding, ee.BindingConfiguration, ee.Address, false ,new List ()); } else { ec = new EndpointConfig(Guid.Empty, clsid, typeof (IMetadataExchange).GUID, ee.Binding, ee.BindingConfiguration, ee.Address, true,new List ()); } list.Add(ec); } } return endpointConfigs; } protected bool RemoveAllServicesForContract (Configuration config, string interfaceID) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl = sg.Services.Services; bool removed = false; // Iterate over every serviceElement // in the services collection // and delete the specific interface ServiceElementCollection svcColl = new ServiceElementCollection (); foreach (ServiceElement el in serviceColl) { ServiceEndpointElementCollection endpointCollection = new ServiceEndpointElementCollection (); foreach (ServiceEndpointElement ee in el.Endpoints) { if (interfaceID.ToUpperInvariant () == ee.Contract.ToUpperInvariant ()) { // found it ! removed = true; endpointCollection.Add(ee); } } foreach (ServiceEndpointElement elementEndpoint in endpointCollection) { el.Endpoints.Remove (elementEndpoint); if (el.Endpoints.Count == 1) if (el.Endpoints[0].Contract == ServiceMetadataBehavior.MexContractName) el.Endpoints.Remove (el.Endpoints[0]); // if Mex endpoint remove it. if (el.Endpoints.Count == 0) svcColl.Add (el); } } foreach (ServiceElement service in svcColl) { sg.Services.Services.Remove(service); } if (serviceColl.Count == 0) { EnsureComMetaDataExchangeBehaviorRemoved(config); RemoveBinding (config); } return removed; } protected bool RemoveEndpointFromServiceOnly (Configuration config, EndpointConfig endpointConfig) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl = sg.Services.Services; ServiceElement serviceElement = null; // Find serviceElement foreach (ServiceElement el in serviceColl) { if (endpointConfig.MatchServiceType (el.Name)) { serviceElement = el; break; } } if (serviceElement == null) { // Didn't find class return false; } // Now, check if endpoint already exists.. foreach (ServiceEndpointElement ee in serviceElement.Endpoints) { if (endpointConfig.MatchContract (ee.Contract) && (ee.Address == endpointConfig.Address) ) { // found it ! serviceElement.Endpoints.Remove(ee); if (!endpointConfig.IsMexEndpoint) RemoveComContractIfNotUsedByAnyService (config, ee.Contract); if (serviceElement.Endpoints.Count == 1) if (serviceElement.Endpoints[0].Contract == ServiceMetadataBehavior.MexContractName) serviceElement.Endpoints.Remove (serviceElement.Endpoints[0]); // if Mex endpoint remove it. if (serviceElement.Endpoints.Count == 0) { serviceColl.Remove(serviceElement); if (serviceColl.Count == 0) { EnsureComMetaDataExchangeBehaviorRemoved(config); RemoveBinding (config); } } return true; } } return false; } // returns true if removed successfully, or false if didnt remove due to missing. protected bool BaseRemoveEndpointConfig(Configuration config, EndpointConfig endpointConfig) { if ((endpointConfig.Methods != null) && (!endpointConfig.IsMexEndpoint)) { bool removeContract = RemoveComContractMethods (config, endpointConfig.Iid.ToString ("B"), endpointConfig.Methods); if (removeContract) RemoveAllServicesForContract (config, endpointConfig.Iid.ToString ("B")); return true; } else return RemoveEndpointFromServiceOnly (config, endpointConfig); } // helper function used by subclasses protected Configuration GetConfigurationFromFile(string fileName) { ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); Configuration machineConfig = ConfigurationManager.OpenMachineConfiguration(); fileMap.MachineConfigFilename = machineConfig.FilePath; fileMap.ExeConfigFilename = fileName; if(!IsValidRuntime(fileName)) { string runtimeVersion = Assembly.GetExecutingAssembly().ImageRuntimeVersion; ToolConsole.WriteError(SR.GetString(SR.InvalidRuntime, runtimeVersion), ""); throw Tool.CreateException(SR.GetString(SR.OperationAbortedDuetoClrVersion), null); } return ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); } const string comServiceBehavior = "ComServiceMexBehavior"; protected void EnsureComMetaDataExchangeBehaviorAdded(Configuration config) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); if (!sg.Behaviors.ServiceBehaviors.ContainsKey(comServiceBehavior)) { ServiceBehaviorElement behavior = new ServiceBehaviorElement(comServiceBehavior); sg.Behaviors.ServiceBehaviors.Add(behavior); ServiceMetadataPublishingElement metadataPublishing = new ServiceMetadataPublishingElement(); if(Tool.Options.Hosting == Hosting.Complus || Tool.Options.Hosting == Hosting.NotSpecified) metadataPublishing.HttpGetEnabled = false; else metadataPublishing.HttpGetEnabled = true; behavior.Add(metadataPublishing); ServiceDebugElement serviceDebug = new ServiceDebugElement(); serviceDebug.IncludeExceptionDetailInFaults = false; behavior.Add(serviceDebug); } } protected void EnsureComMetaDataExchangeBehaviorRemoved (Configuration config) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); if (sg.Behaviors.ServiceBehaviors.ContainsKey(comServiceBehavior)) { ServiceBehaviorElement element = sg.Behaviors.ServiceBehaviors[comServiceBehavior]; sg.Behaviors.ServiceBehaviors.Remove(element); } } // we can only run on the clr version that we are built against internal static bool IsValidVersion(string version) { if (String.IsNullOrEmpty(version)) return false; return (version == Assembly.GetExecutingAssembly().ImageRuntimeVersion); } public static bool IsValidRuntime(string fileName) { // this is a negative check - we only want to fail // if incorrect data specifically was set if(String.IsNullOrEmpty(fileName)) return true; // this check is needed since we might get here on temporary files that are gone by now if (!File.Exists(fileName)) return true; XmlNode startupNode = null; XmlNodeList supportedRuntimes = null; XmlNode requiredRuntime = null; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(fileName); startupNode = xmlDoc.DocumentElement.SelectSingleNode("startup"); bool validRuntimeAvailable = true; if (null != startupNode) { supportedRuntimes = startupNode.SelectNodes("supportedRuntime"); if (null != supportedRuntimes) { if (supportedRuntimes.Count == 0) validRuntimeAvailable = true; else validRuntimeAvailable = false; foreach (XmlNode xmlNodeS in supportedRuntimes) { if (IsValidVersion(xmlNodeS.Attributes.GetNamedItem("version").Value)) validRuntimeAvailable = true; } } requiredRuntime = startupNode.SelectSingleNode("requiredRuntime"); if (null != requiredRuntime) { string requiredVersion = requiredRuntime.Attributes.GetNamedItem("version").Value; if (!IsValidVersion(requiredVersion)) { validRuntimeAvailable = false; } } } return validRuntimeAvailable; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace Microsoft.Tools.ServiceModel.ComSvcConfig { using System; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.Diagnostics; using System.Configuration; using System.Collections; using System.Collections.Specialized; using System.Collections.Generic; using System.IO; using System.Globalization; using System.Text; using System.Threading; using System.Reflection; using System.Runtime.InteropServices; using System.Security; using System.ServiceModel; using System.ServiceModel.Configuration; using Microsoft.Tools.ServiceModel; using System.Xml; class EndpointConfig { Guid appid; Guid clsid; Guid iid; string bindingType; string bindingName; Uri address; bool isMexEndpoint; List methods; EndpointConfigContainer container; public static readonly string TempURI = "http://tempuri.org/"; public static readonly string MexEndpointSuffix = "mex"; public Guid Appid { get { return this.appid; } set { this.appid = value; } } public Guid Clsid { get { return this.clsid; } } public Guid Iid { get { return this.iid; } } public string BindingType { get { return this.bindingType; } } public string BindingName { get { return this.bindingName; } } public Uri Address { get { return this.address; } } public bool IsMexEndpoint { get { return isMexEndpoint; } } public EndpointConfigContainer Container { get { return container; } set { container = value; } } public IList Methods { get { return methods; } set { methods = (List )value ; } } public string ContractType { get { if (isMexEndpoint) return ServiceMetadataBehavior.MexContractName; else return iid.ToString("B").ToUpperInvariant (); } } public bool MatchServiceType (string serviceType) { string[] serviceParams = serviceType.Split(','); if (serviceParams.Length != 2) { return false; } try { Guid guid = new Guid(serviceParams[0]); if (guid != Appid) return false; guid = new Guid(serviceParams[1]); if (guid != Clsid) return false; return true; } catch (FormatException) { } return false; } public bool MatchContract (string contract) { if (isMexEndpoint) { if (ContractType == contract) return true; else return false; } else { try { Guid guid = new Guid (contract); if (guid == Iid) return true; } catch (FormatException) { } return false; } } public string ServiceType { get { return Appid.ToString("B").ToUpperInvariant() + "," + Clsid.ToString("B").ToUpperInvariant(); } } public string ApplicationName { get { ComAdminAppInfo appInfo = ComAdminWrapper.GetAppInfo (appid.ToString ("B")); if (null == appInfo) return null; return appInfo.Name; } } public string ComponentProgID { get { ComAdminAppInfo appInfo = ComAdminWrapper.GetAppInfo (appid.ToString ("B")); if (null == appInfo) return null; ComAdminClassInfo classInfo = appInfo.FindClass (clsid.ToString ("B")); if (null == classInfo) return null; return classInfo.Name; } } public string InterfaceName { get { if (!isMexEndpoint) { ComAdminAppInfo appInfo = ComAdminWrapper.GetAppInfo (appid.ToString ("B")); if (null == appInfo) return null; ComAdminClassInfo classInfo = appInfo.FindClass (clsid.ToString ("B")); if (null == classInfo) return null; ComAdminInterfaceInfo interfaceInfo = classInfo.FindInterface (iid.ToString ("B")); if (null == interfaceInfo) return null; return interfaceInfo.Name; } else { return ContractType; } } } public EndpointConfig(Guid appid, Guid clsid, Guid iid, string bindingType, string bindingName, Uri address, bool isMexEndpoint, List methods) { this.appid = appid; this.clsid = clsid; this.iid = iid; this.bindingType = bindingType; this.bindingName = bindingName; this.address = address; this.isMexEndpoint = isMexEndpoint; this.methods = methods; this.container = null; } } abstract class EndpointConfigContainer { public abstract List GetEndpointConfigs(); public virtual bool HasEndpointsForApplication(Guid appid) { // This is a default (but kind of inefficient) implementation of this function List endpointConfigs = GetEndpointConfigs(appid); return (endpointConfigs.Count > 0); } public virtual List GetEndpointConfigs(Guid appid) { // A default implementation, kind of inefficient, but subclasses can override if they want.. List endpointConfigs = new List (); foreach (EndpointConfig endpointConfig in GetEndpointConfigs()) { if (endpointConfig.Appid == appid) { endpointConfigs.Add(endpointConfig); } } return endpointConfigs; } public abstract void Add(IList endpointConfigs); public abstract void PrepareChanges(); public abstract void AbortChanges(); // this can be called at any point prior to Commit public abstract void CommitChanges(); public abstract string DefaultEndpointAddress(Guid appId, Guid clsid, Guid iid); public abstract string DefaultMexAddress (Guid appId, Guid clsid); public abstract string DefaultBindingType { get ;} public abstract string DefaultBindingName { get ;} public abstract string DefaultTransactionalBindingType { get;} public abstract string DefaultTransactionalBindingName { get;} public abstract string DefaultMexBindingType { get;} public abstract string DefaultMexBindingName { get;} public abstract bool WasModified { get; set; } public abstract Configuration GetConfiguration(bool readOnly); public abstract string BaseServiceAddress(Guid appId, Guid clsid, Guid iid); public abstract List GetBaseAddresses(EndpointConfig config); public abstract void Remove(IList endpointConfigs); protected abstract void RemoveBinding (Configuration config); protected abstract void AddBinding (Configuration config); // returns true if added successfully, or false if didnt add due to duplicate. protected bool BaseAddEndpointConfig(Configuration config, EndpointConfig endpointConfig) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl = sg.Services.Services; ServiceElement serviceElement = null; // Find serviceElement foreach (ServiceElement el in serviceColl) { if (endpointConfig.MatchServiceType(el.Name)) { serviceElement = el; break; } } if (serviceElement == null) { // Didn't find one, create new element for this clsid serviceElement = new ServiceElement(endpointConfig.ServiceType); string baseServiceAddress = BaseServiceAddress(endpointConfig.Appid, endpointConfig.Clsid, endpointConfig.Iid); if (!String.IsNullOrEmpty(baseServiceAddress)) { BaseAddressElement bae = new BaseAddressElement(); bae.BaseAddress = baseServiceAddress; serviceElement.Host.BaseAddresses.Add(bae); } sg.Services.Services.Add(serviceElement); } if (endpointConfig.IsMexEndpoint) { EnsureComMetaDataExchangeBehaviorAdded(config); serviceElement.BehaviorConfiguration = comServiceBehavior; } bool methodsAdded = false; if (!endpointConfig.IsMexEndpoint) { methodsAdded = AddComContractToConfig(config, endpointConfig.InterfaceName, endpointConfig.Iid.ToString("B"), endpointConfig.Methods); } // Now, check if endpoint already exists.. foreach (ServiceEndpointElement ee in serviceElement.Endpoints) { bool listenerExists = true; if (this is ComplusEndpointConfigContainer) listenerExists = ((ComplusEndpointConfigContainer)this).ListenerComponentExists; if (endpointConfig.MatchContract(ee.Contract)) { if (listenerExists) return methodsAdded; // didn't add due to duplicate else serviceElement.Endpoints.Remove(ee); } } // All right, add the new endpoint now ServiceEndpointElement endpointElement = new ServiceEndpointElement(endpointConfig.Address, endpointConfig.ContractType); endpointElement.Binding = endpointConfig.BindingType; endpointElement.BindingConfiguration = endpointConfig.BindingName; serviceElement.Endpoints.Add(endpointElement); AddBinding(config); return true; } protected bool RemoveComContractMethods (Configuration config, string interfaceID, IList methods) { Guid iidInterface = new Guid (interfaceID); ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ComContractElementCollection contractCollection = sg.ComContracts.ComContracts; foreach (ComContractElement contractElement in contractCollection) { try { Guid contract = new Guid (contractElement.Contract); if (contract == iidInterface) { foreach (string methodName in methods) { foreach (ComMethodElement methodElement in contractElement.ExposedMethods) { if (methodElement.ExposedMethod == methodName) { contractElement.ExposedMethods.Remove(methodElement); break; } } } if (contractElement.ExposedMethods.Count == 0) { sg.ComContracts.ComContracts.Remove (contractElement); return true; } } } catch (FormatException) { } } return false; } protected bool RemoveComContractIfNotUsedByAnyService (Configuration config, string interfaceID) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl = sg.Services.Services; Guid iidInterface = new Guid (interfaceID); // Find serviceElement foreach (ServiceElement el in serviceColl) { // Now, check if endpoint already exists.. foreach (ServiceEndpointElement ee in el.Endpoints) { try { if (!IsMetaDataEndpoint (ee)) { Guid Iid = new Guid (ee.Contract); if (iidInterface == Iid) return false; } } catch (FormatException) { } } } ComContractElementCollection contractCollection = sg.ComContracts.ComContracts; foreach (ComContractElement element in contractCollection) { try { Guid contract = new Guid (element.Contract); if (contract == iidInterface) { contractCollection.Remove (element); return true; } } catch (FormatException) { } } return false; } protected bool AddComContractToConfig (Configuration config, string name, string contractType, IList methods) { Guid contractIID = new Guid (contractType); ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ComContractElementCollection contractCollection = sg.ComContracts.ComContracts; foreach (ComContractElement comContract in contractCollection) { try { Guid contractFound = new Guid (comContract.Contract); if (contractIID == contractFound) { bool methodsAdded = false; bool found = false; foreach (string methodName in methods) { found = false; foreach (ComMethodElement methodElement in comContract.ExposedMethods) { if (methodElement.ExposedMethod == methodName) found = true; } if (!found) { comContract.ExposedMethods.Add(new ComMethodElement(methodName)); methodsAdded = true; } } if (comContract.PersistableTypes.Count == 0 && Tool.Options.AllowReferences && methodsAdded) { comContract.PersistableTypes.EmitClear = true; } return methodsAdded; } } catch (FormatException) { } } // The contract does not exists // so we are going to add it ComContractElement newComContract = new ComContractElement (contractIID.ToString ("B").ToUpperInvariant ()); newComContract.Name = name; newComContract.Namespace = EndpointConfig.TempURI + contractIID.ToString ().ToUpperInvariant (); foreach (string methodName in methods) newComContract.ExposedMethods.Add(new ComMethodElement(methodName)); if (newComContract.PersistableTypes.Count == 0 && Tool.Options.AllowReferences) { newComContract.PersistableTypes.EmitClear = true; } newComContract.RequiresSession = true; contractCollection.Add (newComContract); return true; } protected bool IsMetaDataEndpoint (ServiceEndpointElement ee) { if (ee.Contract == ServiceMetadataBehavior.MexContractName) return true; else return false; } // NOTE that all EndpointConfigs returned by this guy have Guid.Empty as the appid, caller needs to fix that up protected Dictionary > BaseGetEndpointsFromConfiguration(Configuration config) { Dictionary > endpointConfigs = new Dictionary >(); ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl; try { serviceColl = sg.Services.Services; } catch (System.Configuration.ConfigurationErrorsException e) { ToolConsole.WriteWarning(e.Message); ToolConsole.WriteWarning(SR.GetString(SR.ConfigFileSkipped, e.Filename)); return endpointConfigs; } foreach (ServiceElement se in serviceColl) { string serviceType = se.Name; Guid clsid = Guid.Empty; Guid appId = Guid.Empty; string[] serviceParams = serviceType.Split(','); if (serviceParams.Length != 2) { continue; } try { appId = new Guid(serviceParams[0]); clsid = new Guid(serviceParams[1]); } catch (FormatException) { // Only Guid serviceTypes are of interest to us - those are the ones our listener picks up continue; } List list = null; if (endpointConfigs.ContainsKey(serviceType)) { list = endpointConfigs[serviceType]; } else { list = new List (); endpointConfigs[serviceType] = list; } foreach (ServiceEndpointElement ee in se.Endpoints) { EndpointConfig ec = null; if (!IsMetaDataEndpoint (ee)) { Guid contractType; try { contractType = new Guid(ee.Contract); } catch (FormatException) { continue; } ec = new EndpointConfig(Guid.Empty, clsid, contractType, ee.Binding, ee.BindingConfiguration, ee.Address, false ,new List ()); } else { ec = new EndpointConfig(Guid.Empty, clsid, typeof (IMetadataExchange).GUID, ee.Binding, ee.BindingConfiguration, ee.Address, true,new List ()); } list.Add(ec); } } return endpointConfigs; } protected bool RemoveAllServicesForContract (Configuration config, string interfaceID) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl = sg.Services.Services; bool removed = false; // Iterate over every serviceElement // in the services collection // and delete the specific interface ServiceElementCollection svcColl = new ServiceElementCollection (); foreach (ServiceElement el in serviceColl) { ServiceEndpointElementCollection endpointCollection = new ServiceEndpointElementCollection (); foreach (ServiceEndpointElement ee in el.Endpoints) { if (interfaceID.ToUpperInvariant () == ee.Contract.ToUpperInvariant ()) { // found it ! removed = true; endpointCollection.Add(ee); } } foreach (ServiceEndpointElement elementEndpoint in endpointCollection) { el.Endpoints.Remove (elementEndpoint); if (el.Endpoints.Count == 1) if (el.Endpoints[0].Contract == ServiceMetadataBehavior.MexContractName) el.Endpoints.Remove (el.Endpoints[0]); // if Mex endpoint remove it. if (el.Endpoints.Count == 0) svcColl.Add (el); } } foreach (ServiceElement service in svcColl) { sg.Services.Services.Remove(service); } if (serviceColl.Count == 0) { EnsureComMetaDataExchangeBehaviorRemoved(config); RemoveBinding (config); } return removed; } protected bool RemoveEndpointFromServiceOnly (Configuration config, EndpointConfig endpointConfig) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); ServiceElementCollection serviceColl = sg.Services.Services; ServiceElement serviceElement = null; // Find serviceElement foreach (ServiceElement el in serviceColl) { if (endpointConfig.MatchServiceType (el.Name)) { serviceElement = el; break; } } if (serviceElement == null) { // Didn't find class return false; } // Now, check if endpoint already exists.. foreach (ServiceEndpointElement ee in serviceElement.Endpoints) { if (endpointConfig.MatchContract (ee.Contract) && (ee.Address == endpointConfig.Address) ) { // found it ! serviceElement.Endpoints.Remove(ee); if (!endpointConfig.IsMexEndpoint) RemoveComContractIfNotUsedByAnyService (config, ee.Contract); if (serviceElement.Endpoints.Count == 1) if (serviceElement.Endpoints[0].Contract == ServiceMetadataBehavior.MexContractName) serviceElement.Endpoints.Remove (serviceElement.Endpoints[0]); // if Mex endpoint remove it. if (serviceElement.Endpoints.Count == 0) { serviceColl.Remove(serviceElement); if (serviceColl.Count == 0) { EnsureComMetaDataExchangeBehaviorRemoved(config); RemoveBinding (config); } } return true; } } return false; } // returns true if removed successfully, or false if didnt remove due to missing. protected bool BaseRemoveEndpointConfig(Configuration config, EndpointConfig endpointConfig) { if ((endpointConfig.Methods != null) && (!endpointConfig.IsMexEndpoint)) { bool removeContract = RemoveComContractMethods (config, endpointConfig.Iid.ToString ("B"), endpointConfig.Methods); if (removeContract) RemoveAllServicesForContract (config, endpointConfig.Iid.ToString ("B")); return true; } else return RemoveEndpointFromServiceOnly (config, endpointConfig); } // helper function used by subclasses protected Configuration GetConfigurationFromFile(string fileName) { ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); Configuration machineConfig = ConfigurationManager.OpenMachineConfiguration(); fileMap.MachineConfigFilename = machineConfig.FilePath; fileMap.ExeConfigFilename = fileName; if(!IsValidRuntime(fileName)) { string runtimeVersion = Assembly.GetExecutingAssembly().ImageRuntimeVersion; ToolConsole.WriteError(SR.GetString(SR.InvalidRuntime, runtimeVersion), ""); throw Tool.CreateException(SR.GetString(SR.OperationAbortedDuetoClrVersion), null); } return ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); } const string comServiceBehavior = "ComServiceMexBehavior"; protected void EnsureComMetaDataExchangeBehaviorAdded(Configuration config) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); if (!sg.Behaviors.ServiceBehaviors.ContainsKey(comServiceBehavior)) { ServiceBehaviorElement behavior = new ServiceBehaviorElement(comServiceBehavior); sg.Behaviors.ServiceBehaviors.Add(behavior); ServiceMetadataPublishingElement metadataPublishing = new ServiceMetadataPublishingElement(); if(Tool.Options.Hosting == Hosting.Complus || Tool.Options.Hosting == Hosting.NotSpecified) metadataPublishing.HttpGetEnabled = false; else metadataPublishing.HttpGetEnabled = true; behavior.Add(metadataPublishing); ServiceDebugElement serviceDebug = new ServiceDebugElement(); serviceDebug.IncludeExceptionDetailInFaults = false; behavior.Add(serviceDebug); } } protected void EnsureComMetaDataExchangeBehaviorRemoved (Configuration config) { ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config); if (sg.Behaviors.ServiceBehaviors.ContainsKey(comServiceBehavior)) { ServiceBehaviorElement element = sg.Behaviors.ServiceBehaviors[comServiceBehavior]; sg.Behaviors.ServiceBehaviors.Remove(element); } } // we can only run on the clr version that we are built against internal static bool IsValidVersion(string version) { if (String.IsNullOrEmpty(version)) return false; return (version == Assembly.GetExecutingAssembly().ImageRuntimeVersion); } public static bool IsValidRuntime(string fileName) { // this is a negative check - we only want to fail // if incorrect data specifically was set if(String.IsNullOrEmpty(fileName)) return true; // this check is needed since we might get here on temporary files that are gone by now if (!File.Exists(fileName)) return true; XmlNode startupNode = null; XmlNodeList supportedRuntimes = null; XmlNode requiredRuntime = null; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(fileName); startupNode = xmlDoc.DocumentElement.SelectSingleNode("startup"); bool validRuntimeAvailable = true; if (null != startupNode) { supportedRuntimes = startupNode.SelectNodes("supportedRuntime"); if (null != supportedRuntimes) { if (supportedRuntimes.Count == 0) validRuntimeAvailable = true; else validRuntimeAvailable = false; foreach (XmlNode xmlNodeS in supportedRuntimes) { if (IsValidVersion(xmlNodeS.Attributes.GetNamedItem("version").Value)) validRuntimeAvailable = true; } } requiredRuntime = startupNode.SelectSingleNode("requiredRuntime"); if (null != requiredRuntime) { string requiredVersion = requiredRuntime.Attributes.GetNamedItem("version").Value; if (!IsValidVersion(requiredVersion)) { validRuntimeAvailable = false; } } } return validRuntimeAvailable; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CompareValidator.cs
- PreviewPrintController.cs
- SvcMapFileLoader.cs
- StatusStrip.cs
- StickyNoteContentControl.cs
- PopOutPanel.cs
- StringConverter.cs
- XMLDiffLoader.cs
- SymmetricAlgorithm.cs
- ScriptResourceAttribute.cs
- DataViewManagerListItemTypeDescriptor.cs
- WindowProviderWrapper.cs
- XmlSignificantWhitespace.cs
- ConsoleKeyInfo.cs
- XmlCountingReader.cs
- DisplayNameAttribute.cs
- LoadedOrUnloadedOperation.cs
- WebPartCatalogAddVerb.cs
- BindableAttribute.cs
- CompoundFileDeflateTransform.cs
- WebContext.cs
- WebPartCatalogCloseVerb.cs
- ButtonChrome.cs
- ProvidersHelper.cs
- TransformCollection.cs
- RepeaterDataBoundAdapter.cs
- AudioException.cs
- HtmlElementEventArgs.cs
- ExpandCollapsePattern.cs
- HtmlFormWrapper.cs
- SqlConnectionPoolProviderInfo.cs
- MetadataWorkspace.cs
- EventManager.cs
- ValidatingReaderNodeData.cs
- HwndProxyElementProvider.cs
- BridgeDataRecord.cs
- InfoCardProofToken.cs
- _RequestCacheProtocol.cs
- UpdateException.cs
- HwndSourceKeyboardInputSite.cs
- UshortList2.cs
- NonParentingControl.cs
- RawStylusInputReport.cs
- TypeReference.cs
- SubclassTypeValidator.cs
- WebPartConnectVerb.cs
- ProtocolsConfigurationHandler.cs
- GroupStyle.cs
- ClientRolePrincipal.cs
- Transform3DGroup.cs
- HttpRequest.cs
- RNGCryptoServiceProvider.cs
- SHA512.cs
- XmlAttributeCache.cs
- DataGridViewCellCancelEventArgs.cs
- ExpandableObjectConverter.cs
- QilXmlWriter.cs
- DependencyPropertyKey.cs
- ChangeBlockUndoRecord.cs
- RightsManagementEncryptedStream.cs
- GridViewCancelEditEventArgs.cs
- EmptyEnumerator.cs
- UpdatePanelTriggerCollection.cs
- LineGeometry.cs
- FolderBrowserDialog.cs
- PlacementWorkspace.cs
- WebRequest.cs
- BoolExpressionVisitors.cs
- InfoCardPolicy.cs
- EntityTypeBase.cs
- ToolStripPanel.cs
- CreateRefExpr.cs
- DecimalStorage.cs
- UnsafeNativeMethods.cs
- DetailsViewCommandEventArgs.cs
- SessionIDManager.cs
- RuntimeArgumentHandle.cs
- NGCPageContentCollectionSerializerAsync.cs
- GridViewSortEventArgs.cs
- UnaryExpression.cs
- PageHandlerFactory.cs
- DoubleStorage.cs
- SymbolEqualComparer.cs
- ColumnHeaderConverter.cs
- DataGridComboBoxColumn.cs
- NextPreviousPagerField.cs
- PartialCachingControl.cs
- ClassImporter.cs
- Button.cs
- XmlSchemaGroup.cs
- HostDesigntimeLicenseContext.cs
- CodeDirectiveCollection.cs
- ALinqExpressionVisitor.cs
- CompilerGlobalScopeAttribute.cs
- TransformConverter.cs
- ViewManager.cs
- PowerModeChangedEventArgs.cs
- StatusBar.cs
- DbConnectionStringCommon.cs
- Vector3DConverter.cs