Update debugger types and thread report handling
This commit is contained in:
parent
3a740d7933
commit
96155736e5
|
@ -9,6 +9,7 @@ using WinDebug = VsChromium.Core.Win32.Debugging;
|
|||
using System.Runtime.InteropServices;
|
||||
using WinLowLevel = LowLevelDesign.Win32.Windows.NativeMethods;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CxbxDebugger
|
||||
{
|
||||
|
@ -32,13 +33,18 @@ namespace CxbxDebugger
|
|||
string[] args = new string[] { };
|
||||
string Target = "";
|
||||
|
||||
public string ProcessName
|
||||
{
|
||||
get { return Target; }
|
||||
}
|
||||
|
||||
RunState State = RunState.NotLaunched;
|
||||
|
||||
DebuggerMessages.DebuggerInit InitParams = new DebuggerMessages.DebuggerInit();
|
||||
|
||||
DebuggerInstance DebugInstance;
|
||||
|
||||
List<IDebuggerGeneralEvents> GeneralEvents = new List<IDebuggerGeneralEvents>();
|
||||
List<IDebuggerSessionEvents> SessionEvents = new List<IDebuggerSessionEvents>();
|
||||
List<IDebuggerProcessEvents> ProcessEvents = new List<IDebuggerProcessEvents>();
|
||||
List<IDebuggerThreadEvents> ThreadEvents = new List<IDebuggerThreadEvents>();
|
||||
List<IDebuggerModuleEvents> ModuleEvents = new List<IDebuggerModuleEvents>();
|
||||
|
@ -103,7 +109,7 @@ namespace CxbxDebugger
|
|||
bpStall.Set();
|
||||
|
||||
// Remove all events
|
||||
GeneralEvents.Clear();
|
||||
SessionEvents.Clear();
|
||||
ProcessEvents.Clear();
|
||||
ThreadEvents.Clear();
|
||||
ModuleEvents.Clear();
|
||||
|
@ -172,6 +178,9 @@ namespace CxbxDebugger
|
|||
if (CanLaunch() == false)
|
||||
throw new Exception("Unable to launch in this state");
|
||||
|
||||
if (args.Length == 0)
|
||||
return false;
|
||||
|
||||
var DebugCreationFlags =
|
||||
WinProcesses.ProcessCreationFlags.DEBUG_ONLY_THIS_PROCESS |
|
||||
WinProcesses.ProcessCreationFlags.CREATE_NEW_CONSOLE;
|
||||
|
@ -197,7 +206,7 @@ namespace CxbxDebugger
|
|||
// Store so they can be marshalled and closed correctly
|
||||
hProcess = new WinProcesses.SafeProcessHandle(stProcessInfo.hProcess);
|
||||
hThread = new WinProcesses.SafeThreadHandle(stProcessInfo.hThread);
|
||||
|
||||
|
||||
bContinue = true;
|
||||
|
||||
State = RunState.Running;
|
||||
|
@ -313,10 +322,7 @@ namespace CxbxDebugger
|
|||
Thread.StartAddress = DebugInfo.lpStartAddress;
|
||||
Thread.ThreadBase = DebugInfo.lpThreadLocalBase;
|
||||
|
||||
foreach (IDebuggerThreadEvents Event in ThreadEvents )
|
||||
{
|
||||
Event.OnThreadCreate(Thread);
|
||||
}
|
||||
Parallel.ForEach(ThreadEvents, Event => Event.OnThreadCreate(Thread));
|
||||
}
|
||||
|
||||
private void HandleExitThread(WinDebug.DEBUG_EVENT DebugEvent)
|
||||
|
@ -333,10 +339,7 @@ namespace CxbxDebugger
|
|||
{
|
||||
uint ExitCode = DebugInfo.dwExitCode;
|
||||
|
||||
foreach (IDebuggerThreadEvents Event in ThreadEvents)
|
||||
{
|
||||
Event.OnThreadExit(TargetThread, ExitCode);
|
||||
}
|
||||
Parallel.ForEach(ThreadEvents, Event => Event.OnThreadExit(TargetThread, ExitCode));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,26 +372,17 @@ namespace CxbxDebugger
|
|||
DebugInstance = new DebuggerInstance(Process);
|
||||
RegisterEventInterfaces(DebugInstance);
|
||||
|
||||
foreach (IDebuggerProcessEvents Event in ProcessEvents)
|
||||
{
|
||||
Event.OnProcessCreate(Process);
|
||||
}
|
||||
Parallel.ForEach(ProcessEvents, Event => Event.OnProcessCreate(Process));
|
||||
|
||||
foreach (IDebuggerThreadEvents Event in ThreadEvents)
|
||||
{
|
||||
Event.OnThreadCreate(MainThread);
|
||||
}
|
||||
|
||||
Parallel.ForEach(ThreadEvents, Event => Event.OnThreadCreate(MainThread));
|
||||
|
||||
var XboxModule = new DebuggerModule();
|
||||
|
||||
XboxModule.Path = Target;
|
||||
XboxModule.ImageBase = DebugInfo.lpBaseOfImage;
|
||||
XboxModule.Core = true;
|
||||
|
||||
foreach (IDebuggerModuleEvents Event in ModuleEvents)
|
||||
{
|
||||
Event.OnModuleLoaded(XboxModule);
|
||||
}
|
||||
Parallel.ForEach(ModuleEvents, Event => Event.OnModuleLoaded(XboxModule));
|
||||
}
|
||||
|
||||
private void HandleExitProcess(WinDebug.DEBUG_EVENT DebugEvent)
|
||||
|
@ -405,10 +399,7 @@ namespace CxbxDebugger
|
|||
|
||||
if (TargetProcess != null)
|
||||
{
|
||||
foreach (IDebuggerProcessEvents Event in ProcessEvents)
|
||||
{
|
||||
Event.OnProcessExit(TargetProcess, ExitCode);
|
||||
}
|
||||
Parallel.ForEach(ProcessEvents, Event => Event.OnProcessExit(TargetProcess, ExitCode));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,10 +417,7 @@ namespace CxbxDebugger
|
|||
Module.Path = ResolveProcessPath(DebugInfo.hFile);
|
||||
Module.ImageBase = DebugInfo.lpBaseOfDll;
|
||||
|
||||
foreach (IDebuggerModuleEvents Event in ModuleEvents)
|
||||
{
|
||||
Event.OnModuleLoaded(Module);
|
||||
}
|
||||
Parallel.ForEach(ModuleEvents, Event => Event.OnModuleLoaded(Module));
|
||||
}
|
||||
|
||||
private void HandleUnloadDll(WinDebug.DEBUG_EVENT DebugEvent)
|
||||
|
@ -445,10 +433,7 @@ namespace CxbxDebugger
|
|||
|
||||
if (TargetModule != null)
|
||||
{
|
||||
foreach (IDebuggerModuleEvents Event in ModuleEvents)
|
||||
{
|
||||
Event.OnModuleUnloaded(TargetModule);
|
||||
}
|
||||
Parallel.ForEach(ModuleEvents, Event => Event.OnModuleUnloaded(TargetModule));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,10 +443,7 @@ namespace CxbxDebugger
|
|||
|
||||
string debugString = ReadProcessString(DebugInfo.lpDebugStringData, DebugInfo.nDebugStringLength, DebugInfo.fUnicode == 1);
|
||||
|
||||
foreach(IDebuggerOutputEvents Event in OutputEvents)
|
||||
{
|
||||
Event.OnDebugOutput(debugString);
|
||||
}
|
||||
Parallel.ForEach(OutputEvents, Event => Event.OnDebugOutput(debugString));
|
||||
}
|
||||
|
||||
private void HandleException(WinDebug.DEBUG_EVENT DebugEvent)
|
||||
|
@ -482,12 +464,28 @@ namespace CxbxDebugger
|
|||
}
|
||||
break;
|
||||
|
||||
case ExceptionCode.PrivilegedInstruction:
|
||||
{
|
||||
// Seeing this frequently called in Win10
|
||||
|
||||
ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_EXCEPTION_NOT_HANDLED;
|
||||
}
|
||||
break;
|
||||
|
||||
case ExceptionCode.StatusHandleNotClosable:
|
||||
{
|
||||
// Seeing this frequently called in Win10
|
||||
|
||||
ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_EXCEPTION_NOT_HANDLED;
|
||||
}
|
||||
break;
|
||||
|
||||
case (ExceptionCode)DebuggerMessages.ReportType.OVERRIDE_EXCEPTION:
|
||||
{
|
||||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Query = DebuggerMessages.GetExceptionHandledQuery(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
|
||||
var Query = DebuggerMessages.GetExceptionHandledQuery(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
|
||||
bool Handled = false;
|
||||
foreach (IDebuggerExceptionEvents Event in ExceptionEvents)
|
||||
|
@ -506,7 +504,7 @@ namespace CxbxDebugger
|
|||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Report = DebuggerMessages.GetHLECacheReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
|
||||
var Report = DebuggerMessages.GetHLECacheReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
SetupHLECacheProvider(Report.FileName);
|
||||
}
|
||||
}
|
||||
|
@ -517,7 +515,7 @@ namespace CxbxDebugger
|
|||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Report = DebuggerMessages.GetKernelPatchReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
|
||||
var Report = DebuggerMessages.GetKernelPatchReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
|
||||
KernelSymbolProvider.AddKernelSymbolFromMessage(Report);
|
||||
}
|
||||
|
@ -529,12 +527,9 @@ namespace CxbxDebugger
|
|||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Report = DebuggerMessages.GetFileOpenedReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
|
||||
var Report = DebuggerMessages.GetFileOpenedReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
|
||||
foreach (IDebuggerFileEvents Event in FileEvents)
|
||||
{
|
||||
Event.OnFileOpened(Report);
|
||||
}
|
||||
Parallel.ForEach(FileEvents, Event => Event.OnFileOpened(Report));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -544,12 +539,9 @@ namespace CxbxDebugger
|
|||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Report = DebuggerMessages.GetFileReadReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
|
||||
var Report = DebuggerMessages.GetFileReadReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
|
||||
foreach (IDebuggerFileEvents Event in FileEvents)
|
||||
{
|
||||
Event.OnFileRead(Report);
|
||||
}
|
||||
Parallel.ForEach(FileEvents, Event => Event.OnFileRead(Report));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -559,12 +551,9 @@ namespace CxbxDebugger
|
|||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Report = DebuggerMessages.GetFileWriteReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
|
||||
var Report = DebuggerMessages.GetFileWriteReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
|
||||
foreach (IDebuggerFileEvents Event in FileEvents)
|
||||
{
|
||||
Event.OnFileWrite(Report);
|
||||
}
|
||||
Parallel.ForEach(FileEvents, Event => Event.OnFileWrite(Report));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -574,13 +563,10 @@ namespace CxbxDebugger
|
|||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Report = DebuggerMessages.GetFileClosedReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
|
||||
var Report = DebuggerMessages.GetFileClosedReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
if (Report != null)
|
||||
{
|
||||
foreach (IDebuggerFileEvents Event in FileEvents)
|
||||
{
|
||||
Event.OnFileClosed(Report);
|
||||
}
|
||||
Parallel.ForEach(FileEvents, Event => Event.OnFileClosed(Report));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -591,14 +577,23 @@ namespace CxbxDebugger
|
|||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Report = DebuggerMessages.GetDebuggerInitReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
|
||||
var Report = DebuggerMessages.GetDebuggerInitReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
|
||||
InitParams = Report;
|
||||
|
||||
foreach (IDebuggerGeneralEvents Event in GeneralEvents)
|
||||
{
|
||||
Event.OnDebugTitleLoaded(InitParams.Title);
|
||||
}
|
||||
Parallel.ForEach(SessionEvents, Event => Event.OnDebugTitleLoaded(InitParams.Title));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case (ExceptionCode)DebuggerMessages.ReportType.DEBUGGER_NEW_TARGET:
|
||||
{
|
||||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Report = DebuggerMessages.GetDebuggerNewTargetReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
|
||||
Parallel.ForEach(SessionEvents, Event => Event.OnDebugTargetChanged(Report.CommandLine));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -608,7 +603,7 @@ namespace CxbxDebugger
|
|||
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
|
||||
if (Thread != null)
|
||||
{
|
||||
var Report = DebuggerMessages.GetMSVCThreadName(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
|
||||
var Report = DebuggerMessages.GetMSVCThreadName(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
|
||||
if(Report != null)
|
||||
{
|
||||
// Resolve the ThreadId of an invalid ID to the current thread name
|
||||
|
@ -623,10 +618,7 @@ namespace CxbxDebugger
|
|||
// Update the resolved thread name
|
||||
ResolvedThread.DebugName = Report.Name;
|
||||
|
||||
foreach (IDebuggerThreadEvents Event in ThreadEvents)
|
||||
{
|
||||
Event.OnThreadNamed(Thread);
|
||||
}
|
||||
Parallel.ForEach(ThreadEvents, Event => Event.OnThreadNamed(Thread));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -644,10 +636,7 @@ namespace CxbxDebugger
|
|||
|
||||
bpStall.Reset();
|
||||
|
||||
foreach (IDebuggerExceptionEvents Event in ExceptionEvents)
|
||||
{
|
||||
Event.OnBreakpoint(Thread, BpAddr, BpCode, FirstChance);
|
||||
}
|
||||
Parallel.ForEach(ExceptionEvents, Event => Event.OnBreakpoint(Thread, BpAddr, BpCode, FirstChance));
|
||||
|
||||
bpStall.WaitOne();
|
||||
}
|
||||
|
@ -674,10 +663,7 @@ namespace CxbxDebugger
|
|||
WinDebug.DEBUG_EVENT DbgEvt = new WinDebug.DEBUG_EVENT();
|
||||
ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_CONTINUE;
|
||||
|
||||
foreach (IDebuggerGeneralEvents Event in GeneralEvents)
|
||||
{
|
||||
Event.OnDebugStart();
|
||||
}
|
||||
Parallel.ForEach(SessionEvents, Event => Event.OnDebugStart());
|
||||
|
||||
// Loop until told to stop
|
||||
while (bContinue == true)
|
||||
|
@ -734,10 +720,7 @@ namespace CxbxDebugger
|
|||
|
||||
State = RunState.Ended;
|
||||
|
||||
foreach (IDebuggerGeneralEvents Event in GeneralEvents)
|
||||
{
|
||||
Event.OnDebugEnd();
|
||||
}
|
||||
Parallel.ForEach(SessionEvents, Event => Event.OnDebugEnd());
|
||||
}
|
||||
|
||||
public DebuggerSymbol ResolveSymbol(uint Address)
|
||||
|
@ -757,8 +740,8 @@ namespace CxbxDebugger
|
|||
|
||||
public void RegisterEventInterfaces(object EventClass)
|
||||
{
|
||||
IDebuggerGeneralEvents GeneralListener = EventClass as IDebuggerGeneralEvents;
|
||||
if(GeneralListener != null ) GeneralEvents.Add(GeneralListener);
|
||||
IDebuggerSessionEvents SessionListener = EventClass as IDebuggerSessionEvents;
|
||||
if(SessionListener != null ) SessionEvents.Add(SessionListener);
|
||||
|
||||
IDebuggerProcessEvents ProcessListener = EventClass as IDebuggerProcessEvents;
|
||||
if (ProcessListener != null) ProcessEvents.Add(ProcessListener);
|
||||
|
|
|
@ -5,11 +5,12 @@ using System;
|
|||
|
||||
namespace CxbxDebugger
|
||||
{
|
||||
public interface IDebuggerGeneralEvents
|
||||
public interface IDebuggerSessionEvents
|
||||
{
|
||||
void OnDebugStart();
|
||||
void OnDebugEnd();
|
||||
void OnDebugTitleLoaded(string Title);
|
||||
void OnDebugTargetChanged(string CommandLine);
|
||||
}
|
||||
|
||||
public interface IDebuggerProcessEvents
|
||||
|
|
|
@ -9,15 +9,20 @@ namespace CxbxDebugger
|
|||
{
|
||||
public enum ReportType : uint
|
||||
{
|
||||
HLECACHE_FILE = 0x00deed00,
|
||||
KERNEL_PATCH = 0x00deed01,
|
||||
FILE_OPENED = 0x00deed02,
|
||||
FILE_READ = 0x00deed03,
|
||||
FILE_CLOSED = 0x00deed04,
|
||||
DEBUGGER_INIT = 0x00deed05,
|
||||
FILE_WRITE = 0x00deed06,
|
||||
HLECACHE_FILE = 0x1000,
|
||||
|
||||
OVERRIDE_EXCEPTION = 0x00ceed01,
|
||||
KERNEL_PATCH = 0x2000,
|
||||
|
||||
FILE_OPENED = 0x3000,
|
||||
|
||||
FILE_READ = 0x3001,
|
||||
FILE_WRITE = 0x3002,
|
||||
FILE_CLOSED = 0x3003,
|
||||
|
||||
DEBUGGER_INIT = 0x400,
|
||||
DEBUGGER_NEW_TARGET = 0x401,
|
||||
|
||||
OVERRIDE_EXCEPTION = 0x500,
|
||||
|
||||
// Exception code from https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
|
||||
MS_VC_EXCEPTION = 0x406D1388,
|
||||
|
@ -29,22 +34,38 @@ namespace CxbxDebugger
|
|||
WCHAR,
|
||||
};
|
||||
|
||||
public class DataProcessor
|
||||
{
|
||||
uint[] SourceData;
|
||||
uint SourceIndex;
|
||||
|
||||
public DataProcessor(uint[] Data)
|
||||
{
|
||||
SourceData = Data;
|
||||
SourceIndex = 0;
|
||||
}
|
||||
|
||||
public uint Pop()
|
||||
{
|
||||
return SourceData[SourceIndex++];
|
||||
}
|
||||
}
|
||||
|
||||
public class HLECache
|
||||
{
|
||||
public string FileName { get; set; }
|
||||
}
|
||||
|
||||
public static HLECache GetHLECacheReport(DebuggerThread Context, uint[] Data)
|
||||
public static HLECache GetHLECacheReport(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
HLECache Report = new HLECache();
|
||||
|
||||
StringType Type = (StringType)Data[0];
|
||||
|
||||
var Type = (StringType)Data.Pop();
|
||||
if (Type != StringType.CHAR)
|
||||
throw new Exception("GetHLECacheReport expects a string message");
|
||||
|
||||
uint Length = Data[1];
|
||||
IntPtr MessagePtr = new IntPtr(Data[2]);
|
||||
var Length = Data.Pop(); ;
|
||||
var MessagePtr = new IntPtr(Data.Pop());
|
||||
|
||||
Report.FileName = Context.OwningProcess.ReadString(MessagePtr, Length);
|
||||
|
||||
|
@ -57,20 +78,19 @@ namespace CxbxDebugger
|
|||
public IntPtr Address { get; set; }
|
||||
}
|
||||
|
||||
public static KernelPatch GetKernelPatchReport(DebuggerThread Context, uint[] Data)
|
||||
public static KernelPatch GetKernelPatchReport(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
KernelPatch Report = new KernelPatch();
|
||||
|
||||
StringType Type = (StringType)Data[0];
|
||||
|
||||
var Type = (StringType)Data.Pop();
|
||||
if (Type != StringType.CHAR)
|
||||
throw new Exception("GetKernelPatchReport expects a string message");
|
||||
|
||||
uint Length = Data[1];
|
||||
IntPtr MessagePtr = new IntPtr(Data[2]);
|
||||
var Length = Data.Pop();
|
||||
var MessagePtr = new IntPtr(Data.Pop());
|
||||
|
||||
Report.Name = Context.OwningProcess.ReadString(MessagePtr, Length);
|
||||
Report.Address = new IntPtr(Data[3]);
|
||||
Report.Address = new IntPtr(Data.Pop());
|
||||
|
||||
return Report;
|
||||
}
|
||||
|
@ -82,23 +102,21 @@ namespace CxbxDebugger
|
|||
public bool Succeeded { get; set; }
|
||||
}
|
||||
|
||||
public static FileOpened GetFileOpenedReport(DebuggerThread Context, uint[] Data)
|
||||
public static FileOpened GetFileOpenedReport(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
FileOpened Report = new FileOpened();
|
||||
|
||||
Report.Handle = new IntPtr(Data[0]);
|
||||
|
||||
StringType Type = (StringType)Data[1];
|
||||
Report.Handle = new IntPtr(Data.Pop());
|
||||
|
||||
var Type = (StringType)Data.Pop();
|
||||
if (Type != StringType.WCHAR)
|
||||
throw new Exception("GetFileOpenedReport expects a widestring message");
|
||||
|
||||
uint Length = Data[2];
|
||||
IntPtr MessagePtr = new IntPtr(Data[3]);
|
||||
var Length = Data.Pop();
|
||||
var MessagePtr = new IntPtr(Data.Pop());
|
||||
|
||||
Report.FileName = Context.OwningProcess.ReadWString(MessagePtr, Length);
|
||||
|
||||
Report.Succeeded = Data[4] != 0;
|
||||
Report.Succeeded = Data.Pop() != 0;
|
||||
|
||||
return Report;
|
||||
}
|
||||
|
@ -110,13 +128,13 @@ namespace CxbxDebugger
|
|||
public uint Offset { get; set; }
|
||||
}
|
||||
|
||||
public static FileRead GetFileReadReport(DebuggerThread Context, uint[] Data)
|
||||
public static FileRead GetFileReadReport(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
FileRead Report = new FileRead();
|
||||
|
||||
Report.Handle = new IntPtr(Data[0]);
|
||||
Report.Length = Data[1];
|
||||
Report.Offset = Data[2];
|
||||
Report.Handle = new IntPtr(Data.Pop());
|
||||
Report.Length = Data.Pop();
|
||||
Report.Offset = Data.Pop();
|
||||
|
||||
return Report;
|
||||
}
|
||||
|
@ -128,13 +146,13 @@ namespace CxbxDebugger
|
|||
public uint Offset { get; set; }
|
||||
}
|
||||
|
||||
public static FileWrite GetFileWriteReport(DebuggerThread Context, uint[] Data)
|
||||
public static FileWrite GetFileWriteReport(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
FileWrite Report = new FileWrite();
|
||||
|
||||
Report.Handle = new IntPtr(Data[0]);
|
||||
Report.Length = Data[1];
|
||||
Report.Offset = Data[2];
|
||||
Report.Handle = new IntPtr(Data.Pop());
|
||||
Report.Length = Data.Pop();
|
||||
Report.Offset = Data.Pop();
|
||||
|
||||
return Report;
|
||||
}
|
||||
|
@ -144,18 +162,20 @@ namespace CxbxDebugger
|
|||
public IntPtr Handle { get; set; }
|
||||
}
|
||||
|
||||
public static FileClosed GetFileClosedReport(DebuggerThread Context, uint[] Data)
|
||||
public static FileClosed GetFileClosedReport(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
// TODO: Restructure this library
|
||||
uint InvalidHandle = (uint)VsChromium.Core.Win32.Handles.NativeMethods.INVALID_HANDLE_VALUE;
|
||||
|
||||
var Handle = Data.Pop();
|
||||
|
||||
// Skip invalid file handles
|
||||
if (Data[0] == InvalidHandle)
|
||||
if (Handle == InvalidHandle)
|
||||
return null;
|
||||
|
||||
FileClosed Report = new FileClosed();
|
||||
|
||||
Report.Handle = new IntPtr(Data[0]);
|
||||
Report.Handle = new IntPtr(Handle);
|
||||
|
||||
return Report;
|
||||
}
|
||||
|
@ -169,59 +189,78 @@ namespace CxbxDebugger
|
|||
public IntPtr ParameterBase { get; set; }
|
||||
}
|
||||
|
||||
public static ExceptionHandledQuery GetExceptionHandledQuery(DebuggerThread Context, uint[] Data)
|
||||
public static ExceptionHandledQuery GetExceptionHandledQuery(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
ExceptionHandledQuery Query = new ExceptionHandledQuery();
|
||||
|
||||
Query.ReponseAddr = new IntPtr(Data[0]);
|
||||
Query.ExceptionAddress = Data[1];
|
||||
Query.ExceptionCode = Data[2];
|
||||
Query.ParameterCount = Data[3];
|
||||
Query.ParameterBase = new IntPtr(Data[4]);
|
||||
Query.ReponseAddr = new IntPtr(Data.Pop());
|
||||
Query.ExceptionAddress = Data.Pop();
|
||||
Query.ExceptionCode = Data.Pop();
|
||||
Query.ParameterCount = Data.Pop();
|
||||
Query.ParameterBase = new IntPtr(Data.Pop());
|
||||
|
||||
return Query;
|
||||
}
|
||||
|
||||
public class DebuggerInit
|
||||
{
|
||||
public uint TitleID { get; set; }
|
||||
public string Title { get; set; }
|
||||
}
|
||||
|
||||
public static DebuggerInit GetDebuggerInitReport(DebuggerThread Context, uint[] Data)
|
||||
public static DebuggerInit GetDebuggerInitReport(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
DebuggerInit Report = new DebuggerInit();
|
||||
|
||||
Report.TitleID = Data[0];
|
||||
|
||||
StringType Type = (StringType)Data[1];
|
||||
StringType Type = (StringType)Data.Pop();
|
||||
|
||||
if (Type != StringType.CHAR)
|
||||
throw new Exception("GetDebuggerInitReport expects a string message");
|
||||
|
||||
uint Length = Data[2];
|
||||
IntPtr MessagePtr = new IntPtr(Data[3]);
|
||||
uint Length = Data.Pop();
|
||||
IntPtr MessagePtr = new IntPtr(Data.Pop());
|
||||
|
||||
Report.Title = Context.OwningProcess.ReadString(MessagePtr, Length);
|
||||
|
||||
return Report;
|
||||
}
|
||||
|
||||
public class DebuggerNewTarget
|
||||
{
|
||||
public string CommandLine { get; set; }
|
||||
}
|
||||
|
||||
public static DebuggerNewTarget GetDebuggerNewTargetReport(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
var Report = new DebuggerNewTarget();
|
||||
|
||||
StringType Type = (StringType)Data.Pop();
|
||||
|
||||
if (Type != StringType.CHAR)
|
||||
throw new Exception("GetDebuggerInitReport expects a string message");
|
||||
|
||||
uint Length = Data.Pop();
|
||||
IntPtr MessagePtr = new IntPtr(Data.Pop());
|
||||
|
||||
Report.CommandLine = Context.OwningProcess.ReadString(MessagePtr, Length);
|
||||
|
||||
return Report;
|
||||
}
|
||||
|
||||
public class MSVCThreadName
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public uint ThreadId { get; set; }
|
||||
}
|
||||
|
||||
public static MSVCThreadName GetMSVCThreadName(DebuggerThread Context, uint[] Data)
|
||||
public static MSVCThreadName GetMSVCThreadName(DebuggerThread Context, DataProcessor Data)
|
||||
{
|
||||
uint Type = Data[0];
|
||||
var Type = Data.Pop();
|
||||
if (Type != 0x1000)
|
||||
return null;
|
||||
|
||||
string ReportName = "";
|
||||
|
||||
IntPtr MessagePtr = new IntPtr(Data[1]);
|
||||
IntPtr MessagePtr = new IntPtr(Data.Pop());
|
||||
if (MessagePtr != IntPtr.Zero)
|
||||
{
|
||||
ReportName = Context.OwningProcess.ReadString(MessagePtr);
|
||||
|
@ -230,7 +269,7 @@ namespace CxbxDebugger
|
|||
MSVCThreadName Report = new MSVCThreadName();
|
||||
|
||||
Report.Name = ReportName;
|
||||
Report.ThreadId = Data[2];
|
||||
Report.ThreadId = Data.Pop();
|
||||
|
||||
return Report;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue