You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			174 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //----------------------------------------------------------------
 | |
| // Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| //----------------------------------------------------------------
 | |
| namespace System.ServiceModel.Activities
 | |
| {
 | |
|     using System.Diagnostics;
 | |
|     using System.Globalization;
 | |
|     using System.ServiceModel;
 | |
|     using System.ServiceModel.Activities.Description;
 | |
|     using System.ServiceModel.Channels;
 | |
|     using System.ServiceModel.Description;
 | |
|     using System.Runtime;
 | |
|     using System.Threading;
 | |
|     using System.Security;
 | |
|     using System.Security.Permissions;
 | |
|     
 | |
|     [Fx.Tag.XamlVisible(false)]
 | |
|     public class WorkflowControlEndpoint : ServiceEndpoint
 | |
|     {
 | |
|         static Uri defaultBaseUri;
 | |
| 
 | |
|         // Double-checked locking pattern requires volatile for read/write synchronization
 | |
|         static volatile ContractDescription workflowControlServiceBaseContract;
 | |
|         static volatile ContractDescription workflowControlServiceContract;
 | |
|         static object workflowContractDescriptionLock = new object();
 | |
| 
 | |
|         public WorkflowControlEndpoint()
 | |
|             : this(WorkflowControlEndpoint.GetDefaultBinding(),
 | |
|             new EndpointAddress(new Uri(WorkflowControlEndpoint.DefaultBaseUri, new Uri(Guid.NewGuid().ToString(), UriKind.Relative))))
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         public WorkflowControlEndpoint(Binding binding, EndpointAddress address)
 | |
|             : base(WorkflowControlEndpoint.WorkflowControlServiceContract, binding, address)
 | |
|         {
 | |
|             this.IsSystemEndpoint = true;
 | |
|         }
 | |
| 
 | |
|         internal static ContractDescription WorkflowControlServiceBaseContract
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (workflowControlServiceBaseContract == null)
 | |
|                 {
 | |
|                     lock (workflowContractDescriptionLock)
 | |
|                     {
 | |
|                         if (workflowControlServiceBaseContract == null)
 | |
|                         {
 | |
|                             foreach (OperationDescription operation in WorkflowControlServiceContract.Operations)
 | |
|                             {
 | |
|                                 if (operation.DeclaringContract != WorkflowControlServiceContract)
 | |
|                                 {
 | |
|                                     workflowControlServiceBaseContract = operation.DeclaringContract;
 | |
|                                     break;
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 return workflowControlServiceBaseContract;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal static ContractDescription WorkflowControlServiceContract
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (workflowControlServiceContract == null)
 | |
|                 {
 | |
|                     lock (workflowContractDescriptionLock)
 | |
|                     {
 | |
|                         if (workflowControlServiceContract == null)
 | |
|                         {
 | |
|                             ContractDescription tempControlServiceContract = ContractDescription.GetContract(
 | |
|                                 typeof(IWorkflowUpdateableInstanceManagement));
 | |
|                             tempControlServiceContract.Behaviors.Add(new ServiceMetadataContractBehavior(true));
 | |
|                             ApplyOperationBehaviors(tempControlServiceContract);
 | |
|                             // For back-compat, need to support existing code which expects the old contract type
 | |
|                             tempControlServiceContract.ContractType = typeof(IWorkflowInstanceManagement);
 | |
|                             workflowControlServiceContract = tempControlServiceContract;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 return workflowControlServiceContract;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [Fx.Tag.SecurityNote(Critical = "Critical because it retreives the Process Id via Process.Id, which has a link demand for Full Trust.",
 | |
|             Safe = "Safe because it demands FullTrust")]
 | |
|         [SecuritySafeCritical]
 | |
|         [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
 | |
|         static void RetrieveProcessIdAndAppDomainId(out int processId, out int appDomainId)
 | |
|         {
 | |
|             processId = Process.GetCurrentProcess().Id;
 | |
|             appDomainId = AppDomain.CurrentDomain.Id;
 | |
|         }
 | |
| 
 | |
|         static Uri DefaultBaseUri
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (defaultBaseUri == null)
 | |
|                 {
 | |
|                     // If we are running in full trust, use the ProcessId and AppDomainId. If partial trust, use a new guid to make the URI unique and avoid
 | |
|                     // the usage of ProcessId and AppDomainId. We are doing this for back compat.
 | |
|                     if (PartialTrustHelpers.AppDomainFullyTrusted)
 | |
|                     {
 | |
|                         int processId;
 | |
|                         int appDomainId;
 | |
|                         RetrieveProcessIdAndAppDomainId(out processId, out appDomainId);
 | |
|                         defaultBaseUri = new Uri(string.Format(CultureInfo.InvariantCulture, "net.pipe://localhost/workflowControlServiceEndpoint/{0}/{1}",
 | |
|                             processId,
 | |
|                             appDomainId));
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         Uri tempUri = new Uri(string.Format(CultureInfo.InvariantCulture, "net.pipe://localhost/workflowControlServiceEndpoint/{0}",
 | |
|                             Guid.NewGuid().ToString()));
 | |
|                         // Using Interlocked.CompareExchange because new Guid.NewGuid is not atomic.
 | |
|                         Interlocked.CompareExchange(ref defaultBaseUri, tempUri, null);
 | |
|                     }
 | |
|                 }
 | |
|                 return defaultBaseUri;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static Binding GetDefaultBinding()
 | |
|         {
 | |
|             return new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { TransactionFlow = true };
 | |
|         }
 | |
| 
 | |
|         static void ApplyOperationBehaviors(ContractDescription contractDescription)
 | |
|         {
 | |
|             foreach (OperationDescription operationDescription in contractDescription.Operations)
 | |
|             {
 | |
|                 //Except "Abandon" all the operations in this contract are Async.
 | |
|                 //All Transacted* operation are Transacted & Async.
 | |
|                 switch (operationDescription.Name)
 | |
|                 {
 | |
|                     case XD2.WorkflowInstanceManagementService.Abandon:
 | |
|                     case XD2.WorkflowInstanceManagementService.Cancel:
 | |
|                     case XD2.WorkflowInstanceManagementService.Run:
 | |
|                     case XD2.WorkflowInstanceManagementService.Suspend:
 | |
|                     case XD2.WorkflowInstanceManagementService.Terminate:
 | |
|                     case XD2.WorkflowInstanceManagementService.Unsuspend:
 | |
|                     case XD2.WorkflowInstanceManagementService.Update:
 | |
|                         EnsureDispatch(operationDescription);
 | |
|                         break;
 | |
|                     case XD2.WorkflowInstanceManagementService.TransactedCancel:
 | |
|                     case XD2.WorkflowInstanceManagementService.TransactedRun:
 | |
|                     case XD2.WorkflowInstanceManagementService.TransactedSuspend:
 | |
|                     case XD2.WorkflowInstanceManagementService.TransactedTerminate:
 | |
|                     case XD2.WorkflowInstanceManagementService.TransactedUnsuspend:
 | |
|                     case XD2.WorkflowInstanceManagementService.TransactedUpdate:
 | |
|                         EnsureDispatch(operationDescription);
 | |
|                         EnsureTransactedInvoke(operationDescription);
 | |
|                         break;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static void EnsureDispatch(OperationDescription operationDescription)
 | |
|         {
 | |
|             operationDescription.Behaviors.Add(new ControlOperationBehavior(false));
 | |
|         }
 | |
| 
 | |
|         static void EnsureTransactedInvoke(OperationDescription operationDescription)
 | |
|         {
 | |
|             OperationBehaviorAttribute operationAttribute = operationDescription.Behaviors.Find<OperationBehaviorAttribute>();
 | |
|             operationAttribute.TransactionScopeRequired = true;
 | |
|         }
 | |
|     }
 | |
| }
 |