You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.ComponentModel.Design;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
||||
public struct ActivityHandlerDescriptor
|
||||
{
|
||||
[MarshalAs(UnmanagedType.BStr)]
|
||||
public string Name;
|
||||
public int Token;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
//
|
||||
// IMPORTANT: Do not edit this file without consulting Break Safe Synchronization.doc!
|
||||
//
|
||||
internal abstract class BreakSafeBase<T> where T : ICloneable, new()
|
||||
{
|
||||
#region Data members
|
||||
|
||||
private volatile object currentData; // object because type parameters instances cannot be volatile.
|
||||
private T nonEEDataClone;
|
||||
private volatile bool nonEEDataConsistent;
|
||||
private volatile bool nonEEIgnoreUpdate;
|
||||
private Mutex nonEELock;
|
||||
private object controllerUpdateObject;
|
||||
private int controllerManagedThreadId;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods and properties
|
||||
|
||||
protected BreakSafeBase(int controllerManagedThreadId)
|
||||
{
|
||||
this.currentData = new T();
|
||||
this.nonEEDataClone = default(T);
|
||||
this.nonEEDataConsistent = false;
|
||||
this.nonEEIgnoreUpdate = false;
|
||||
this.nonEELock = new Mutex(false);
|
||||
this.controllerManagedThreadId = controllerManagedThreadId;
|
||||
}
|
||||
|
||||
private bool IsEECall
|
||||
{
|
||||
get
|
||||
{
|
||||
return Thread.CurrentThread.ManagedThreadId == this.controllerManagedThreadId;
|
||||
}
|
||||
}
|
||||
|
||||
protected object GetControllerUpdateObject()
|
||||
{
|
||||
return this.controllerUpdateObject;
|
||||
}
|
||||
|
||||
protected void SetControllerUpdateObject(object updateObject)
|
||||
{
|
||||
// Ensure that the access to the variable this.controllerUpdateObject is exactly one instruction - StFld in this case.
|
||||
this.controllerUpdateObject = updateObject;
|
||||
}
|
||||
|
||||
protected T GetReaderData()
|
||||
{
|
||||
// Ensure that the access to the variable this.currentData is exactly one instruction - LdFld in this case.
|
||||
object data = this.currentData;
|
||||
return (T)data;
|
||||
}
|
||||
|
||||
protected T GetWriterData()
|
||||
{
|
||||
if (IsEECall)
|
||||
{
|
||||
if (this.nonEEDataConsistent && this.nonEEIgnoreUpdate == false)
|
||||
{
|
||||
// Modify the object referred to by this.currentData directly.
|
||||
return (T)this.currentData;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clone and discard any non-EE update.
|
||||
this.nonEEIgnoreUpdate = true;
|
||||
return (T)((T)this.currentData).Clone();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset the flag so that we can keep track of any concurrent EE updates.
|
||||
this.nonEEIgnoreUpdate = false;
|
||||
|
||||
// Ensure that the access to the variable this.currentData is exactly one instruction - LdFld in this case.
|
||||
object data = this.currentData;
|
||||
return (T)((T)data).Clone();
|
||||
}
|
||||
}
|
||||
|
||||
protected void SaveData(T data)
|
||||
{
|
||||
if (IsEECall)
|
||||
this.currentData = data;
|
||||
else
|
||||
{
|
||||
// The non-EE clone is now in a consistent state.
|
||||
this.nonEEDataClone = data;
|
||||
this.nonEEDataConsistent = true;
|
||||
|
||||
this.controllerUpdateObject = null;
|
||||
|
||||
// If an EE call has already modified the data, it would have also performed current non-EE update
|
||||
// when the debugger entered break mode. So discard the update. Asl ensure that the access to the
|
||||
// variable this.currentData is exactly one instruction - StFld in this case.
|
||||
if (this.nonEEIgnoreUpdate == false)
|
||||
this.currentData = data;
|
||||
|
||||
// Clear the flag because we will clear the this.nonEEDataClone.
|
||||
this.nonEEDataConsistent = false;
|
||||
this.nonEEDataClone = default(T);
|
||||
}
|
||||
}
|
||||
|
||||
protected void Lock()
|
||||
{
|
||||
// Serialize non-EE calls and do not invoke synchronization primitives during FuncEval.
|
||||
if (!IsEECall)
|
||||
this.nonEELock.WaitOne();
|
||||
}
|
||||
|
||||
protected void Unlock()
|
||||
{
|
||||
// Serialize non-EE calls and do not invoke synchronization primitives during FuncEval.
|
||||
if (!IsEECall)
|
||||
this.nonEELock.ReleaseMutex();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,209 @@
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Globalization;
|
||||
using Microsoft.Win32;
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
internal sealed class DebugControllerThread
|
||||
{
|
||||
#region Data members
|
||||
|
||||
private Thread controllerThread = null;
|
||||
private int threadId = 0;
|
||||
private ManualResetEvent threadInitializedEvent = null;
|
||||
private volatile bool runThread = false;
|
||||
private static readonly string ExpressionEvaluationFrameTypeName = "ExpressionEvaluationFrameTypeName";
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public DebugControllerThread()
|
||||
{
|
||||
this.threadInitializedEvent = new ManualResetEvent(false);
|
||||
this.threadInitializedEvent.Reset();
|
||||
|
||||
this.controllerThread = new Thread(ControllerThreadFunction);
|
||||
this.controllerThread.IsBackground = true;
|
||||
this.controllerThread.Priority = ThreadPriority.Lowest;
|
||||
this.controllerThread.Name = "__dct__";
|
||||
}
|
||||
|
||||
public void RunThread(IInstanceTable instanceTable)
|
||||
{
|
||||
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.DebugControllerThread():"));
|
||||
if (this.controllerThread == null)
|
||||
return;
|
||||
|
||||
this.runThread = true;
|
||||
this.controllerThread.Start(instanceTable);
|
||||
this.threadInitializedEvent.WaitOne();
|
||||
}
|
||||
|
||||
public void StopThread()
|
||||
{
|
||||
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.StopThread():"));
|
||||
|
||||
try
|
||||
{
|
||||
if (this.controllerThread != null)
|
||||
{
|
||||
this.runThread = false;
|
||||
Thread.Sleep(10);
|
||||
|
||||
// On x64 we put the debug controller thread to Sleep(Timeout.Infinite) in
|
||||
// ExpressionEvaluationFunction. This thread needs to be started before it
|
||||
// a Join can execute.
|
||||
if (this.controllerThread.IsAlive && IntPtr.Size == 8)
|
||||
{
|
||||
while (this.controllerThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
|
||||
{
|
||||
this.controllerThread.Start();
|
||||
this.controllerThread.Join();
|
||||
}
|
||||
}
|
||||
else
|
||||
this.controllerThread.Join();
|
||||
}
|
||||
}
|
||||
catch (ThreadStateException)
|
||||
{
|
||||
// Ignore the ThreadStateException which will be thrown when StopThread() is called during
|
||||
// AppDomain unload.
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.controllerThread = null;
|
||||
}
|
||||
|
||||
this.controllerThread = null;
|
||||
this.threadId = 0;
|
||||
this.threadInitializedEvent = null;
|
||||
}
|
||||
|
||||
private void ControllerThreadFunction(object instanceTable)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ControllerThreadFunction():"));
|
||||
|
||||
IExpressionEvaluationFrame expressionEvaluationFrame = null;
|
||||
|
||||
try
|
||||
{
|
||||
RegistryKey debugEngineSubKey = Registry.LocalMachine.OpenSubKey(RegistryKeys.DebuggerSubKey);
|
||||
if (debugEngineSubKey != null)
|
||||
{
|
||||
string evaluationFrameTypeName = debugEngineSubKey.GetValue(ExpressionEvaluationFrameTypeName, String.Empty) as string;
|
||||
if (!String.IsNullOrEmpty(evaluationFrameTypeName) && Type.GetType(evaluationFrameTypeName) != null)
|
||||
expressionEvaluationFrame = Activator.CreateInstance(Type.GetType(evaluationFrameTypeName)) as IExpressionEvaluationFrame;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (expressionEvaluationFrame == null)
|
||||
{
|
||||
Type eeFrameType = null;
|
||||
|
||||
const string eeFrameTypeNameFormat = "Microsoft.Workflow.DebugEngine.ExpressionEvaluationFrame, Microsoft.Workflow.ExpressionEvaluation, Version={0}.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
|
||||
|
||||
// Try versions 12.0.0.0, 11.0.0.0, 10.0.0.0
|
||||
for (int version = 12; eeFrameType == null && version >= 10; --version)
|
||||
{
|
||||
try
|
||||
{
|
||||
eeFrameType = Type.GetType(string.Format(CultureInfo.InvariantCulture, eeFrameTypeNameFormat, version));
|
||||
}
|
||||
catch (TypeLoadException)
|
||||
{
|
||||
// Fall back to next-lower version
|
||||
}
|
||||
}
|
||||
|
||||
if (eeFrameType != null)
|
||||
{
|
||||
expressionEvaluationFrame = Activator.CreateInstance(eeFrameType) as IExpressionEvaluationFrame;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Assert(expressionEvaluationFrame != null, "Failed to create Expression Evaluation Frame.");
|
||||
|
||||
if (expressionEvaluationFrame != null)
|
||||
expressionEvaluationFrame.CreateEvaluationFrame((IInstanceTable)instanceTable, (DebugEngineCallback)Delegate.CreateDelegate(typeof(DebugEngineCallback), this, "ExpressionEvaluationFunction"));
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Don't throw exceptions to the Runtime, it would terminate the debugee.
|
||||
}
|
||||
}
|
||||
|
||||
// This thread spins forever. It is used by the Debug Engine to perform expression evaluation as a "carrier
|
||||
// wave". It is created only when the debugger is attached and terminates itself when the debugger isn't
|
||||
// attached anymore.
|
||||
public void ExpressionEvaluationFunction()
|
||||
{
|
||||
this.threadId = NativeMethods.GetCurrentThreadId();
|
||||
this.threadInitializedEvent.Set();
|
||||
|
||||
|
||||
using (new DebuggerThreadMarker())
|
||||
{
|
||||
// If an exception occurs somehow, continue to spin.
|
||||
while (this.runThread)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Expression eval on x64 does not work (bug 18143) so
|
||||
// don't let the thread spin.
|
||||
if (IntPtr.Size == 8)
|
||||
{
|
||||
Thread.Sleep(Timeout.Infinite);
|
||||
}
|
||||
else
|
||||
// Spin within the try catch.
|
||||
while (this.runThread);
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ExpressionEvaluationFunction(): ThreadAbortException"));
|
||||
|
||||
// Explicitly do not call ResetAbort().
|
||||
throw;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ExpressionEvaluationFunction(): other exception"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public int ThreadId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.threadId;
|
||||
}
|
||||
}
|
||||
|
||||
public int ManagedThreadId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.controllerThread.ManagedThreadId;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Globalization;
|
||||
using Microsoft.Win32;
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
#region Interface IExpressionEvaluationFrame
|
||||
|
||||
public delegate void DebugEngineCallback();
|
||||
|
||||
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
||||
public interface IExpressionEvaluationFrame
|
||||
{
|
||||
void CreateEvaluationFrame(IInstanceTable instanceTable, DebugEngineCallback callback);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Workflow.Runtime;
|
||||
using System.Collections.Generic;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.ComponentModel.Design;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
//
|
||||
// IMPORTANT: Do not edit this file without consulting Break Safe Synchronization.doc!
|
||||
//
|
||||
|
||||
#region interface IInstanceTable
|
||||
|
||||
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
||||
public interface IInstanceTable
|
||||
{
|
||||
Activity GetActivity(string instanceId, string activityName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class InstanceData
|
||||
|
||||
internal sealed class InstanceData : ICloneable
|
||||
{
|
||||
Activity rootActivity;
|
||||
|
||||
public Activity RootActivity
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.rootActivity;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.rootActivity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public InstanceData(Activity rootActivity)
|
||||
{
|
||||
this.rootActivity = rootActivity;
|
||||
}
|
||||
|
||||
object ICloneable.Clone()
|
||||
{
|
||||
InstanceData instanceData = new InstanceData(this.rootActivity);
|
||||
return instanceData;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class InstanceMap : Dictionary<Guid, InstanceData>, ICloneable
|
||||
{
|
||||
object ICloneable.Clone()
|
||||
{
|
||||
InstanceMap data = new InstanceMap();
|
||||
foreach (Guid instsanceId in Keys)
|
||||
data.Add(instsanceId, (InstanceData)(((ICloneable)(this[instsanceId])).Clone()));
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class InstanceTable
|
||||
|
||||
internal sealed class InstanceTable : BreakSafeBase<InstanceMap>, IInstanceTable
|
||||
{
|
||||
public InstanceTable(int controllerManagedThreadId)
|
||||
: base(controllerManagedThreadId)
|
||||
{ }
|
||||
|
||||
// Controller invoked.
|
||||
public void AddInstance(Guid instanceId, Activity rootActivity)
|
||||
{
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
|
||||
InstanceMap instanceMap = GetWriterData();
|
||||
instanceMap[instanceId] = new InstanceData(rootActivity);
|
||||
SaveData(instanceMap);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Controller invoked.
|
||||
public void RemoveInstance(Guid instanceId)
|
||||
{
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
|
||||
InstanceMap instanceMap = GetWriterData();
|
||||
instanceMap.Remove(instanceId);
|
||||
SaveData(instanceMap);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Controller invoked during Dynamic Update notification subscription changes.
|
||||
public Activity GetRootActivity(Guid instanceId)
|
||||
{
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
|
||||
return GetReaderData()[instanceId].RootActivity;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Controller invoked during Dynamic Update notification subscription changes.
|
||||
public void UpdateRootActivity(Guid instanceId, Activity rootActivity)
|
||||
{
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
|
||||
InstanceMap instanceMap = GetWriterData();
|
||||
instanceMap[instanceId].RootActivity = rootActivity;
|
||||
SaveData(instanceMap);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// DE invoked for watches through expression evaluation.
|
||||
Activity IInstanceTable.GetActivity(string instanceId, string activityQualifiedName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
|
||||
|
||||
Activity rootActivity = GetReaderData()[new Guid(instanceId)].RootActivity;
|
||||
return DebuggerHelpers.ParseActivity(rootActivity, activityQualifiedName);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Remoting;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Workflow.Runtime;
|
||||
using System.Workflow.Runtime.Hosting;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Remoting.Channels;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.ComponentModel.Compiler;
|
||||
using System.Workflow.ComponentModel.Design;
|
||||
using System.Workflow.ComponentModel.Serialization;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Configuration;
|
||||
using System.Security.Permissions;
|
||||
using System.Globalization;
|
||||
using Microsoft.Win32;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
#region Interface IWorkflowDebugger
|
||||
|
||||
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
||||
public interface IWorkflowDebugger
|
||||
{
|
||||
void InstanceCreated(Guid programId, Guid instanceId, Guid scheduleTypeId);
|
||||
void InstanceDynamicallyUpdated(Guid programId, Guid instanceId, Guid scheduleTypeId);
|
||||
void InstanceCompleted(Guid programId, Guid instanceId);
|
||||
void BeforeActivityStatusChanged(Guid programId, Guid scheduleTypeId, Guid instanceId, string activityQualifiedName, string hierarchicalActivityId, ActivityExecutionStatus status, int stateReaderId);
|
||||
void ActivityStatusChanged(Guid programId, Guid scheduleTypeId, Guid instanceId, string activityQualifiedName, string hierarchicalActivityId, ActivityExecutionStatus status, int stateReaderId);
|
||||
void SetInitialActivityStatus(Guid programId, Guid scheduleTypeId, Guid instanceId, string activityQualifiedName, string hierarchicalActivityId, ActivityExecutionStatus status, int stateReaderId);
|
||||
void ScheduleTypeLoaded(Guid programId, Guid scheduleTypeId, string assemblyFullName, string fileName, string md5Digest, bool isDynamic, string scheduleNamespace, string scheduleName, string workflowMarkup);
|
||||
void UpdateHandlerMethodsForActivity(Guid programId, Guid scheduleTypeId, string activityQualifiedName, List<ActivityHandlerDescriptor> handlerMethods);
|
||||
void AssemblyLoaded(Guid programId, string assemblyPath, bool fromGlobalAssemblyCache);
|
||||
void HandlerInvoked(Guid programId, Guid instanceId, int threadId, string activityQualifiedName);
|
||||
void BeforeHandlerInvoked(Guid programId, Guid scheduleTypeId, string activityQualifiedName, ActivityHandlerDescriptor handlerMethod);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Workflow.ComponentModel;
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
||||
public interface IWorkflowDebuggerService
|
||||
{
|
||||
void NotifyHandlerInvoking(Delegate delegateHandler);
|
||||
void NotifyHandlerInvoked();
|
||||
}
|
||||
|
||||
internal sealed class WorkflowDebuggerService : IWorkflowDebuggerService
|
||||
{
|
||||
private IWorkflowCoreRuntime coreRuntime;
|
||||
|
||||
internal WorkflowDebuggerService(IWorkflowCoreRuntime coreRuntime)
|
||||
{
|
||||
if (coreRuntime == null)
|
||||
throw new ArgumentNullException("coreRuntime");
|
||||
|
||||
this.coreRuntime = coreRuntime;
|
||||
}
|
||||
|
||||
void IWorkflowDebuggerService.NotifyHandlerInvoking(Delegate delegateHandler)
|
||||
{
|
||||
this.coreRuntime.RaiseHandlerInvoking(delegateHandler);
|
||||
}
|
||||
|
||||
void IWorkflowDebuggerService.NotifyHandlerInvoked()
|
||||
{
|
||||
this.coreRuntime.RaiseHandlerInvoked();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.ComponentModel.Design;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
internal static class NativeMethods
|
||||
{
|
||||
public const int STANDARD_RIGHTS_REQUIRED = (0x000F0000);
|
||||
public const int TOKEN_ASSIGN_PRIMARY = (0x0001);
|
||||
public const int TOKEN_DUPLICATE = (0x0002);
|
||||
public const int TOKEN_IMPERSONATE = (0x0004);
|
||||
public const int TOKEN_QUERY = (0x0008);
|
||||
public const int TOKEN_QUERY_SOURCE = (0x0010);
|
||||
public const int TOKEN_ADJUST_PRIVILEGES = (0x0020);
|
||||
public const int TOKEN_ADJUST_GROUPS = (0x0040);
|
||||
public const int TOKEN_ADJUST_DEFAULT = (0x0080);
|
||||
public const int TOKEN_ADJUST_SESSIONID = (0x0100);
|
||||
|
||||
public const int TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
|
||||
TOKEN_ASSIGN_PRIMARY |
|
||||
TOKEN_DUPLICATE |
|
||||
TOKEN_IMPERSONATE |
|
||||
TOKEN_QUERY |
|
||||
TOKEN_QUERY_SOURCE |
|
||||
TOKEN_ADJUST_PRIVILEGES |
|
||||
TOKEN_ADJUST_GROUPS |
|
||||
TOKEN_ADJUST_DEFAULT);
|
||||
|
||||
[Flags]
|
||||
public enum SECURITY_INFORMATION : uint
|
||||
{
|
||||
OWNER_SECURITY_INFORMATION = 0x00000001,
|
||||
GROUP_SECURITY_INFORMATION = 0x00000002,
|
||||
DACL_SECURITY_INFORMATION = 0x00000004,
|
||||
SACL_SECURITY_INFORMATION = 0x00000008,
|
||||
UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000,
|
||||
UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,
|
||||
PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000,
|
||||
PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum RpcAuthnLevel
|
||||
{
|
||||
Default = 0,
|
||||
None = 1,
|
||||
Connect = 2,
|
||||
Call = 3,
|
||||
Pkt = 4,
|
||||
PktIntegrity = 5,
|
||||
PktPrivacy = 6
|
||||
}
|
||||
|
||||
public enum EoAuthnCap
|
||||
{
|
||||
None = 0x00,
|
||||
MutualAuth = 0x01,
|
||||
StaticCloaking = 0x20,
|
||||
DynamicCloaking = 0x40,
|
||||
AnyAuthority = 0x80,
|
||||
MakeFullSIC = 0x100,
|
||||
Default = 0x800,
|
||||
SecureRefs = 0x02,
|
||||
AccessControl = 0x04,
|
||||
AppID = 0x08,
|
||||
Dynamic = 0x10,
|
||||
RequireFullSIC = 0x200,
|
||||
AutoImpersonate = 0x400,
|
||||
NoCustomMarshal = 0x2000,
|
||||
DisableAAA = 0x1000
|
||||
}
|
||||
|
||||
public enum RpcImpLevel
|
||||
{
|
||||
Default = 0,
|
||||
Anonymous = 1,
|
||||
Identify = 2,
|
||||
Impersonate = 3,
|
||||
Delegate = 4
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = false)]
|
||||
public static extern int GetCurrentThreadId();
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = false)]
|
||||
public static extern IntPtr GetCurrentProcess();
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool RevertToSelf();
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool GetKernelObjectSecurity(IntPtr Handle, SECURITY_INFORMATION RequestedInformation, IntPtr pSecurityDescriptor, UInt32 nLength, out UInt32 lpnLengthNeeded);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool SetKernelObjectSecurity(IntPtr Handle, SECURITY_INFORMATION SecurityInformation, IntPtr SecurityDescriptor);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
}
|
||||
|
||||
internal static class Guids
|
||||
{
|
||||
internal const string CLSID_WDEProgramPublisher = "B6C0E598-314D-4b63-8C5C-4014F2A1B737";
|
||||
public const string IID_IWDEProgramNode = "e5e93adb-a6fe-435e-8640-31ae310d812f";
|
||||
public const string IID_IWDEProgramPublisher = "2BE74789-F70B-42a3-80CA-E91743385844";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
internal sealed class ProgramNode : IWDEProgramNode
|
||||
{
|
||||
private DebugController controller;
|
||||
|
||||
public ProgramNode(DebugController controller)
|
||||
{
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
void IWDEProgramNode.Attach(ref Guid programId, int attachTimeout, int detachPingInterval, out string hostName, out string uri, out int controllerThreadId, out bool isSynchronousAttach)
|
||||
{
|
||||
this.controller.Attach(programId, attachTimeout, detachPingInterval, out hostName, out uri, out controllerThreadId, out isSynchronousAttach);
|
||||
}
|
||||
}
|
||||
|
||||
[ComImport(), Guid(Guids.IID_IWDEProgramNode), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
internal interface IWDEProgramNode
|
||||
{
|
||||
void Attach(ref Guid programId, int attachTimeout, int detachPingInterval, [Out, MarshalAs(UnmanagedType.BStr)] out string hostName, [Out, MarshalAs(UnmanagedType.BStr)] out string uri, [Out] out int controllerThreadId, [Out, MarshalAs(UnmanagedType.Bool)] out bool isSynchronousAttach);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
[ComImport, Guid(Guids.CLSID_WDEProgramPublisher)]
|
||||
internal class WDEProgramPublisher
|
||||
{
|
||||
}
|
||||
|
||||
internal sealed class ProgramPublisher
|
||||
{
|
||||
#region Data members
|
||||
|
||||
private bool isPublished = false;
|
||||
IWDEProgramPublisher publisher;
|
||||
private DebugController controller;
|
||||
GCHandle gchWdeProgramNode; // This is used to pin the wdeProgramNodeSingleton (VS Debugger is using address to calculate cookies)
|
||||
private IWDEProgramNode wdeProgramNodeSingleton;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public ProgramPublisher()
|
||||
{
|
||||
this.publisher = null;
|
||||
}
|
||||
|
||||
public bool Publish(DebugController controller)
|
||||
{
|
||||
Debug.WriteLine("WDE: ProgramPublisher.Publish()");
|
||||
|
||||
// In order to guarantee that the Program Nodes are always in the MTA, publish on a separate thread.
|
||||
if (isPublished)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
this.controller = controller;
|
||||
Thread publisherThread = new Thread(PublisherThreadFunc);
|
||||
publisherThread.SetApartmentState(ApartmentState.MTA);
|
||||
publisherThread.IsBackground = true;
|
||||
publisherThread.Start();
|
||||
publisherThread.Join();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Eat up exceptions if the debugger is not installed.
|
||||
Debug.WriteLine("WDE: ProgramPublisher.Publish() exception: " + e.ToString());
|
||||
}
|
||||
|
||||
return this.isPublished;
|
||||
}
|
||||
|
||||
private void PublisherThreadFunc()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.publisher = new WDEProgramPublisher() as IWDEProgramPublisher;
|
||||
this.wdeProgramNodeSingleton = new ProgramNode(this.controller);
|
||||
this.gchWdeProgramNode = GCHandle.Alloc(this.wdeProgramNodeSingleton);
|
||||
|
||||
this.publisher.Publish(this.wdeProgramNodeSingleton);
|
||||
this.isPublished = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Ignore any exceptions that are caused by WDE.dll not being present or registered.
|
||||
Debug.WriteLine("WDE: ProgramPublisher.PublisherThreadFunc() exception: " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void Unpublish()
|
||||
{
|
||||
if (!isPublished)
|
||||
return;
|
||||
|
||||
Debug.WriteLine("WDE: ProgramPublisher.Unpublish()");
|
||||
|
||||
// In order to guarantee that the Program Nodes are always in the MTA, unpublish on a separate thread.
|
||||
try
|
||||
{
|
||||
Thread unpublisherThread = new Thread(UnpublishThreadFunc);
|
||||
unpublisherThread.SetApartmentState(ApartmentState.MTA);
|
||||
unpublisherThread.IsBackground = true;
|
||||
unpublisherThread.Start();
|
||||
unpublisherThread.Join();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Eat up exceptions if the debugger is not installed, etc.
|
||||
Debug.WriteLine("WDE: ProgramPublisher.Unpublish() exception: " + e.ToString());
|
||||
}
|
||||
|
||||
Debug.WriteLine("WDE: ProgramPublisher.Unpublish() Done");
|
||||
}
|
||||
|
||||
private void UnpublishThreadFunc()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.publisher.Unpublish(this.wdeProgramNodeSingleton);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine("WDE: ProgramPublisher.UnpublishThreadFunc(): catch exception " + e.ToString());
|
||||
// We eat up any exceptions that can occur because the host process is abnormally terminated.
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.gchWdeProgramNode.Free(); // Rrelease pin on the this.wdeProgramNodeSingleton
|
||||
|
||||
Marshal.ReleaseComObject(this.publisher);
|
||||
this.publisher = null;
|
||||
}
|
||||
|
||||
this.isPublished = false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
[ComImport(), Guid(Guids.IID_IWDEProgramPublisher), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
internal interface IWDEProgramPublisher
|
||||
{
|
||||
void Publish([MarshalAs(UnmanagedType.IUnknown)] object ProgramNode);
|
||||
void Unpublish([MarshalAs(UnmanagedType.IUnknown)] object ProgramNode);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
|
||||
namespace System.Workflow.Runtime.DebugEngine
|
||||
{
|
||||
|
||||
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
||||
public enum WorkflowDebuggerSteppingOption
|
||||
{
|
||||
Sequential = 0,
|
||||
Concurrent = 1
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
|
||||
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
||||
public sealed class WorkflowDebuggerSteppingAttribute : Attribute
|
||||
{
|
||||
private WorkflowDebuggerSteppingOption steppingOption;
|
||||
|
||||
public WorkflowDebuggerSteppingAttribute(WorkflowDebuggerSteppingOption steppingOption)
|
||||
{
|
||||
this.steppingOption = steppingOption;
|
||||
}
|
||||
|
||||
public WorkflowDebuggerSteppingOption SteppingOption
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.steppingOption;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user