| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.ServiceModel.ComIntegration
- {
- using System;
- using System.ServiceModel.Dispatcher;
- using System.ServiceModel.Description;
- using System.Collections.Generic;
- using System.Collections;
- using System.Diagnostics;
- using System.EnterpriseServices;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.ServiceModel;
- using System.ServiceModel.Configuration;
- using System.Transactions;
- using SR = System.ServiceModel.SR;
- using System.ServiceModel.Diagnostics;
- using System.Runtime;
- // The values of the enum are reflected from the values in the
- // COM+ Admin SDK.
- //
- enum Bitness
- {
- Bitness32 = 0x01,
- Bitness64 = 0x02
- }
- enum ThreadingModel
- {
- MTA,
- STA
- }
- enum HostingMode
- {
- ComPlus, // Living in a DllHost.exe
- WebHostOutOfProcess, // From webhost to dllhost.exe
- WebHostInProcess // Inside webhost
- }
- class ServiceInfo
- {
- ServiceElement service;
- Guid clsid;
- Guid appid;
- HostingMode hostingMode;
- Guid partitionId;
- Bitness bitness;
- ThreadingModel threadingModel;
- TransactionOption transactionOption;
- IsolationLevel isolationLevel;
- bool checkRoles;
- string[] componentRoleMembers;
- bool objectPoolingEnabled;
- int maxPoolSize;
- Type managedType;
- List<ContractInfo> contracts;
- string serviceName;
- Dictionary<Guid, List<Type>> udts;
- public string ServiceName
- {
- get
- {
- return serviceName;
- }
- }
- // NOTE: Construction of this thing is quite inefficient-- it
- // has several nested loops that could probably be
- // improved. Such optimizations have been left for when
- // it turns out to be a performance problem, for the
- // sake of simplicity.
- //
- public ServiceInfo(Guid clsid,
- ServiceElement service,
- ComCatalogObject application,
- ComCatalogObject classObject,
- HostingMode hostingMode)
- {
- // Simple things...
- //
- this.service = service;
- this.clsid = clsid;
- this.appid = Fx.CreateGuid((string)application.GetValue("ID"));
- this.partitionId = Fx.CreateGuid((string)application.GetValue("AppPartitionID"));
- this.bitness = (Bitness)classObject.GetValue("Bitness");
- this.transactionOption = (TransactionOption)classObject.GetValue("Transaction");
- this.hostingMode = hostingMode;
- this.managedType = TypeCacheManager.ResolveClsidToType(clsid);
- this.serviceName = application.Name + "." + classObject.Name;
- this.udts = new Dictionary<Guid, List<Type>>();
- // Isolation Level
- COMAdminIsolationLevel adminIsolationLevel;
- adminIsolationLevel = (COMAdminIsolationLevel)classObject.GetValue("TxIsolationLevel");
- switch (adminIsolationLevel)
- {
- case COMAdminIsolationLevel.Any:
- this.isolationLevel = IsolationLevel.Unspecified;
- break;
- case COMAdminIsolationLevel.ReadUncommitted:
- this.isolationLevel = IsolationLevel.ReadUncommitted;
- break;
- case COMAdminIsolationLevel.ReadCommitted:
- this.isolationLevel = IsolationLevel.ReadCommitted;
- break;
- case COMAdminIsolationLevel.RepeatableRead:
- this.isolationLevel = IsolationLevel.RepeatableRead;
- break;
- case COMAdminIsolationLevel.Serializable:
- this.isolationLevel = IsolationLevel.Serializable;
- break;
- default:
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ListenerInitFailed(
- SR.GetString(SR.InvalidIsolationLevelValue,
- this.clsid, adminIsolationLevel)));
- }
- // Threading Model
- //
- COMAdminThreadingModel adminThreadingModel;
- adminThreadingModel = (COMAdminThreadingModel)classObject.GetValue("ThreadingModel");
- switch (adminThreadingModel)
- {
- case COMAdminThreadingModel.Apartment:
- case COMAdminThreadingModel.Main:
- this.threadingModel = ThreadingModel.STA;
- objectPoolingEnabled = false;
- break;
- default:
- this.threadingModel = ThreadingModel.MTA;
- objectPoolingEnabled = (bool)classObject.GetValue("ObjectPoolingEnabled");
- break;
- }
- // Object Pool settings
- //
- if (objectPoolingEnabled)
- {
- maxPoolSize = (int)classObject.GetValue("MaxPoolSize");
- }
- else
- maxPoolSize = 0;
- // Security Settings
- //
- bool appSecurityEnabled;
- appSecurityEnabled = (bool)application.GetValue(
- "ApplicationAccessChecksEnabled");
- if (appSecurityEnabled)
- {
- bool classSecurityEnabled;
- classSecurityEnabled = (bool)classObject.GetValue(
- "ComponentAccessChecksEnabled");
- if (classSecurityEnabled)
- {
- this.checkRoles = true;
- }
- }
- // Component Roles
- //
- ComCatalogCollection roles;
- roles = classObject.GetCollection("RolesForComponent");
- this.componentRoleMembers = CatalogUtil.GetRoleMembers(application, roles);
- // Contracts
- // One ContractInfo per unique IID exposed, so we need to
- // filter duplicates.
- //
- this.contracts = new List<ContractInfo>();
- ComCatalogCollection interfaces;
- interfaces = classObject.GetCollection("InterfacesForComponent");
- foreach (ServiceEndpointElement endpoint in service.Endpoints)
- {
- ContractInfo contract = null;
- if (endpoint.Contract == ServiceMetadataBehavior.MexContractName)
- continue;
- Guid iid;
- if (DiagnosticUtility.Utility.TryCreateGuid(endpoint.Contract, out iid))
- {
- // (Filter duplicates.)
- bool duplicate = false;
- foreach (ContractInfo otherContract in this.contracts)
- {
- if (iid == otherContract.IID)
- {
- duplicate = true;
- break;
- }
- }
- if (duplicate) continue;
- foreach (ComCatalogObject interfaceObject in interfaces)
- {
- Guid otherInterfaceID;
- if (DiagnosticUtility.Utility.TryCreateGuid((string)interfaceObject.GetValue("IID"), out otherInterfaceID))
- {
- if (otherInterfaceID == iid)
- {
- contract = new ContractInfo(iid,
- endpoint,
- interfaceObject,
- application);
- break;
- }
- }
- }
- }
- if (contract == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ListenerInitFailed(
- SR.GetString(SR.EndpointNotAnIID,
- clsid.ToString("B").ToUpperInvariant(),
- endpoint.Contract)));
- }
- this.contracts.Add(contract);
- }
- }
- public Type ServiceType
- {
- get { return this.managedType; }
- }
- public ServiceElement ServiceElement
- {
- get { return this.service; }
- }
- public Guid Clsid
- {
- get { return this.clsid; }
- }
- public Guid AppID
- {
- get { return this.appid; }
- }
- public Guid PartitionId
- {
- get { return this.partitionId; }
- }
- public Bitness Bitness
- {
- get { return this.bitness; }
- }
- public bool CheckRoles
- {
- get { return this.checkRoles; }
- }
- public ThreadingModel ThreadingModel
- {
- get { return this.threadingModel; }
- }
- public TransactionOption TransactionOption
- {
- get { return this.transactionOption; }
- }
- public IsolationLevel IsolationLevel
- {
- get { return this.isolationLevel; }
- }
- public string[] ComponentRoleMembers
- {
- get { return this.componentRoleMembers; }
- }
- public List<ContractInfo> Contracts
- {
- get { return this.contracts; }
- }
- public HostingMode HostingMode
- {
- get { return this.hostingMode; }
- }
- public bool Pooled
- {
- get { return this.objectPoolingEnabled; }
- }
- public int MaxPoolSize
- {
- get { return this.maxPoolSize; }
- }
- internal Guid[] Assemblies
- {
- get
- {
- Guid[] ret = new Guid[this.udts.Keys.Count];
- this.udts.Keys.CopyTo(ret, 0);
- return ret;
- }
- }
- internal bool HasUdts()
- {
- // use the assembly count since we only add assemblies when we got UDTs
- return (this.udts.Keys.Count > 0);
- }
- internal Type[] GetTypes(Guid assemblyId)
- {
- List<Type> ret = null;
- udts.TryGetValue(assemblyId, out ret);
- if (null == ret)
- return new Type[0];
- return ret.ToArray();
- }
- internal void AddUdt(Type udt, Guid assemblyId)
- {
- if (!udts.ContainsKey(assemblyId))
- udts[assemblyId] = new List<Type>();
- if (!udts[assemblyId].Contains(udt))
- udts[assemblyId].Add(udt);
- }
- }
- class ContractInfo
- {
- string name;
- Guid iid;
- string[] interfaceRoleMembers;
- List<OperationInfo> operations;
- public ContractInfo(Guid iid,
- ServiceEndpointElement endpoint,
- ComCatalogObject interfaceObject,
- ComCatalogObject application)
- {
- this.name = endpoint.Contract;
- this.iid = iid;
- // Interface Roles
- //
- ComCatalogCollection roles;
- roles = interfaceObject.GetCollection("RolesForInterface");
- this.interfaceRoleMembers = CatalogUtil.GetRoleMembers(application,
- roles);
- // Operations
- //
- this.operations = new List<OperationInfo>();
- ComCatalogCollection methods;
- methods = interfaceObject.GetCollection("MethodsForInterface");
- foreach (ComCatalogObject method in methods)
- {
- this.operations.Add(new OperationInfo(method,
- application));
- }
- }
- public string Name
- {
- get { return this.name; }
- }
- public Guid IID
- {
- get { return this.iid; }
- }
- public string[] InterfaceRoleMembers
- {
- get { return this.interfaceRoleMembers; }
- }
- public List<OperationInfo> Operations
- {
- get { return this.operations; }
- }
- }
- class OperationInfo
- {
- string name;
- string[] methodRoleMembers;
- public OperationInfo(ComCatalogObject methodObject,
- ComCatalogObject application)
- {
- this.name = (string)methodObject.GetValue("Name");
- // Method Roles
- //
- ComCatalogCollection roles;
- roles = methodObject.GetCollection("RolesForMethod");
- this.methodRoleMembers = CatalogUtil.GetRoleMembers(application,
- roles);
- }
- public string Name
- {
- get { return this.name; }
- }
- public string[] MethodRoleMembers
- {
- get { return this.methodRoleMembers; }
- }
- }
- }
|