SOS/dotnet-dump extensibility - Part 2 (#1826)
authorMike McLaughlin <mikem@microsoft.com>
Tue, 15 Dec 2020 21:45:52 +0000 (13:45 -0800)
committerGitHub <noreply@github.com>
Tue, 15 Dec 2020 21:45:52 +0000 (13:45 -0800)
* Native SOS clean up and refactoring

Added and updated IHost, ITarget and IRuntime native interfaces and
implementations. Going forward these will be provided by the managed
host support.

Added "runtimes" command and moved the runtime selection options from
sosstatus to this command.

Move include files to common SOS inc directory.

78 files changed:
diagnostics.sln
documentation/design-docs/dotnet-dump-extensibility.md
src/Microsoft.Diagnostics.DebugServices.Implementation/Microsoft.Diagnostics.DebugServices.Implementation.csproj
src/Microsoft.Diagnostics.DebugServices.Implementation/ModuleService.cs
src/Microsoft.Diagnostics.DebugServices.Implementation/ModuleServiceFromDataReader.cs
src/Microsoft.Diagnostics.DebugServices.Implementation/RuntimeService.cs
src/Microsoft.Diagnostics.DebugServices.Implementation/Thread.cs
src/Microsoft.Diagnostics.DebugServices/MemoryServiceExtensions.cs
src/SOS/SOS.Hosting/LLDBServices.cs
src/SOS/SOS.Hosting/SOSHost.cs
src/SOS/SOS.NETCore/SymbolReader.cs
src/SOS/SOS.UnitTests/Scripts/DualRuntimes.script
src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script
src/SOS/Strike/CMakeLists.txt
src/SOS/Strike/EventCallbacks.cpp
src/SOS/Strike/ExpressionNode.cpp
src/SOS/Strike/Strike.vcxproj
src/SOS/Strike/Strike.vcxproj.filters
src/SOS/Strike/cordebugdatatarget.h [deleted file]
src/SOS/Strike/cordebuglibraryprovider.h [deleted file]
src/SOS/Strike/datatarget.cpp [deleted file]
src/SOS/Strike/datatarget.h [deleted file]
src/SOS/Strike/eeheap.cpp
src/SOS/Strike/exts.cpp
src/SOS/Strike/exts.h
src/SOS/Strike/hostcoreclr.cpp
src/SOS/Strike/hostcoreclr.h
src/SOS/Strike/hostdesktop.cpp
src/SOS/Strike/inc/dbgeng.h [deleted file]
src/SOS/Strike/inc/dbghelp.h [deleted file]
src/SOS/Strike/inc/wdbgexts.h [deleted file]
src/SOS/Strike/platform/cordebugdatatarget.h [new file with mode: 0644]
src/SOS/Strike/platform/cordebuglibraryprovider.h [new file with mode: 0644]
src/SOS/Strike/platform/datatarget.cpp [new file with mode: 0644]
src/SOS/Strike/platform/datatarget.h [new file with mode: 0644]
src/SOS/Strike/platform/hostimpl.cpp [new file with mode: 0644]
src/SOS/Strike/platform/hostimpl.h [new file with mode: 0644]
src/SOS/Strike/platform/runtimeimpl.cpp [new file with mode: 0644]
src/SOS/Strike/platform/runtimeimpl.h [new file with mode: 0644]
src/SOS/Strike/platform/targetimpl.cpp [new file with mode: 0644]
src/SOS/Strike/platform/targetimpl.h [new file with mode: 0644]
src/SOS/Strike/runtime.cpp [deleted file]
src/SOS/Strike/runtime.h [deleted file]
src/SOS/Strike/sos.def
src/SOS/Strike/sos_unixexports.src
src/SOS/Strike/sosdocs.txt
src/SOS/Strike/sosdocsunix.txt
src/SOS/Strike/strike.cpp
src/SOS/Strike/strike.h
src/SOS/Strike/util.cpp
src/SOS/Strike/util.h
src/SOS/Strike/xplat/dbgeng.h
src/SOS/dbgutil/dbgutil.vcxproj
src/SOS/debugshim/debugshim.vcxproj
src/SOS/gcdump/gcdump.vcxproj
src/SOS/inc/dbgeng/DbgModel.h [new file with mode: 0644]
src/SOS/inc/dbgeng/dbgeng.h [new file with mode: 0644]
src/SOS/inc/dbgeng/dbghelp.h [new file with mode: 0644]
src/SOS/inc/dbgeng/wdbgexts.h [new file with mode: 0644]
src/SOS/inc/host.h [new file with mode: 0644]
src/SOS/inc/lldbservices.h [new file with mode: 0644]
src/SOS/inc/runtime.h [new file with mode: 0644]
src/SOS/inc/target.h [new file with mode: 0644]
src/SOS/lldbplugin/CMakeLists.txt
src/SOS/lldbplugin/inc/lldbservices.h [deleted file]
src/SOS/lldbplugin/lldbplugin.vcxproj
src/SOS/lldbplugin/lldbplugin.vcxproj.filters
src/SOS/lldbplugin/services.cpp
src/SOS/lldbplugin/services.h
src/SOS/lldbplugin/setsostidcommand.cpp
src/SOS/lldbplugin/soscommand.cpp
src/SOS/lldbplugin/sosplugin.cpp
src/SOS/lldbplugin/sosplugin.h
src/Tools/dotnet-dump/Commands/RuntimesCommand.cs [deleted file]
src/Tools/dotnet-dump/Commands/SOSCommand.cs
src/inc/holder.h [deleted file]
src/inc/releaseholder.h [new file with mode: 0644]
src/inc/stresslog.h

index fea947769cf8876c2f6b05bfc8d6df3fdbe68e51..432bc090327015ceb0d1555689944e6bcc14e16d 100644 (file)
@@ -181,6 +181,22 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StackTracee", "src\tests\St
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.DebugServices.Implementation", "src\Microsoft.Diagnostics.DebugServices.Implementation\Microsoft.Diagnostics.DebugServices.Implementation.csproj", "{1F23F5DA-F766-445F-88FF-86137BDC2709}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "inc", "inc", "{BE45F03E-D700-404F-A890-8ED7D8969958}"
+       ProjectSection(SolutionItems) = preProject
+               src\SOS\inc\host.h = src\SOS\inc\host.h
+               src\SOS\inc\lldbservices.h = src\SOS\inc\lldbservices.h
+               src\SOS\inc\runtime.h = src\SOS\inc\runtime.h
+               src\SOS\inc\target.h = src\SOS\inc\target.h
+       EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dbgeng", "dbgeng", "{7A5421DE-51AC-4521-849E-38479AF08D00}"
+       ProjectSection(SolutionItems) = preProject
+               src\SOS\inc\dbgeng\dbgeng.h = src\SOS\inc\dbgeng\dbgeng.h
+               src\SOS\inc\dbgeng\dbghelp.h = src\SOS\inc\dbgeng\dbghelp.h
+               src\SOS\inc\dbgeng\DbgModel.h = src\SOS\inc\dbgeng\DbgModel.h
+               src\SOS\inc\dbgeng\wdbgexts.h = src\SOS\inc\dbgeng\wdbgexts.h
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Checked|Any CPU = Checked|Any CPU
@@ -1582,6 +1598,8 @@ Global
                {642E6E67-8A84-473D-9507-C302BF10989D} = {B62728C8-1267-4043-B46F-5537BBAEC692}
                {57EB54E7-521A-4CDE-9DAE-8D6AE90A20BB} = {03479E19-3F18-49A6-910A-F5041E27E7C0}
                {1F23F5DA-F766-445F-88FF-86137BDC2709} = {19FAB78C-3351-4911-8F0C-8C6056401740}
+               {BE45F03E-D700-404F-A890-8ED7D8969958} = {41638A4C-0DAF-47ED-A774-ECBBAC0315D7}
+               {7A5421DE-51AC-4521-849E-38479AF08D00} = {BE45F03E-D700-404F-A890-8ED7D8969958}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {46465737-C938-44FC-BE1A-4CE139EBB5E0}
index 75be747ea7f0c8fb8bc5bfb12b51be0efba2a271..f03e9d14e6e5ff03ab72c39bf939030f0a7febd2 100644 (file)
@@ -2,9 +2,9 @@
 
 This document describes a mechanism to allow first and third party users to add custom commands and services to `dotnet-dump` and `SOS` on the supported debuggers. Such extensibility has been a frequent ask from companies like Criteo and some teams at Microsoft. The goal is to write the code for a command once and have it run under all the supported debuggers, including dotnet-dump.
 
-Internally, the ability to host commands like the future "gcheapdiff" under dotnet-dump, lldb and cdb/windbg will be invaluable. The implementation of new commands in C# is faster/more productive for each future command our team needs to add. Other people on .NET team and in the community are more likely to contribute improvements into our tools (similar to what Stephen did with DumpAsync). Unlike the plugin situation, if they contribute directly to our repo then the improvements will automatically flow to all customers and provide broader value.
+Internally, the ability to host commands like the future `gcheapdiff` under dotnet-dump, lldb and cdb/windbg will be invaluable for the productivity of developers in the ecosystem. Implementing new commands and features in C# is far easier and more productive for the interested parties. Other people on .NET team and in the community are more likely to contribute improvements to our tools, similar to what Stephen did with `dumpasync`. Unlike the plugin situation, if they contribute directly to our repo then the improvements will automatically flow to all customers and provide broader value.
 
-This effort is part of the "untified extensiblity" where various teams are coming together to define a common debugger abstraction across all of the debuggers and debugger like hosts (dotnet-dump). Azure Watson could use this infrastructure to write a !analyze like commands and other analysis tools using a very subset of the DAC (as a service) to do some unhandled exception and stack trace triage.
+This effort is part of the "unified extensiblity" models - where various teams are coming together to define a common abstraction across all debuggers and debugger like hosts (dotnet-dump). Services such as Azure Watson could use this infrastructure to write a commands akin to `!analyze` and other analysis tools using a subset of the DAC - provided as a service - to do some unhandled exception and stack trace triage.
 
 ## Goals
 
@@ -22,7 +22,7 @@ This effort is part of the "untified extensiblity" where various teams are comin
  
 ## Customer Value
 
-- Improve our CSS engineer experience by providing commands in Visual Studio that keep them from needed to switch to windbg. 
+- Improve our CSS engineer experience by providing commands in Visual Studio that keep them from needing to switch to windbg. 
     - Commands that CSS devs would find useful in Visual Studio that can't be done in VS any other way:
         - !GCHandles - Provides statistics about GCHandles in the process.
         - !ThreadPool - This command lists basic information about the ThreadPool, including the number of work requests in the queue, number of completion port threads, and number of timers.
@@ -30,8 +30,8 @@ This effort is part of the "untified extensiblity" where various teams are comin
         - rest of list TBD.
         
 - Enables support for Azure Geneva diagnostics which is using the Native AOT corert based runtime. This infrastructure will allow the necessary set of SOS commands to be written and executed across the support platforms (Windows windbg and Linux lldb).
-   
-- Improve our internal .NET team productivity and inner loop development by providing these commands and the native SOS command under Visual Studio. See issue [#1397](https://github.com/dotnet/diagnostics/issues/1397).
+
+- Improve our internal .NET team productivity and inner loop development by providing these managed commands and the classical native SOS commands under debuggers like Visual Studio. See issue [#1397](https://github.com/dotnet/diagnostics/issues/1397).  
       
 - This plan would allow these ClrMD based commands to run across all our debuggers (dotnet-dump, windbg, lldb and Visual Studio):
     - Criteo's 5 or so extension commands:
@@ -118,7 +118,7 @@ The threading model is single-threaded mainly because native debuggers like dbge
 
 ## Hosts
 
-The host is the debugger or program the command and the infrastructure runs. The goal is to allow the same code for a command to run under different programs like the dotnet-dump REPL, the lldb and Windows debuggers. Under Visual Studio the host will be a VS extension package. 
+The host is the debugger or program the command and the infrastructure runs on. The goal is to allow the same code for a command to run under different programs like the dotnet-dump REPL, lldb and Windows debuggers. Under Visual Studio the host will be a VS extension package. 
 
 #### IHost
 
index 0372a0f7f74e22960ff5da610dab9a5274da89b8..349c939f38e98cf8a7cd0d0b5d1abeb5532e8794 100644 (file)
@@ -2,7 +2,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <NoWarn>;1591;1701</NoWarn>
     <Description>Diagnostics debug services</Description>
     <IsPackable>true</IsPackable>
index 3542d906ec5d5b7768a5d7c6ff150b79ecc28948..4e65a452c4aead35b755f523386e0062241be765 100644 (file)
@@ -68,8 +68,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
         /// </summary>
         IEnumerable<IModule> IModuleService.EnumerateModules()
         {
-            GetModules();
-            return _sortedByBaseAddress;
+            return GetSortedModules();
         }
 
         /// <summary>
@@ -111,16 +110,15 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
         /// <returns>module or null</returns>
         IModule IModuleService.GetModuleFromAddress(ulong address)
         {
-            GetModules();
-
             Debug.Assert((address & ~MemoryService.SignExtensionMask()) == 0);
-            int min = 0, max = _sortedByBaseAddress.Length - 1;
+            IModule[] modules = GetSortedModules();
+            int min = 0, max = modules.Length - 1;
 
             // Check if there is a module that contains the address range
             while (min <= max)
             {
                 int mid = (min + max) / 2;
-                IModule module = _sortedByBaseAddress[mid];
+                IModule module = modules[mid];
 
                 ulong start = module.ImageBase;
                 Debug.Assert((start & ~MemoryService.SignExtensionMask()) == 0);
@@ -162,18 +160,30 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
         #endregion
 
         /// <summary>
-        /// Get/create the modules dictionary and sorted array.
+        /// Get/create the modules dictionary.
         /// </summary>
         private Dictionary<ulong, IModule> GetModules()
         {
             if (_modules == null)
             {
                 _modules = GetModulesInner();
-                _sortedByBaseAddress = _modules.OrderBy((pair) => pair.Key).Select((pair) => pair.Value).ToArray();
             }
             return _modules;
         }
 
+        /// <summary>
+        /// Create the sorted array of modules.
+        /// </summary>
+        /// <returns></returns>
+        private IModule[] GetSortedModules()
+        {
+            if (_sortedByBaseAddress == null)
+            {
+                _sortedByBaseAddress = GetModules().OrderBy((pair) => pair.Key).Select((pair) => pair.Value).ToArray();
+            }
+            return _sortedByBaseAddress;
+        }
+
         /// <summary>
         /// Get/create the modules.
         /// </summary>
@@ -210,7 +220,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
         }
 
         /// <summary>
-        /// Returns the PE file's PDB info from the debug directory
+        /// Returns information about the PE file.
         /// </summary>
         /// <param name="isVirtual">the memory layout of the module</param>
         /// <param name="address">module base address</param>
@@ -280,33 +290,32 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
 
             if (!string.IsNullOrEmpty(downloadFilePath))
             {
-                Trace.TraceInformation("GetPEReader: downloading {0}", downloadFilePath);
-                Stream stream = null;
+                Trace.TraceInformation("GetPEReader: downloaded {0}", downloadFilePath);
+                Stream stream;
                 try
                 {
                     stream = File.OpenRead(downloadFilePath);
                 }
                 catch (Exception ex) when (ex is DirectoryNotFoundException || ex is FileNotFoundException || ex is UnauthorizedAccessException || ex is IOException)
                 {
-                    Trace.TraceError($"GetPEReader: exception {ex.Message}");
+                    Trace.TraceError($"GetPEReader: OpenRead exception {ex.Message}");
+                    return null;
                 }
-                if (stream != null)
+                try
                 {
-                    try
+                    reader = new PEReader(stream);
+                    if (reader.PEHeaders == null || reader.PEHeaders.PEHeader == null)
                     {
-                        reader = new PEReader(stream);
-                        if (reader.PEHeaders == null || reader.PEHeaders.PEHeader == null)
-                        {
-                            reader = null;
-                        }
-                    }
-                    catch (Exception ex) when (ex is BadImageFormatException || ex is IOException)
-                    {
-                        Trace.TraceError($"GetPEReader: exception {ex.Message}");
-                        reader = null;
+                        return null;
                     }
                 }
+                catch (Exception ex) when (ex is BadImageFormatException || ex is IOException)
+                {
+                    Trace.TraceError($"GetPEReader: PEReader exception {ex.Message}");
+                    return null;
+                }
             }
+
             return reader;
         }
 
index 8581ae314468e02a3a7c6fdab7d666d5ce92ddf8..8474b638999cdaddff27b01afc3be1f5ff52534a 100644 (file)
@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information.
 
 using Microsoft.Diagnostics.Runtime;
+using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
@@ -104,13 +105,13 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
             foreach (ModuleInfo moduleInfo in _dataReader.EnumerateModules().OrderBy((info) => info.ImageBase))
             {
                 var module = new ModuleFromDataReader(this, moduleIndex, moduleInfo);
-                if (!modules.TryGetValue(moduleInfo.ImageBase, out IModule dup))
+                try
                 {
                     modules.Add(moduleInfo.ImageBase, module);
                 }
-                else
+                catch (ArgumentException)
                 {
-                    Trace.TraceError($"GetModules(): duplicate module base '{module}' dup '{dup}'");
+                    Trace.TraceError($"GetModules(): duplicate module base '{module}' dup '{modules[moduleInfo.ImageBase]}'");
                 }
                 moduleIndex++;
             }
index cfe680b31b8bdc8de53a07ac02640d3543cf04fb..7214374d0941a668fc9bf68e0dbc899a3c11c019 100644 (file)
@@ -204,9 +204,9 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
             return bytesRead;
         }
 
-        unsafe bool IMemoryReader.Read<T>(ulong address, out T value)
+        bool IMemoryReader.Read<T>(ulong address, out T value)
         {
-            Span<byte> buffer = stackalloc byte[sizeof(T)];
+            Span<byte> buffer = stackalloc byte[Marshal.SizeOf<T>()];
             if (((IMemoryReader)this).Read(address, buffer) == buffer.Length)
             {
                 value = Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(buffer));
index bf3f0847d2fbd1fe33245b6b8dad41cc109d79cd..8060c1cc41d2708ce62cc64cf9e78dc398ab5573 100644 (file)
@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information.
 
 using System;
+using System.Runtime.InteropServices;
 
 namespace Microsoft.Diagnostics.DebugServices.Implementation
 {
@@ -38,27 +39,21 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
             {
                 try
                 {
-                    byte[] threadContext = GetThreadContext();
-                    unsafe
+                    Span<byte> threadContext = new Span<byte>(GetThreadContext(), info.RegisterOffset, info.RegisterSize);
+                    switch (info.RegisterSize)
                     {
-                        fixed (byte* ptr = threadContext)
-                        {
-                            switch (info.RegisterSize)
-                            {
-                                case 1:
-                                    value = *((byte*)(ptr + info.RegisterOffset));
-                                    return true;
-                                case 2:
-                                    value = *((ushort*)(ptr + info.RegisterOffset));
-                                    return true;
-                                case 4:
-                                    value = *((uint*)(ptr + info.RegisterOffset));
-                                    return true;
-                                case 8:
-                                    value = *((ulong*)(ptr + info.RegisterOffset));
-                                    return true;
-                            }
-                        }
+                        case 1:
+                            value = MemoryMarshal.Read<byte>(threadContext);
+                            return true;
+                        case 2:
+                            value = MemoryMarshal.Read<ushort>(threadContext);
+                            return true;
+                        case 4:
+                            value = MemoryMarshal.Read<uint>(threadContext);
+                            return true;
+                        case 8:
+                            value = MemoryMarshal.Read<ulong>(threadContext);
+                            return true;
                     }
                 }
                 catch (DiagnosticsException)
index b7d916ad7ec7446f354c835b9f58cc632d0b998f..8ecd85626d4adeadcda3313d8546b791d59bc648 100644 (file)
@@ -69,7 +69,7 @@ namespace Microsoft.Diagnostics.DebugServices
             {
                 if (bytesRead == sizeof(uint))
                 {
-                    value = BitConverter.ToUInt32(buffer.ToArray(), 0);
+                    value = MemoryMarshal.Read<uint>(buffer);
                     return true;
                 }
             }
@@ -93,10 +93,10 @@ namespace Microsoft.Diagnostics.DebugServices
                 switch (pointerSize)
                 {
                     case 4:
-                        value = BitConverter.ToUInt32(buffer.ToArray(), 0);
+                        value = MemoryMarshal.Read<uint>(buffer);
                         return true;
                     case 8:
-                        value = BitConverter.ToUInt64(buffer.ToArray(), 0);
+                        value = MemoryMarshal.Read<ulong>(buffer);
                         return true;
                 }
             }
index 64f6a811bff6122b853899c2a039685577689e0d..0b73fd67dbacf732929c0341aff74b79b1e8612e 100644 (file)
@@ -186,13 +186,17 @@ namespace SOS.Hosting
             IntPtr self,
             uint index,
             ulong *moduleBase,
-            ulong *moduleSize)
+            ulong *moduleSize,
+            uint* timestamp,
+            uint* checksum)
         {
             try
             {
                 IModule module = _soshost.ModuleService.GetModuleFromIndex((int)index);
                 SOSHost.Write(moduleBase, module.ImageBase);
                 SOSHost.Write(moduleSize, module.ImageSize);
+                SOSHost.Write(timestamp, (uint)module.IndexTimeStamp);
+                SOSHost.Write(checksum, 0);
             }
             catch (DiagnosticsException)
             {
@@ -211,7 +215,7 @@ namespace SOS.Hosting
             IntPtr self);
 
         [UnmanagedFunctionPointer(CallingConvention.Winapi)]
-        private delegate UIntPtr GetExpressionDelegate(
+        private delegate ulong GetExpressionDelegate(
             IntPtr self,
             [In][MarshalAs(UnmanagedType.LPStr)] string text);
 
@@ -489,8 +493,10 @@ namespace SOS.Hosting
         private unsafe delegate int GetModuleInfoDelegate(
             IntPtr self,
             [In] uint index,
-            [Out] ulong *moduleBase,
-            [Out] ulong *moduleSize);
+            [Out] ulong* moduleBase,
+            [Out] ulong* moduleSize,
+            [Out] uint* timestamp,
+            [Out] uint* checksum);
 
         [UnmanagedFunctionPointer(CallingConvention.Winapi)]
         private delegate int GetModuleVersionInformationDelegate(
index f14cb034c8604cfc860318361475ecd8ceaa5bf9..1fc9cb79991682d196788ffcddff2d33c635eb1e 100644 (file)
@@ -206,17 +206,17 @@ namespace SOS.Hosting
 
         #region Reverse PInvoke Implementations
 
-        internal static UIntPtr GetExpression(
+        internal static ulong GetExpression(
             string expression)
         {
             if (expression != null)
             {
                 if (ulong.TryParse(expression.Replace("0x", ""), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong result))
                 {
-                    return new UIntPtr(result);
+                    return result;
                 }
             }
-            return UIntPtr.Zero;
+            return 0;
         }
 
         internal int GetInterrupt(
index 8988806c3de0c7ba3e1393799e3bd2b15dd24c9d..7656c0d89e1e0edc4990f12968ad35a84463ad6a 100644 (file)
@@ -247,7 +247,7 @@ namespace SOS
             out IntPtr localVarName);
 
         [UnmanagedFunctionPointer(CallingConvention.Winapi)]
-        public delegate UIntPtr GetExpressionDelegate(
+        public delegate ulong GetExpressionDelegate(
             [In, MarshalAs(UnmanagedType.LPStr)] string expression);
 
         public delegate int GetMetadataLocatorDelegate(
@@ -684,17 +684,17 @@ namespace SOS
         /// </summary>
         /// <param name="expression">hex number</param>
         /// <returns>value</returns>
-        public static UIntPtr GetExpression(
+        public static ulong GetExpression(
             string expression)
         {
             if (expression != null)
             {
                 if (ulong.TryParse(expression.Replace("0x", ""), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong result))
                 {
-                    return new UIntPtr(result);
+                    return result;
                 }
             }
-            return UIntPtr.Zero;
+            return 0;
         }
 
         /// <summary>
index a9448432d2f511d702c984aff41de8cb98185aa8..61c7782d4c1022feed588ab67bb51dcb2475e75e 100644 (file)
@@ -75,8 +75,10 @@ IFDEF:TRIAGE_DUMP
 SOSCOMMAND:setclrpath %DESKTOP_RUNTIME_PATH%
 ENDIF:TRIAGE_DUMP
 
-SOSCOMMAND:SOSStatus -netfx
-VERIFY:\s*Switched to desktop CLR runtime successfully\s+
+SOSCOMMAND:runtimes -netfx
+VERIFY:\s*Switched to desktop .NET Framework runtime successfully\s+
+
+SOSCOMMAND:runtimes
 
 # Currently not on a desktop CLR thread so using the -all option to dump it.
 SOSCOMMAND:ClrStack -all
index 9d8488c44526658091f3bd767b9580894a548c36..d719f8e1d24d3759696b7ad52aa8b1a517bbf63f 100644 (file)
@@ -54,6 +54,7 @@ ENDIF:LIVE
 CONTINUE
 
 SOSCOMMAND:SetSymbolServer -ms
+
 !IFDEF:DOTNETDUMP
 IFDEF:WINDOWS
 SOSCOMMAND:SetHostRuntime
@@ -73,7 +74,16 @@ VERIFY:.*\s+<HEXVAL>\s+<HEXVAL>.*\s+SymbolTestApp\.Program\.Foo4\(System\.String
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Foo2\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 29\]\s*
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Foo1\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 24\]\s*
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Main\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 19\]\s*
-SOSCOMMAND:SetSymbolServer -disable
+
+SOSCOMMAND:runtimes
+!IFDEF:DESKTOP
+VERIFY:.*\.NET Core .*runtime at.*\s+
+ENDIF:DESKTOP
+IFDEF:DESKTOP
+VERIFY:.*\Desktop .NET Framework.*runtime at.*\s+
+ENDIF:DESKTOP
+
+SOSCOMMAND:SOSStatus
 
 # Issue: https://github.com/dotnet/diagnostics/issues/1567
 !IFDEF:ALPINE
@@ -90,6 +100,7 @@ VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.(dll|exe)!SymbolTestApp\.Program\
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.(dll|exe)!SymbolTestApp\.Program\.Foo2\(.*\)\s+\+\s+<DECVAL>\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 29\]\s*
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.(dll|exe)!SymbolTestApp\.Program\.Foo1\(.*\)\s+\+\s+<DECVAL>\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 24\]\s*
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.(dll|exe)!SymbolTestApp\.Program\.Main\(.*\)\s+\+\s+<DECVAL>\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 19\]\s*
+SOSCOMMAND:SetSymbolServer -disable
 
 # Verify that ClrStack all option works (locals/params)
 SOSCOMMAND:ClrStack -a
index 39ba12e9e8897f688a951d98ff922e7cc2ba9125..2ad365910d85475a1aac7f5bb16ae0618fc7333b 100644 (file)
@@ -50,8 +50,10 @@ endif()
 
 add_definitions(-DSTRIKE)  
 
+include_directories(${ROOT_DIR}/src/SOS/inc)
 include_directories(${ROOT_DIR}/src/SOS/gcdump)
 include_directories(${ROOT_DIR}/src/SOS/debugshim)
+include_directories(platform)
 
 if(WIN32)
   include_directories(inc)
@@ -64,7 +66,6 @@ if(WIN32)
 
   set(SOS_SOURCES
     disasm.cpp
-    datatarget.cpp
     dllsext.cpp
     eeheap.cpp
     EventCallbacks.cpp
@@ -74,7 +75,6 @@ if(WIN32)
     gcroot.cpp
     hostcoreclr.cpp
     metadata.cpp
-    runtime.cpp
     sigparser.cpp
     sildasm.cpp
     sos.cpp
@@ -84,6 +84,10 @@ if(WIN32)
     vm.cpp
     WatchCmd.cpp
     Native.rc
+    platform/datatarget.cpp
+    platform/hostimpl.cpp
+    platform/targetimpl.cpp
+    platform/runtimeimpl.cpp
   )
   
   add_definitions(-DFX_VER_INTERNALNAME_STR=SOS.dll)
@@ -129,26 +133,27 @@ else(WIN32)
   add_compile_options(-Wno-format)
 
   include_directories(BEFORE xplat)
-  include_directories(BEFORE ../lldbplugin/inc)
 
   add_compile_options(-fPIC)
 
   set(SOS_SOURCES
     disasm.cpp
-    datatarget.cpp
     eeheap.cpp
     exts.cpp
     gchist.cpp
     gcroot.cpp
     hostcoreclr.cpp
     metadata.cpp
-    runtime.cpp
     sigparser.cpp
     sildasm.cpp
     stressLogDump.cpp
     strike.cpp
     sos.cpp
     util.cpp
+    platform/datatarget.cpp
+    platform/hostimpl.cpp
+    platform/targetimpl.cpp
+    platform/runtimeimpl.cpp
   )
 
   set(DEF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sos_unixexports.src)
index 2c5813af577b5e3cfeb009a8537fe3a0ac58e5ff..7802d07b1a3ddf34cb36e486913426ed4c0a9d88 100644 (file)
@@ -4,26 +4,29 @@
 
 #include "EventCallbacks.h"
 
-EventCallbacks::EventCallbacks(IDebugClient* pDebugClient) : m_refCount(1), m_pDebugClient(pDebugClient)
+EventCallbacks::EventCallbacks(IDebugClient* pDebugClient) : 
+    m_refCount(1),
+    m_pDebugClient(pDebugClient)
 {
+    m_pDebugClient->AddRef();
 }
 
 EventCallbacks::~EventCallbacks()
 {
-    if(m_pDebugClient != NULL)
+    if (m_pDebugClient != NULL)
         m_pDebugClient->Release();
 }
 
-    // IUnknown implementation
+// IUnknown implementation
 HRESULT __stdcall EventCallbacks::QueryInterface(REFIID riid, VOID** ppInterface)
 {
-    if(riid == __uuidof(IDebugEventCallbacks))
+    if (riid == __uuidof(IDebugEventCallbacks))
     {
         *ppInterface = static_cast<IDebugEventCallbacks*>(this);
         AddRef();
         return S_OK;
     }
-    else if(riid == __uuidof(IUnknown))
+    else if (riid == __uuidof(IUnknown))
     {
         *ppInterface = static_cast<IUnknown*>(this);
         AddRef();
@@ -37,13 +40,13 @@ HRESULT __stdcall EventCallbacks::QueryInterface(REFIID riid, VOID** ppInterface
 
 ULONG __stdcall EventCallbacks::AddRef()
 {
-    return InterlockedIncrement((volatile LONG *) &m_refCount);
+    return InterlockedIncrement((volatile LONG*)&m_refCount);
 }
 
 ULONG __stdcall EventCallbacks::Release()
 {
-    ULONG count = InterlockedDecrement((volatile LONG *) &m_refCount);
-    if(count == 0)
+    ULONG count = InterlockedDecrement((volatile LONG*)&m_refCount);
+    if (count == 0)
     {
         delete this;
     }
@@ -105,8 +108,7 @@ HRESULT __stdcall EventCallbacks::Exception(PEXCEPTION_RECORD64 Exception, ULONG
 
 HRESULT __stdcall EventCallbacks::ExitProcess(ULONG ExitCode)
 {
-    Runtime::CleanupRuntimes();
-    CleanupTempDirectory();
+    Target::CleanupTarget();
     return DEBUG_STATUS_NO_CHANGE;
 }
 
index 263fea04aa6a94d2e92d1486ab6cb95431064b8d..850784346a2a6bea776841fa74f165381d482bdb 100644 (file)
@@ -50,10 +50,10 @@ HRESULT ExpressionNode::CreateExpressionNode(__in_z WCHAR* pExpression, Expressi
     *ppExpressionNode = NULL;
 
     HRESULT Status = g_pRuntime->GetCorDebugInterface(&s_pCorDebugProcess);
-    if (FAILED(Status)) 
-    {
+    if (FAILED(Status)) {
         return Status;
     }
+
     Status = CreateExpressionNodeHelper(pExpression,
         pExpression,
         0,
@@ -63,9 +63,9 @@ HRESULT ExpressionNode::CreateExpressionNode(__in_z WCHAR* pExpression, Expressi
         0,
         NULL,
         ppExpressionNode);
-    if(FAILED(Status) && *ppExpressionNode == NULL)
-    {
 
+    if (FAILED(Status) && *ppExpressionNode == NULL)
+    {
         WCHAR pErrorMessage[MAX_ERROR];
         _snwprintf_s(pErrorMessage, MAX_ERROR, _TRUNCATE, L"Error 0x%x while parsing expression", Status);
         *ppExpressionNode = new ExpressionNode(pExpression, pErrorMessage);
index ab8b69636828d0362ea4c0c17a60612efff21484..3c8268df976bc0d71c21ad4bb1f24f91da8f30e1 100644 (file)
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\Strike\Debug\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\Strike\Debug\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">sos.dir\Debug\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">sos</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.dll</TargetExt>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\Strike\Checked\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\Strike\Checked\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">sos.dir\Checked\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">sos</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">.dll</TargetExt>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">false</LinkIncremental>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">false</GenerateManifest>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\Strike\Release\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\Strike\Release\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">sos.dir\Release\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">sos</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.dll</TargetExt>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\Strike\RelWithDebInfo\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\Strike\RelWithDebInfo\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">sos.dir\RelWithDebInfo\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">sos</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">.dll</TargetExt>
@@ -84,7 +84,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\SOS\Strike;..\..\pal\prebuilt\inc;..\..\inc;..\..\SOS\gcdump;..\..\SOS\debugshim;inc;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\DIA SDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\inc;..\..\inc;..\..\pal\prebuilt\inc;..\..\SOS\gcdump;..\..\SOS\debugshim;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\DIA SDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>%(AdditionalOptions) /d2Zi+ /Zm200 /ZH:SHA_256 /source-charset:utf-8 /homeparams</AdditionalOptions>
       <AssemblerListingLocation>Debug/</AssemblerListingLocation>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DataExecutionPrevention>true</DataExecutionPrevention>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
-      <ImportLibrary>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/Debug/sos.lib</ImportLibrary>
+      <ImportLibrary>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/Debug/sos.lib</ImportLibrary>
       <LargeAddressAware>true</LargeAddressAware>
-      <ModuleDefinitionFile>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/sos.def</ModuleDefinitionFile>
-      <ProgramDataBaseFile>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/Debug/sos.pdb</ProgramDataBaseFile>
+      <ModuleDefinitionFile>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/sos.def</ModuleDefinitionFile>
+      <ProgramDataBaseFile>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/Debug/sos.pdb</ProgramDataBaseFile>
       <RandomizedBaseAddress>true</RandomizedBaseAddress>
       <SubSystem>Console</SubSystem>
       <Version>
       <EnableCOMDATFolding>false</EnableCOMDATFolding>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
-      <ImportLibrary>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/Checked/sos.lib</ImportLibrary>
+      <ImportLibrary>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/Checked/sos.lib</ImportLibrary>
       <LargeAddressAware>true</LargeAddressAware>
-      <ModuleDefinitionFile>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/sos.def</ModuleDefinitionFile>
+      <ModuleDefinitionFile>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/sos.def</ModuleDefinitionFile>
       <OptimizeReferences>true</OptimizeReferences>
-      <ProgramDataBaseFile>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/Checked/sos.pdb</ProgramDataBaseFile>
+      <ProgramDataBaseFile>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/Checked/sos.pdb</ProgramDataBaseFile>
       <RandomizedBaseAddress>true</RandomizedBaseAddress>
       <SubSystem>Console</SubSystem>
       <Version>
     </ClCompile>
     <ResourceCompile>
       <PreprocessorDefinitions>WIN32;NDEBUG;URTBLDENV_FRIENDLY=Retail;_AMD64_;_WIN64;AMD64;BIT64=1;_TARGET_64BIT_=1;_TARGET_AMD64_=1;DBG_TARGET_64BIT=1;DBG_TARGET_AMD64=1;DBG_TARGET_WIN64=1;_WIN32;WINVER=0x0602;_WIN32_WINNT=0x0602;WIN32_LEAN_AND_MEAN=1;_CRT_SECURE_NO_WARNINGS;FEATURE_CORESYSTEM;FEATURE_COMINTEROP;FEATURE_HIJACK;_SECURE_SCL=0;_TARGET_WIN64_=1;SOS_TARGET_AMD64=1;SOS_TARGET_ARM64=1;STRIKE;USE_STL;FX_VER_INTERNALNAME_STR=SOS.dll;CMAKE_INTDIR=\"Release\";sos_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\Strike;..\..\SOS\Strike;..\..\pal\prebuilt\inc;..\..\inc;..\..\SOS\gcdump;..\..\SOS\debugshim;inc;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\DIA SDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\Strike;..\..\SOS\Strike;..\..\pal\prebuilt\inc;..\..\inc;..\..\SOS\gcdump;..\..\SOS\debugshim;inc;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\DIA SDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <MASM>
       <PreprocessorDefinitions>NDEBUG;URTBLDENV_FRIENDLY=Retail;_AMD64_;_WIN64;AMD64;BIT64=1;_TARGET_64BIT_=1;_TARGET_AMD64_=1;DBG_TARGET_64BIT=1;DBG_TARGET_AMD64=1;DBG_TARGET_WIN64=1;WIN32;_WIN32;WINVER=0x0602;_WIN32_WINNT=0x0602;WIN32_LEAN_AND_MEAN=1;_CRT_SECURE_NO_WARNINGS;FEATURE_CORESYSTEM;FEATURE_COMINTEROP;FEATURE_HIJACK;_SECURE_SCL=0;_TARGET_WIN64_=1;SOS_TARGET_AMD64=1;SOS_TARGET_ARM64=1;STRIKE;USE_STL;FX_VER_INTERNALNAME_STR=SOS.dll;CMAKE_INTDIR="Release";sos_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <IgnoreSpecificDefaultLibraries>libucrt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
-      <ImportLibrary>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/Release/sos.lib</ImportLibrary>
+      <ImportLibrary>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/Release/sos.lib</ImportLibrary>
       <LargeAddressAware>true</LargeAddressAware>
       <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
-      <ModuleDefinitionFile>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/sos.def</ModuleDefinitionFile>
+      <ModuleDefinitionFile>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/sos.def</ModuleDefinitionFile>
       <OptimizeReferences>true</OptimizeReferences>
-      <ProgramDataBaseFile>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/Release/sos.pdb</ProgramDataBaseFile>
+      <ProgramDataBaseFile>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/Release/sos.pdb</ProgramDataBaseFile>
       <RandomizedBaseAddress>true</RandomizedBaseAddress>
       <SubSystem>Console</SubSystem>
       <Version>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <IgnoreSpecificDefaultLibraries>libucrt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
-      <ImportLibrary>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/RelWithDebInfo/sos.lib</ImportLibrary>
+      <ImportLibrary>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/RelWithDebInfo/sos.lib</ImportLibrary>
       <LargeAddressAware>true</LargeAddressAware>
       <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
       <ModuleDefinitionFile>sos.def</ModuleDefinitionFile>
       <OptimizeReferences>true</OptimizeReferences>
-      <ProgramDataBaseFile>C:/ssd/diagnostics/artifacts/obj/Windows_NT.x64.Debug/src/SOS/Strike/RelWithDebInfo/sos.pdb</ProgramDataBaseFile>
+      <ProgramDataBaseFile>$(ArtifactsObjDir)Windows_NT.x64.Debug/src/SOS/Strike/RelWithDebInfo/sos.pdb</ProgramDataBaseFile>
       <RandomizedBaseAddress>true</RandomizedBaseAddress>
       <SubSystem>Console</SubSystem>
       <Version>
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="disasm.cpp" />
-    <ClCompile Include="datatarget.cpp" />
     <ClCompile Include="dllsext.cpp" />
     <ClCompile Include="eeheap.cpp" />
     <ClCompile Include="EventCallbacks.cpp" />
     <ClCompile Include="gcroot.cpp" />
     <ClCompile Include="hostdesktop.cpp" />
     <ClCompile Include="metadata.cpp" />
-    <ClCompile Include="runtime.cpp" />
+    <ClCompile Include="platform\datatarget.cpp" />
+    <ClCompile Include="platform\hostimpl.cpp" />
+    <ClCompile Include="platform\runtimeimpl.cpp" />
+    <ClCompile Include="platform\targetimpl.cpp" />
     <ClCompile Include="sildasm.cpp" />
     <ClCompile Include="sos.cpp" />
     <ClCompile Include="stressLogDump.cpp" />
     <ClCompile Include="disasmARM64.cpp" />
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="cordebugdatatarget.h" />
-    <ClInclude Include="cordebuglibraryprovider.h" />
     <ClInclude Include="data.h" />
-    <ClInclude Include="datatarget.h" />
     <ClInclude Include="disasm.h" />
     <ClInclude Include="EventCallbacks.h" />
     <ClInclude Include="ExpressionNode.h" />
     <ClInclude Include="exts.h" />
     <ClInclude Include="hostcoreclr.h" />
-    <ClInclude Include="inc\dbgeng.h" />
-    <ClInclude Include="inc\dbghelp.h" />
-    <ClInclude Include="inc\wdbgexts.h" />
     <ClInclude Include="ntinfo.h" />
     <ClInclude Include="platformspecific.h" />
-    <ClInclude Include="runtime.h" />
+    <ClInclude Include="platform\cordebugdatatarget.h" />
+    <ClInclude Include="platform\cordebuglibraryprovider.h" />
+    <ClInclude Include="platform\datatarget.h" />
+    <ClInclude Include="platform\hostimpl.h" />
+    <ClInclude Include="platform\runtimeimpl.h" />
+    <ClInclude Include="platform\targetimpl.h" />
     <ClInclude Include="sos.h" />
     <ClInclude Include="sos_md.h" />
     <ClInclude Include="sos_stacktrace.h" />
index 0b1f0e7aa13e27cb8a05243c86addda8a711539f..087500105965123ef455322c40a7772399424246 100644 (file)
@@ -2,7 +2,6 @@
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <ClCompile Include="disasm.cpp" />
-    <ClCompile Include="datatarget.cpp" />
     <ClCompile Include="dllsext.cpp" />
     <ClCompile Include="eeheap.cpp" />
     <ClCompile Include="EventCallbacks.cpp" />
     <ClCompile Include="disasmX86.cpp" />
     <ClCompile Include="disasmARM64.cpp" />
     <ClCompile Include="hostcoreclr.cpp" />
-    <ClCompile Include="runtime.cpp" />
+    <ClCompile Include="platform\datatarget.cpp">
+      <Filter>platform</Filter>
+    </ClCompile>
+    <ClCompile Include="platform\hostimpl.cpp">
+      <Filter>platform</Filter>
+    </ClCompile>
+    <ClCompile Include="platform\runtimeimpl.cpp">
+      <Filter>platform</Filter>
+    </ClCompile>
+    <ClCompile Include="platform\targetimpl.cpp">
+      <Filter>platform</Filter>
+    </ClCompile>
     <ClCompile Include="hostdesktop.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="data.h" />
-    <ClInclude Include="datatarget.h" />
     <ClInclude Include="disasm.h" />
     <ClInclude Include="EventCallbacks.h" />
     <ClInclude Include="ExpressionNode.h" />
     <ClInclude Include="xplat\wdbgexts.h">
       <Filter>xplat</Filter>
     </ClInclude>
-    <ClInclude Include="inc\dbgeng.h">
-      <Filter>inc</Filter>
+    <ClInclude Include="hostcoreclr.h" />
+    <ClInclude Include="platform\cordebugdatatarget.h">
+      <Filter>platform</Filter>
     </ClInclude>
-    <ClInclude Include="inc\dbghelp.h">
-      <Filter>inc</Filter>
+    <ClInclude Include="platform\cordebuglibraryprovider.h">
+      <Filter>platform</Filter>
     </ClInclude>
-    <ClInclude Include="inc\wdbgexts.h">
-      <Filter>inc</Filter>
+    <ClInclude Include="platform\datatarget.h">
+      <Filter>platform</Filter>
+    </ClInclude>
+    <ClInclude Include="platform\hostimpl.h">
+      <Filter>platform</Filter>
+    </ClInclude>
+    <ClInclude Include="platform\runtimeimpl.h">
+      <Filter>platform</Filter>
+    </ClInclude>
+    <ClInclude Include="platform\targetimpl.h">
+      <Filter>platform</Filter>
     </ClInclude>
-    <ClInclude Include="hostcoreclr.h" />
-    <ClInclude Include="runtime.h" />
-    <ClInclude Include="cordebugdatatarget.h" />
-    <ClInclude Include="cordebuglibraryprovider.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Native.rc" />
@@ -73,8 +88,8 @@
     <Filter Include="xplat">
       <UniqueIdentifier>{b766b3f8-a753-4134-bf7f-50c4f05b59b1}</UniqueIdentifier>
     </Filter>
-    <Filter Include="inc">
-      <UniqueIdentifier>{406edc67-c8c4-4f19-ad39-c799a63f4c2a}</UniqueIdentifier>
+    <Filter Include="platform">
+      <UniqueIdentifier>{8340fe5a-df30-45ca-8a4e-7811ac6ebbd2}</UniqueIdentifier>
     </Filter>
   </ItemGroup>
   <ItemGroup>
diff --git a/src/SOS/Strike/cordebugdatatarget.h b/src/SOS/Strike/cordebugdatatarget.h
deleted file mode 100644 (file)
index 71102d4..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#ifndef __cordebugdatatarget_h__
-#define __cordebugdatatarget_h__
-
-/**********************************************************************\
-* Data target for the debugged process. Provided to OpenVirtualProcess 
-* in order to get an ICorDebugProcess back.
-\**********************************************************************/
-class CorDebugDataTarget : public ICorDebugMutableDataTarget, public ICorDebugMetaDataLocator, public ICorDebugDataTarget4
-{
-public:
-    CorDebugDataTarget() : m_ref(0)
-    {
-    }
-
-    virtual ~CorDebugDataTarget() {}
-
-    virtual HRESULT STDMETHODCALLTYPE QueryInterface(
-        REFIID InterfaceId,
-        PVOID* pInterface)
-    {
-        if (InterfaceId == IID_IUnknown)
-        {
-            *pInterface = static_cast<IUnknown *>(static_cast<ICorDebugDataTarget *>(this));
-        }
-        else if (InterfaceId == IID_ICorDebugDataTarget)
-        {
-            *pInterface = static_cast<ICorDebugDataTarget *>(this);
-        }
-        else if (InterfaceId == IID_ICorDebugMutableDataTarget)
-        {
-            *pInterface = static_cast<ICorDebugMutableDataTarget *>(this);
-        }
-        else if (InterfaceId == IID_ICorDebugMetaDataLocator)
-        {
-            *pInterface = static_cast<ICorDebugMetaDataLocator *>(this);
-        }
-        else if (InterfaceId == IID_ICorDebugDataTarget4)
-        {
-            *pInterface = static_cast<ICorDebugDataTarget4 *>(this);
-        }
-        else
-        {
-            *pInterface = NULL;
-            return E_NOINTERFACE;
-        }
-
-        AddRef();
-        return S_OK;
-    }
-    
-    virtual ULONG STDMETHODCALLTYPE AddRef()
-    {
-        return InterlockedIncrement(&m_ref);    
-    }
-
-    virtual ULONG STDMETHODCALLTYPE Release()
-    {
-        LONG ref = InterlockedDecrement(&m_ref);
-        if (ref == 0)
-        {
-            delete this;
-        }
-        return ref;
-    }
-
-    //
-    // ICorDebugDataTarget.
-    //
-
-    virtual HRESULT STDMETHODCALLTYPE GetPlatform(CorDebugPlatform * pPlatform)
-    {
-        ULONG platformKind = g_targetMachine->GetPlatform();
-        if (IsWindowsTarget())
-        {
-            if (platformKind == IMAGE_FILE_MACHINE_I386)
-                *pPlatform = CORDB_PLATFORM_WINDOWS_X86;
-            else if (platformKind == IMAGE_FILE_MACHINE_AMD64)
-                *pPlatform = CORDB_PLATFORM_WINDOWS_AMD64;
-            else if (platformKind == IMAGE_FILE_MACHINE_ARMNT)
-                *pPlatform = CORDB_PLATFORM_WINDOWS_ARM;
-            else if (platformKind == IMAGE_FILE_MACHINE_ARM64)
-                *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64;
-            else
-                return E_FAIL;
-        }
-        else
-        {
-            if (platformKind == IMAGE_FILE_MACHINE_I386)
-                *pPlatform = CORDB_PLATFORM_POSIX_X86;
-            else if (platformKind == IMAGE_FILE_MACHINE_AMD64)
-                *pPlatform = CORDB_PLATFORM_POSIX_AMD64;
-            else if (platformKind == IMAGE_FILE_MACHINE_ARMNT)
-                *pPlatform = CORDB_PLATFORM_POSIX_ARM;
-            else if (platformKind == IMAGE_FILE_MACHINE_ARM64)
-                *pPlatform = CORDB_PLATFORM_POSIX_ARM64;
-            else
-                return E_FAIL;
-        }
-    
-        return S_OK;
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE ReadVirtual( 
-        CORDB_ADDRESS address,
-        BYTE * pBuffer,
-        ULONG32 request,
-        ULONG32 * pcbRead)
-    {
-        if (g_ExtData == NULL)
-        {
-            return E_UNEXPECTED;
-        }
-#ifdef FEATURE_PAL
-        if (g_sos != nullptr)
-        {
-            // LLDB synthesizes memory (returns 0's) for missing pages (in this case the missing metadata  pages) 
-            // in core dumps. This functions creates a list of the metadata regions and caches the metadata if 
-            // available from the local or downloaded assembly. If the read would be in the metadata of a loaded 
-            // assembly, the metadata from the this cache will be returned.
-            HRESULT hr = GetMetadataMemory(address, request, pBuffer);
-            if (SUCCEEDED(hr)) {
-                if (pcbRead != nullptr) {
-                    *pcbRead = request;
-                }
-                return hr;
-            }
-        }
-#endif
-        HRESULT hr = g_ExtData->ReadVirtual(address, pBuffer, request, (PULONG) pcbRead);
-        if (FAILED(hr)) 
-        {
-            ExtDbgOut("CorDebugDataTarget::ReadVirtual FAILED %08x address %p size %08x\n", hr, address, request);
-        }
-        return hr;
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE GetThreadContext(
-        DWORD dwThreadOSID,
-        ULONG32 contextFlags,
-        ULONG32 contextSize,
-        BYTE * context)
-    {
-        HRESULT hr;
-#ifdef FEATURE_PAL
-        if (g_ExtServices == NULL)
-        {
-            return E_UNEXPECTED;
-        }
-        hr = g_ExtServices->GetThreadContextById(dwThreadOSID, contextFlags, contextSize, context);
-#else
-        ULONG ulThreadIDOrig;
-        ULONG ulThreadIDRequested;
-
-        hr = g_ExtSystem->GetCurrentThreadId(&ulThreadIDOrig);
-        if (FAILED(hr))
-        {
-            return hr;
-        }
-
-        hr = g_ExtSystem->GetThreadIdBySystemId(dwThreadOSID, &ulThreadIDRequested);
-        if (FAILED(hr))
-        {
-            return hr;
-        }
-
-        hr = g_ExtSystem->SetCurrentThreadId(ulThreadIDRequested);
-        if (FAILED(hr))
-        {
-            return hr;
-        }
-
-        // Prepare context structure
-        ZeroMemory(context, contextSize);
-        g_targetMachine->SetContextFlags(context, contextFlags);
-
-        // Ok, do it!
-        hr = g_ExtAdvanced->GetThreadContext((LPVOID) context, contextSize);
-
-        // This is cleanup; failure here doesn't mean GetThreadContext should fail
-        // (that's determined by hr).
-        g_ExtSystem->SetCurrentThreadId(ulThreadIDOrig);
-#endif // FEATURE_PAL
-
-        // GetThreadContext clears ContextFlags or sets them incorrectly and DBI needs it set to know what registers to copy
-        g_targetMachine->SetContextFlags(context, contextFlags);
-
-        return hr;
-    }
-
-    //
-    // ICorDebugMutableDataTarget.
-    //
-
-    virtual HRESULT STDMETHODCALLTYPE WriteVirtual(CORDB_ADDRESS address,
-                                                   const BYTE * pBuffer,
-                                                   ULONG32 bytesRequested)
-    {
-        if (g_ExtData == NULL)
-        {
-            return E_UNEXPECTED;
-        }
-        return g_ExtData->WriteVirtual(address, (PVOID)pBuffer, bytesRequested, NULL);
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE SetThreadContext(DWORD dwThreadID,
-                                                       ULONG32 contextSize,
-                                                       const BYTE * pContext)
-    {
-        return E_NOTIMPL;
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE ContinueStatusChanged(DWORD dwThreadId,
-                                                            CORDB_CONTINUE_STATUS continueStatus)
-    {
-        return E_NOTIMPL;
-    }
-
-    //
-    // ICorDebugMetaDataLocator.
-    //
-
-    virtual HRESULT STDMETHODCALLTYPE GetMetaData(
-        /* [in] */ LPCWSTR wszImagePath,
-        /* [in] */ DWORD dwImageTimeStamp,
-        /* [in] */ DWORD dwImageSize,
-        /* [in] */ ULONG32 cchPathBuffer,
-        /* [annotation][out] */ 
-        _Out_ ULONG32 *pcchPathBuffer,
-        /* [annotation][length_is][size_is][out] */ 
-        _Out_writes_to_(cchPathBuffer, *pcchPathBuffer) WCHAR wszPathBuffer[])
-    {
-        return ::GetICorDebugMetadataLocator(wszImagePath, dwImageTimeStamp, dwImageSize, cchPathBuffer, pcchPathBuffer, wszPathBuffer);
-    }
-
-    //
-    // ICorDebugDataTarget4
-    //
-    virtual HRESULT STDMETHODCALLTYPE VirtualUnwind(DWORD threadId, ULONG32 contextSize, PBYTE context)
-    {
-#ifdef FEATURE_PAL
-        if (g_ExtServices == NULL)
-        {
-            return E_UNEXPECTED;
-        }
-        return g_ExtServices->VirtualUnwind(threadId, contextSize, context);
-#else 
-        return E_NOTIMPL;
-#endif
-    }
-
-protected:
-    LONG m_ref;
-};
-
-#endif // __cordebugdatatarget_h__
diff --git a/src/SOS/Strike/cordebuglibraryprovider.h b/src/SOS/Strike/cordebuglibraryprovider.h
deleted file mode 100644 (file)
index f5eac41..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#ifndef __cordebuglibraryprovider_h__
-#define __cordebuglibraryprovider_h__
-
-#ifndef FEATURE_PAL
-extern HMODULE LoadLibraryAndCheck(PCWSTR filename, DWORD timestamp, DWORD filesize);
-#endif
-
-/**********************************************************************\
- * Provides a way for the public CLR debugging interface to find the 
- * appropriate mscordbi.dll, DAC, etc.
-\**********************************************************************/
-class CorDebugLibraryProvider : public ICLRDebuggingLibraryProvider, ICLRDebuggingLibraryProvider2
-{
-public:
-    CorDebugLibraryProvider(Runtime* pRuntime) :
-        m_ref(0),
-        m_pRuntime(pRuntime)
-    {
-    }
-
-    virtual ~CorDebugLibraryProvider() {}
-
-    virtual HRESULT STDMETHODCALLTYPE QueryInterface(
-        REFIID InterfaceId,
-        PVOID* pInterface)
-    {
-        if (InterfaceId == IID_IUnknown)
-        {
-            *pInterface = static_cast<IUnknown *>(static_cast<ICLRDebuggingLibraryProvider*>(this));
-        }
-#ifndef FEATURE_PAL
-        else if (InterfaceId == IID_ICLRDebuggingLibraryProvider)
-        {
-            *pInterface = static_cast<ICLRDebuggingLibraryProvider *>(this);
-        }
-#endif
-        else if (InterfaceId == IID_ICLRDebuggingLibraryProvider2)
-        {
-            *pInterface = static_cast<ICLRDebuggingLibraryProvider2 *>(this);
-        }
-        else
-        {
-            *pInterface = NULL;
-            return E_NOINTERFACE;
-        }
-
-        AddRef();
-        return S_OK;
-    }
-    
-    virtual ULONG STDMETHODCALLTYPE AddRef()
-    {
-        return InterlockedIncrement(&m_ref);    
-    }
-
-    virtual ULONG STDMETHODCALLTYPE Release()
-    {
-        LONG ref = InterlockedDecrement(&m_ref);
-        if (ref == 0)
-        {
-            delete this;
-        }
-        return ref;
-    }
-
-    HRESULT ProvideLibraryInternal(
-        const WCHAR* pwszFileName,
-        DWORD dwTimestamp,
-        DWORD dwSizeOfImage,
-        HMODULE* phModule,
-        LPWSTR* ppResolvedModulePath)
-    {
-        const char* filePath = nullptr;
-
-        if (_wcsncmp(pwszFileName, m_pRuntime->GetDacDllNameW(), _wcslen(m_pRuntime->GetDacDllNameW())) == 0)
-        {
-            filePath = m_pRuntime->GetDacFilePath();
-        }
-        else if (_wcsncmp(pwszFileName, NET_DBI_DLL_NAME_W, _wcslen(NET_DBI_DLL_NAME_W)) == 0)
-        {
-            filePath = m_pRuntime->GetDbiFilePath();
-        }
-
-        ArrayHolder<WCHAR> modulePath = new WCHAR[MAX_LONGPATH + 1];
-        if (filePath != nullptr)
-        {
-            int length = MultiByteToWideChar(CP_ACP, 0, filePath, -1, modulePath, MAX_LONGPATH);
-            if (0 >= length)
-            {
-                ExtErr("MultiByteToWideChar(filePath) failed. Last error = 0x%x\n", GetLastError());
-                return HRESULT_FROM_WIN32(GetLastError());
-            }
-        }
-        else
-        {
-            LPCSTR runtimeDirectory = m_pRuntime->GetRuntimeDirectory();
-            if (runtimeDirectory == nullptr)
-            {
-                ExtErr("Runtime not loaded\n");
-                return E_FAIL;
-            }
-            int length = MultiByteToWideChar(CP_ACP, 0, runtimeDirectory, -1, modulePath, MAX_LONGPATH);
-            if (0 >= length)
-            {
-                ExtErr("MultiByteToWideChar(runtimeDirectory) failed. Last error = 0x%x\n", GetLastError());
-                return HRESULT_FROM_WIN32(GetLastError());
-            }
-            wcscat_s(modulePath, MAX_LONGPATH, pwszFileName);
-        }
-
-        ExtOut("Loaded %S\n", modulePath.GetPtr());
-
-#ifndef FEATURE_PAL
-        if (phModule != NULL)
-        {
-            *phModule = LoadLibraryAndCheck(modulePath.GetPtr(), dwTimestamp, dwSizeOfImage);
-        }
-#endif
-        if (ppResolvedModulePath != NULL)
-        {
-            *ppResolvedModulePath = modulePath.Detach();
-        }
-        return S_OK;
-    }
-
-    // Called by the shim to locate and load dac and dbi
-    // Parameters:
-    //    pwszFileName - the name of the file to load
-    //    dwTimestamp - the expected timestamp of the file
-    //    dwSizeOfImage - the expected SizeOfImage (a PE header data value)
-    //    phModule - a handle to loaded module
-    //
-    // Return Value
-    //    S_OK if the file was loaded, or any error if not
-    virtual HRESULT STDMETHODCALLTYPE ProvideLibrary(
-        const WCHAR * pwszFileName,
-        DWORD dwTimestamp,
-        DWORD dwSizeOfImage,
-        HMODULE* phModule)
-    {
-        if ((phModule == NULL) || (pwszFileName == NULL))
-        {
-            return E_INVALIDARG;
-        }
-        return ProvideLibraryInternal(pwszFileName, dwTimestamp, dwSizeOfImage, phModule, NULL);
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE ProvideLibrary2(
-        const WCHAR* pwszFileName,
-        DWORD dwTimestamp,
-        DWORD dwSizeOfImage,
-        LPWSTR* ppResolvedModulePath)
-    {
-        if ((pwszFileName == NULL) || (ppResolvedModulePath == NULL))
-        {
-            return E_INVALIDARG;
-        }
-        return ProvideLibraryInternal(pwszFileName, dwTimestamp, dwSizeOfImage, NULL, ppResolvedModulePath);
-    }
-
-protected:
-    LONG m_ref;
-    Runtime* m_pRuntime;
-};
-
-#endif // __cordebuglibraryprovider_h__
diff --git a/src/SOS/Strike/datatarget.cpp b/src/SOS/Strike/datatarget.cpp
deleted file mode 100644 (file)
index f6fd547..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#include "sos.h"
-#include "datatarget.h"
-#include "corhdr.h"
-#include "cor.h"
-#include "dacprivate.h"
-#include "sospriv.h"
-#include "corerror.h"
-
-#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
-
-DataTarget::DataTarget(ULONG64 baseAddress) :
-    m_ref(0),
-    m_baseAddress(baseAddress)
-{
-}
-
-STDMETHODIMP
-DataTarget::QueryInterface(
-    THIS_
-    ___in REFIID InterfaceId,
-    ___out PVOID* Interface
-    )
-{
-    if (InterfaceId == IID_IUnknown ||
-        InterfaceId == IID_ICLRDataTarget)
-    {
-        *Interface = (ICLRDataTarget*)this;
-        AddRef();
-        return S_OK;
-    }
-    else if (InterfaceId == IID_ICLRDataTarget2)
-    {
-        *Interface = (ICLRDataTarget2*)this;
-        AddRef();
-        return S_OK;
-    }
-    else if (InterfaceId == IID_ICorDebugDataTarget4)
-    {
-        *Interface = (ICorDebugDataTarget4*)this;
-        AddRef();
-        return S_OK;
-    }
-    else if (InterfaceId == IID_ICLRMetadataLocator)
-    {
-        *Interface = (ICLRMetadataLocator*)this;
-        AddRef();
-        return S_OK;
-    }
-    else if (InterfaceId == IID_ICLRRuntimeLocator)
-    {
-        *Interface = (ICLRRuntimeLocator*)this;
-        AddRef();
-        return S_OK;
-    }
-    else
-    {
-        *Interface = NULL;
-        return E_NOINTERFACE;
-    }
-}
-
-STDMETHODIMP_(ULONG)
-DataTarget::AddRef(
-    THIS
-    )
-{
-    LONG ref = InterlockedIncrement(&m_ref);    
-    return ref;
-}
-
-STDMETHODIMP_(ULONG)
-DataTarget::Release(
-    THIS
-    )
-{
-    LONG ref = InterlockedDecrement(&m_ref);
-    if (ref == 0)
-    {
-        delete this;
-    }
-    return ref;
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::GetMachineType(
-    /* [out] */ ULONG32 *machine)
-{
-    if (g_ExtControl == NULL)
-    {
-        return E_UNEXPECTED;
-    }
-    return g_ExtControl->GetExecutingProcessorType((PULONG)machine);
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::GetPointerSize(
-    /* [out] */ ULONG32 *size)
-{
-#if defined(SOS_TARGET_AMD64) || defined(SOS_TARGET_ARM64) || defined(SOS_TARGET_MIPS64)
-    *size = 8;
-#elif defined(SOS_TARGET_ARM) || defined(SOS_TARGET_X86)
-    *size = 4;
-#else
-  #error Unsupported architecture
-#endif
-
-    return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::GetImageBase(
-    /* [string][in] */ LPCWSTR name,
-    /* [out] */ CLRDATA_ADDRESS *base)
-{
-    if (g_ExtSymbols == NULL)
-    {
-        return E_UNEXPECTED;
-    }
-    CHAR lpstr[MAX_LONGPATH];
-    int name_length = WideCharToMultiByte(CP_ACP, 0, name, -1, lpstr, MAX_LONGPATH, NULL, NULL);
-    if (name_length == 0)
-    {
-        return E_FAIL;
-    }
-#ifndef FEATURE_PAL
-    // Remove the extension on Windows/dbgeng.
-    CHAR *lp = strrchr(lpstr, '.');
-    if (lp != nullptr)
-    {
-        *lp = '\0';
-    }
-#endif
-    return g_ExtSymbols->GetModuleByModuleName(lpstr, 0, NULL, base);
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::ReadVirtual(
-    /* [in] */ CLRDATA_ADDRESS address,
-    /* [length_is][size_is][out] */ PBYTE buffer,
-    /* [in] */ ULONG32 request,
-    /* [optional][out] */ ULONG32 *done)
-{
-    if (g_ExtData == NULL)
-    {
-        return E_UNEXPECTED;
-    }
-#ifdef FEATURE_PAL
-    if (g_sos != nullptr)
-    {
-        // LLDB synthesizes memory (returns 0's) for missing pages (in this case the missing metadata  pages) 
-        // in core dumps. This functions creates a list of the metadata regions and caches the metadata if 
-        // available from the local or downloaded assembly. If the read would be in the metadata of a loaded 
-        // assembly, the metadata from the this cache will be returned.
-        HRESULT hr = GetMetadataMemory(address, request, buffer);
-        if (SUCCEEDED(hr)) {
-            if (done != nullptr) {
-                *done = request;
-            }
-            return hr;
-        }
-    }
-#endif
-    HRESULT hr = g_ExtData->ReadVirtual(address, (PVOID)buffer, request, (PULONG)done);
-    if (FAILED(hr)) 
-    {
-        ExtDbgOut("DataTarget::ReadVirtual FAILED %08x address %08llx size %08x\n", hr, address, request);
-    }
-    return hr;
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::WriteVirtual(
-    /* [in] */ CLRDATA_ADDRESS address,
-    /* [size_is][in] */ PBYTE buffer,
-    /* [in] */ ULONG32 request,
-    /* [optional][out] */ ULONG32 *done)
-{
-    if (g_ExtData == NULL)
-    {
-        return E_UNEXPECTED;
-    }
-    return g_ExtData->WriteVirtual(address, (PVOID)buffer, request, (PULONG)done);
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::GetTLSValue(
-    /* [in] */ ULONG32 threadID,
-    /* [in] */ ULONG32 index,
-    /* [out] */ CLRDATA_ADDRESS* value)
-{
-    return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::SetTLSValue(
-    /* [in] */ ULONG32 threadID,
-    /* [in] */ ULONG32 index,
-    /* [in] */ CLRDATA_ADDRESS value)
-{
-    return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::GetCurrentThreadID(
-    /* [out] */ ULONG32 *threadID)
-{
-    if (g_ExtSystem == NULL)
-    {
-        return E_UNEXPECTED;
-    }
-    return g_ExtSystem->GetCurrentThreadSystemId((PULONG)threadID);
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::GetThreadContext(
-    /* [in] */ ULONG32 threadID,
-    /* [in] */ ULONG32 contextFlags,
-    /* [in] */ ULONG32 contextSize,
-    /* [out, size_is(contextSize)] */ PBYTE context)
-{
-    HRESULT hr;
-#ifdef FEATURE_PAL
-    if (g_ExtServices == NULL)
-    {
-        return E_UNEXPECTED;
-    }
-    hr = g_ExtServices->GetThreadContextById(threadID, contextFlags, contextSize, context);
-#else
-    if (g_ExtSystem == NULL || g_ExtAdvanced == NULL)
-    {
-        return E_UNEXPECTED;
-    }
-    ULONG ulThreadIDOrig;
-    ULONG ulThreadIDRequested;
-
-    hr = g_ExtSystem->GetCurrentThreadId(&ulThreadIDOrig);
-    if (FAILED(hr))
-    {
-        return hr;
-    }
-
-    hr = g_ExtSystem->GetThreadIdBySystemId(threadID, &ulThreadIDRequested);
-    if (FAILED(hr))
-    {
-        return hr;
-    }
-
-    hr = g_ExtSystem->SetCurrentThreadId(ulThreadIDRequested);
-    if (FAILED(hr))
-    {
-        return hr;
-    }
-
-    // Prepare context structure
-    ZeroMemory(context, contextSize);
-    g_targetMachine->SetContextFlags(context, contextFlags);
-
-    // Ok, do it!
-    hr = g_ExtAdvanced->GetThreadContext((LPVOID) context, contextSize);
-
-    // This is cleanup; failure here doesn't mean GetThreadContext should fail
-    // (that's determined by hr).
-    g_ExtSystem->SetCurrentThreadId(ulThreadIDOrig);
-#endif
-
-    // GetThreadContext clears ContextFlags or sets them incorrectly and DBI needs it set to know what registers to copy
-    g_targetMachine->SetContextFlags(context, contextFlags);
-
-    return hr;
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::SetThreadContext(
-    /* [in] */ ULONG32 threadID,
-    /* [in] */ ULONG32 contextSize,
-    /* [out, size_is(contextSize)] */ PBYTE context)
-{
-    return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::Request(
-    /* [in] */ ULONG32 reqCode,
-    /* [in] */ ULONG32 inBufferSize,
-    /* [size_is][in] */ BYTE *inBuffer,
-    /* [in] */ ULONG32 outBufferSize,
-    /* [size_is][out] */ BYTE *outBuffer)
-{
-    return E_NOTIMPL;
-}
-
-// ICLRDataTarget2
-
-HRESULT STDMETHODCALLTYPE 
-DataTarget::AllocVirtual(
-    /* [in] */ CLRDATA_ADDRESS addr,
-    /* [in] */ ULONG32 size,
-    /* [in] */ ULONG32 typeFlags,
-    /* [in] */ ULONG32 protectFlags,
-    /* [out] */ CLRDATA_ADDRESS* virt)
-{
-#ifdef FEATURE_PAL
-    return E_NOTIMPL;
-#else
-    ULONG64 hProcess;
-    HRESULT hr = g_ExtSystem->GetCurrentProcessHandle(&hProcess);
-    if (FAILED(hr)) {
-        return hr;
-    }
-    LPVOID allocation = ::VirtualAllocEx((HANDLE)hProcess, (LPVOID)addr, size, typeFlags, protectFlags);
-    if (allocation == NULL) {
-        return HRESULT_FROM_WIN32(::GetLastError());
-    }
-    *virt = (CLRDATA_ADDRESS)allocation;
-    return S_OK;
-#endif
-}
-        
-HRESULT STDMETHODCALLTYPE 
-DataTarget::FreeVirtual(
-    /* [in] */ CLRDATA_ADDRESS addr,
-    /* [in] */ ULONG32 size,
-    /* [in] */ ULONG32 typeFlags)
-{
-#ifdef FEATURE_PAL
-    return E_NOTIMPL;
-#else
-    ULONG64 hProcess;
-    HRESULT hr = g_ExtSystem->GetCurrentProcessHandle(&hProcess);
-    if (FAILED(hr)) {
-        return hr;
-    }
-    ::VirtualFreeEx((HANDLE)hProcess, (LPVOID)addr, size, typeFlags);
-    return S_OK;
-#endif
-}
-
-// ICorDebugDataTarget4
-
-HRESULT STDMETHODCALLTYPE 
-DataTarget::VirtualUnwind(
-    /* [in] */ DWORD threadId,
-    /* [in] */ ULONG32 contextSize,
-    /* [in, out, size_is(contextSize)] */ PBYTE context)
-{
-#ifdef FEATURE_PAL
-    if (g_ExtServices == NULL)
-    {
-        return E_UNEXPECTED;
-    }
-    return g_ExtServices->VirtualUnwind(threadId, contextSize, context);
-#else
-    return E_NOTIMPL;
-#endif
-}
-
-// ICLRMetadataLocator
-
-HRESULT STDMETHODCALLTYPE
-DataTarget::GetMetadata(
-    /* [in] */ LPCWSTR imagePath,
-    /* [in] */ ULONG32 imageTimestamp,
-    /* [in] */ ULONG32 imageSize,
-    /* [in] */ GUID* mvid,
-    /* [in] */ ULONG32 mdRva,
-    /* [in] */ ULONG32 flags,
-    /* [in] */ ULONG32 bufferSize,
-    /* [out, size_is(bufferSize), length_is(*dataSize)] */
-    BYTE* buffer,
-    /* [out] */ ULONG32* dataSize)
-{
-    return ::GetMetadataLocator(imagePath, imageTimestamp, imageSize, mvid, mdRva, flags, bufferSize, buffer, dataSize);
-}
-
-// ICLRRuntimeLocator
-
-HRESULT STDMETHODCALLTYPE 
-DataTarget::GetRuntimeBase(
-    /* [out] */ CLRDATA_ADDRESS* baseAddress)
-{
-    *baseAddress = m_baseAddress;
-    return S_OK;
-}
-
diff --git a/src/SOS/Strike/datatarget.h b/src/SOS/Strike/datatarget.h
deleted file mode 100644 (file)
index 69ffb94..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-class DataTarget : public ICLRDataTarget2, ICorDebugDataTarget4, ICLRMetadataLocator, ICLRRuntimeLocator
-{
-private:
-    LONG m_ref;                         // Reference count.
-    ULONG64 m_baseAddress;              // Runtime base address
-
-public:
-    DataTarget(ULONG64 baseAddress);
-    virtual ~DataTarget() {}
-    
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        ___in REFIID InterfaceId,
-        ___out PVOID* Interface
-        );
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        );
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        );
-
-    //
-    // ICLRDataTarget.
-    //
-    
-    virtual HRESULT STDMETHODCALLTYPE GetMachineType( 
-        /* [out] */ ULONG32 *machine);
-
-    virtual HRESULT STDMETHODCALLTYPE GetPointerSize( 
-        /* [out] */ ULONG32 *size);
-
-    virtual HRESULT STDMETHODCALLTYPE GetImageBase( 
-        /* [string][in] */ LPCWSTR name,
-        /* [out] */ CLRDATA_ADDRESS *base);
-
-    virtual HRESULT STDMETHODCALLTYPE ReadVirtual( 
-        /* [in] */ CLRDATA_ADDRESS address,
-        /* [length_is][size_is][out] */ PBYTE buffer,
-        /* [in] */ ULONG32 request,
-        /* [optional][out] */ ULONG32 *done);
-
-    virtual HRESULT STDMETHODCALLTYPE WriteVirtual( 
-        /* [in] */ CLRDATA_ADDRESS address,
-        /* [size_is][in] */ PBYTE buffer,
-        /* [in] */ ULONG32 request,
-        /* [optional][out] */ ULONG32 *done);
-
-    virtual HRESULT STDMETHODCALLTYPE GetTLSValue(
-        /* [in] */ ULONG32 threadID,
-        /* [in] */ ULONG32 index,
-        /* [out] */ CLRDATA_ADDRESS* value);
-
-    virtual HRESULT STDMETHODCALLTYPE SetTLSValue(
-        /* [in] */ ULONG32 threadID,
-        /* [in] */ ULONG32 index,
-        /* [in] */ CLRDATA_ADDRESS value);
-
-    virtual HRESULT STDMETHODCALLTYPE GetCurrentThreadID(
-        /* [out] */ ULONG32* threadID);
-
-    virtual HRESULT STDMETHODCALLTYPE GetThreadContext(
-        /* [in] */ ULONG32 threadID,
-        /* [in] */ ULONG32 contextFlags,
-        /* [in] */ ULONG32 contextSize,
-        /* [out, size_is(contextSize)] */ PBYTE context);
-
-    virtual HRESULT STDMETHODCALLTYPE SetThreadContext(
-        /* [in] */ ULONG32 threadID,
-        /* [in] */ ULONG32 contextSize,
-        /* [in, size_is(contextSize)] */ PBYTE context);
-
-    virtual HRESULT STDMETHODCALLTYPE Request( 
-        /* [in] */ ULONG32 reqCode,
-        /* [in] */ ULONG32 inBufferSize,
-        /* [size_is][in] */ BYTE *inBuffer,
-        /* [in] */ ULONG32 outBufferSize,
-        /* [size_is][out] */ BYTE *outBuffer);
-
-    // ICLRDataTarget2
-
-    virtual HRESULT STDMETHODCALLTYPE AllocVirtual( 
-            /* [in] */ CLRDATA_ADDRESS addr,
-            /* [in] */ ULONG32 size,
-            /* [in] */ ULONG32 typeFlags,
-            /* [in] */ ULONG32 protectFlags,
-            /* [out] */ CLRDATA_ADDRESS *virt);
-        
-    virtual HRESULT STDMETHODCALLTYPE FreeVirtual( 
-            /* [in] */ CLRDATA_ADDRESS addr,
-            /* [in] */ ULONG32 size,
-            /* [in] */ ULONG32 typeFlags);
-
-    // ICorDebugDataTarget4
-
-    virtual HRESULT STDMETHODCALLTYPE VirtualUnwind(
-        /* [in] */ DWORD threadId,
-        /* [in] */ ULONG32 contextSize,
-        /* [in, out, size_is(contextSize)] */ PBYTE context);
-
-    // ICLRMetadataLocator
-
-    virtual HRESULT STDMETHODCALLTYPE GetMetadata(
-        /* [in] */ LPCWSTR imagePath,
-        /* [in] */ ULONG32 imageTimestamp,
-        /* [in] */ ULONG32 imageSize,
-        /* [in] */ GUID* mvid,
-        /* [in] */ ULONG32 mdRva,
-        /* [in] */ ULONG32 flags,
-        /* [in] */ ULONG32 bufferSize,
-        /* [out, size_is(bufferSize), length_is(*dataSize)] */
-        BYTE* buffer,
-        /* [out] */ ULONG32* dataSize);
-
-    // ICLRRuntimeLocator
-
-    virtual HRESULT STDMETHODCALLTYPE GetRuntimeBase(
-        /* [out] */ CLRDATA_ADDRESS* baseAddress);
-};
\ No newline at end of file
index dd0a68e3ba03806a5cf951569c825707b59b13f7..966f96ce231bed95deeb0ae8007900092901941f 100644 (file)
@@ -10,7 +10,7 @@
 #include <assert.h>
 #include "sos.h"
 #include "safemath.h"
-#include "holder.h"
+#include "releaseholder.h"
 
 
 // This is the increment for the segment lookup data
index c0a0061f765d431c8529f1f5015998b1f7536375..9d2e91a502884714724ae57723feb6baed3a795b 100644 (file)
@@ -98,7 +98,7 @@ ExtQuery(ILLDBServices* services)
     SOS_ExtQueryFailGo(g_ExtData2, IDebugDataSpaces2);
     SOS_ExtQueryFailGo(g_ExtAdvanced, IDebugAdvanced);
 #endif // FEATURE_PAL
-    return S_OK;
+    return Status;
 
  Fail:
     if (Status == E_OUTOFMEMORY)
@@ -175,6 +175,7 @@ ExtRelease(void)
     EXT_RELEASE(g_ExtServices2);
     g_ExtServices = NULL;
 #endif // FEATURE_PAL
+    ReleaseTarget();
 }
 
 #ifndef FEATURE_PAL
@@ -201,6 +202,7 @@ void CleanupEventCallbacks()
 {
     if(g_pCallbacksClient != NULL)
     {
+        g_pCallbacksClient->SetEventCallbacks(NULL);
         g_pCallbacksClient->Release();
         g_pCallbacksClient = NULL;
     }
@@ -231,13 +233,12 @@ DebugExtensionInitialize(PULONG Version, PULONG Flags)
     }
     g_Initialized = true;
 
-    if ((Hr = DebugCreate(__uuidof(IDebugClient),
-                          (void **)&DebugClient)) != S_OK)
+    if ((Hr = DebugCreate(__uuidof(IDebugClient), (void **)&DebugClient)) != S_OK)
     {
         return Hr;
     }
-    if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
-                                              (void **)&DebugControl)) != S_OK)
+
+    if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl), (void **)&DebugControl)) != S_OK)
     {
         return Hr;
     }
@@ -306,6 +307,7 @@ DebugExtensionUninitialize(void)
 {
     // Execute all registered cleanup tasks
     OnUnloadTask::Run();
+    g_Initialized = false;
 }
 
 BOOL WINAPI 
@@ -320,14 +322,6 @@ DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
 
 #else // FEATURE_PAL
 
-__attribute__((destructor)) 
-void
-Uninitialize(void)
-{
-    // Execute all registered cleanup tasks
-    OnUnloadTask::Run();
-}
-
 HRESULT
 DebugClient::QueryInterface(
     REFIID InterfaceId,
index beca2efeb401edfffc6cd19e87995ce3d977ebb6..7a58e82a5dd6c944530e545ac38098f22ee702a1 100644 (file)
@@ -71,7 +71,7 @@ typedef struct _TADDR_SEGINFO
 } TADDR_SEGINFO;
 
 #include "util.h"
-#include "runtime.h"
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -150,8 +150,6 @@ extern ILLDBServices2*       g_ExtServices2;
 
 #endif // FEATURE_PAL
 
-extern bool g_dotnetDumpHost;
-
 HRESULT
 ExtQuery(PDEBUG_CLIENT client);
 
@@ -202,23 +200,7 @@ inline void EENotLoadedMessage(HRESULT Status)
 inline void DACMessage(HRESULT Status)
 {
     ExtOut("Failed to load data access module, 0x%08x\n", Status);
-#ifdef FEATURE_PAL
-    if (true)
-#else 
-    if (g_dotnetDumpHost)
-#endif
-    {
-        if (Status == CORDBG_E_MISSING_DEBUGGER_EXPORTS)
-        {
-            ExtOut("You can run the debugger command 'setclrpath <directory>' to control the load of %s.\n", GetDacDllName());
-            ExtOut("If that succeeds, the SOS command should work on retry.\n");
-        }
-        else
-        {
-            ExtOut("Can not load or initialize %s. The target runtime may not be initialized.\n", GetDacDllName());
-        }
-    }
-    else
+    if (GetHost()->GetHostType() == IHost::HostType::DbgEng)
     {
         ExtOut("Verify that 1) you have a recent build of the debugger (10.0.18317.1001 or newer)\n");
         ExtOut("            2) the file %s that matches your version of %s is\n", GetDacDllName(), GetRuntimeDllName());
@@ -239,12 +221,22 @@ inline void DACMessage(HRESULT Status)
         ExtOut("If you are debugging a minidump, you need to make sure that your executable\n");
         ExtOut("path is pointing to %s as well.\n", GetRuntimeDllName());
     }
+    else
+    {
+        if (Status == CORDBG_E_MISSING_DEBUGGER_EXPORTS)
+        {
+            ExtOut("You can run the debugger command 'setclrpath <directory>' to control the load of %s.\n", GetDacDllName());
+            ExtOut("If that succeeds, the SOS command should work on retry.\n");
+        }
+        else
+        {
+            ExtOut("Can not load or initialize %s. The target runtime may not be initialized.\n", GetDacDllName());
+        }
+    }
     ExtOut("\n");
     ExtOut("For more information see https://go.microsoft.com/fwlink/?linkid=2135652\n");
 }
 
-HRESULT CheckEEDll();
-
 // The minimum initialization for a command
 #define INIT_API_EXT()                                          \
     HRESULT Status;                                             \
@@ -261,7 +253,7 @@ HRESULT CheckEEDll();
     if ((Status = ArchQuery()) != S_OK) return Status;
 
 #define INIT_API_EE()                                           \
-    if ((Status = CheckEEDll()) != S_OK)           \
+    if ((Status = GetTarget()->GetRuntime(&g_pRuntime)) != S_OK)\
     {                                                           \
         EENotLoadedMessage(Status);                             \
         return Status;                                          \
@@ -448,7 +440,6 @@ inline CLRDATA_ADDRESS GetBP(const CROSS_PLATFORM_CONTEXT& context)
     return TO_CDADDR(g_targetMachine->GetBP(context));
 }
 
-
 //-----------------------------------------------------------------------------------------
 //
 //  api declaration macros & api access macros
index b6c2a3174ad82e02fbd6605c884caacf6b978e76..b4ebde697a1e9978a50053a0d1b07008b17eedf6 100644 (file)
@@ -52,11 +52,9 @@ extern void UninitializeDesktopClrHost();
 #endif
 
 bool g_useDesktopClrHost = false;
-bool g_dotnetDumpHost = false;
 static bool g_hostingInitialized = false;
 bool g_symbolStoreInitialized = false;
 LPCSTR g_hostRuntimeDirectory = nullptr;
-LPCSTR g_tmpPath = nullptr;
 SOSNetCoreCallbacks g_SOSNetCoreCallbacks;
 
 #ifndef FEATURE_PAL
@@ -126,6 +124,27 @@ static void AddFilesFromDirectoryToTpaList(const char* directory, std::string& t
     }
 }
 
+/// <summary>
+/// Helper function to get the absolute path from a relative one
+/// </summary>
+/// <param name="path">relative path</param>
+/// <param name="absolutePath">absolute path output</param>
+/// <returns>true success, false invalid path</returns>
+bool GetAbsolutePath(const char* path, std::string& absolutePath)
+{
+    ArrayHolder<char> fullPath = new char[MAX_LONGPATH];
+#ifdef FEATURE_PAL
+    if (realpath(path, fullPath) != nullptr && fullPath[0] != '\0')
+#else
+    if (GetFullPathNameA(path, MAX_LONGPATH, fullPath, nullptr) != 0)
+#endif
+    {
+        absolutePath.assign(fullPath);
+        return true;
+    }
+    return false;
+}
+
 #ifdef FEATURE_PAL
 
 #if defined(__linux__)
@@ -134,23 +153,6 @@ static void AddFilesFromDirectoryToTpaList(const char* directory, std::string& t
 #define symlinkEntrypointExecutable "/proc/curproc/exe"
 #endif
 
-static bool GetAbsolutePath(const char* path, std::string& absolutePath)
-{
-    bool result = false;
-
-    char realPath[PATH_MAX];
-    if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
-    {
-        absolutePath.assign(realPath);
-        // realpath should return canonicalized path without the trailing slash
-        assert(absolutePath.back() != '/');
-
-        result = true;
-    }
-
-    return result;
-}
-
 static bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable)
 {
     bool result = false;
@@ -392,7 +394,7 @@ static HRESULT GetHostRuntime(std::string& coreClrPath, std::string& hostRuntime
                     // Find highest 6.0.x version
                     if (!FindDotNetVersion(6, 0, hostRuntimeDirectory))
                     {
-                        HRESULT hr = CheckEEDll();
+                        HRESULT hr = GetTarget()->GetRuntime(&g_pRuntime);
                         if (FAILED(hr)) {
                             return hr;
                         }
@@ -423,66 +425,6 @@ static HRESULT GetHostRuntime(std::string& coreClrPath, std::string& hostRuntime
     return S_OK;
 }
 
-/**********************************************************************\
- * Returns the unique temporary directory for this instance of SOS
-\**********************************************************************/
-LPCSTR GetTempDirectory()
-{
-    if (g_tmpPath == nullptr)
-    {
-        char tmpPath[MAX_LONGPATH];
-        if (::GetTempPathA(MAX_LONGPATH, tmpPath) == 0)
-        {
-            strcpy_s(tmpPath, MAX_LONGPATH, ".");
-            strcat_s(tmpPath, MAX_LONGPATH, DIRECTORY_SEPARATOR_STR_A);
-        }
-        char pidstr[128];
-        sprintf_s(pidstr, _countof(pidstr), "sos%d", GetCurrentProcessId());
-        strcat_s(tmpPath, MAX_LONGPATH, pidstr);
-        strcat_s(tmpPath, MAX_LONGPATH, DIRECTORY_SEPARATOR_STR_A);
-
-        CreateDirectoryA(tmpPath, NULL);
-        g_tmpPath = _strdup(tmpPath);
-        OnUnloadTask::Register(CleanupTempDirectory);
-    }
-    return g_tmpPath;
-}
-
-/**********************************************************************\
- * Clean up the temporary directory files and DAC symlink.
-\**********************************************************************/
-void CleanupTempDirectory()
-{
-    LPCSTR tmpPath = (LPCSTR)InterlockedExchangePointer((PVOID *)&g_tmpPath, nullptr);
-    if (tmpPath != nullptr)
-    {
-        std::string directory(tmpPath);
-        directory.append("*");
-
-        WIN32_FIND_DATAA data;
-        HANDLE findHandle = FindFirstFileA(directory.c_str(), &data);
-
-        if (findHandle != INVALID_HANDLE_VALUE) 
-        {
-            do
-            {
-                if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
-                {
-                    std::string file(tmpPath);
-                    file.append(data.cFileName);
-                    DeleteFileA(file.c_str());
-                }
-            } 
-            while (0 != FindNextFileA(findHandle, &data));
-
-            FindClose(findHandle);
-        }
-
-        RemoveDirectoryA(tmpPath);
-        free((void*)tmpPath);
-    }
-}
-
 #ifndef FEATURE_PAL
 
 /**********************************************************************\
@@ -518,15 +460,6 @@ extern "C" HRESULT SOSInitializeByHost(
     {
         return E_INVALIDARG;
     }
-    if (tempDirectory != nullptr)
-    {
-        g_tmpPath = _strdup(tempDirectory);
-    }
-    if (runtimeModulePath != nullptr)
-    {
-        g_runtimeModulePath = _strdup(runtimeModulePath);
-    }
-    Runtime::SetDacDbiPath(isDesktop, dacFilePath, dbiFilePath);
 #ifndef FEATURE_PAL
     // When SOS is hosted on dotnet-dump, the ExtensionApis are not set so 
     // the expression evaluation function needs to be supplied.
@@ -534,7 +467,6 @@ extern "C" HRESULT SOSInitializeByHost(
 #endif
     g_symbolStoreInitialized = symbolStoreEnabled;
     g_hostingInitialized = true;
-    g_dotnetDumpHost = true;
     return S_OK;
 }
 
@@ -748,7 +680,7 @@ HRESULT InitializeSymbolStore(
         logging,
         msdl,
         symweb,
-        GetTempDirectory(),
+        GetTarget()->GetTempDirectory(),
         symbolServer,
         authToken,
         timeoutInMinutes,
@@ -801,7 +733,7 @@ void InitializeSymbolStoreFromSymPath()
                         false,                  // logging
                         false,                  // msdl
                         false,                  // symweb
-                        GetTempDirectory(),     // tempDirectory
+                        GetTarget()->GetTempDirectory(),     // tempDirectory
                         nullptr,                // symbolServerPath
                         nullptr,                // authToken
                         0,                      // timeoutInMinutes
index ff9b67d15994bfcdda5948daa234f33e624e35c9..df950d21357cb73b3ac88302376960931c0015a2 100644 (file)
@@ -83,7 +83,6 @@ static const char *MetadataHelperClassName = "SOS.MetadataHelper";
 
 extern HMODULE g_hInstance;
 extern LPCSTR g_hostRuntimeDirectory;
-extern LPCSTR g_tmpPath;
 extern SOSNetCoreCallbacks g_SOSNetCoreCallbacks;
 
 #ifdef FEATURE_PAL
@@ -91,8 +90,7 @@ extern bool GetAbsolutePath(const char* path, std::string& absolutePath);
 extern HRESULT LoadNativeSymbols(bool runtimeOnly = false);
 #endif
 
-extern LPCSTR GetTempDirectory();
-extern void CleanupTempDirectory();
+extern bool GetAbsolutePath(const char* path, std::string& absolutePath);
 extern BOOL IsHostingInitialized();
 extern HRESULT InitializeHosting();
 
index 61e5760dd2bd9406c08bba352d3e6b2425c2c9bd..a216b5aa673b020fd014ef925abc256843a7ea02 100644 (file)
@@ -11,7 +11,8 @@
 #include <tchar.h>
 #include <strsafe.h>
 #include <string>
-#include <holder.h>
+#include <palclr.h>
+#include <releaseholder.h>
 #include <arrayholder.h>
 
 #define CLR_VERSION     L"v4.0.30319"
diff --git a/src/SOS/Strike/inc/dbgeng.h b/src/SOS/Strike/inc/dbgeng.h
deleted file mode 100644 (file)
index cf04574..0000000
+++ /dev/null
@@ -1,16126 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//----------------------------------------------------------------------------
-//
-// Debugger engine interfaces.
-//
-//
-//----------------------------------------------------------------------------
-
-#ifndef __DBGENG_H__
-#define __DBGENG_H__
-
-#include <stdarg.h>
-#include <objbase.h>
-
-#ifndef _WDBGEXTS_
-typedef struct _WINDBG_EXTENSION_APIS32* PWINDBG_EXTENSION_APIS32;
-typedef struct _WINDBG_EXTENSION_APIS64* PWINDBG_EXTENSION_APIS64;
-#endif
-
-#ifndef _CRASHLIB_
-typedef struct _MEMORY_BASIC_INFORMATION64* PMEMORY_BASIC_INFORMATION64;
-#endif
-
-#ifndef __specstrings
-// Should include SpecStrings.h to get proper definitions.
-#define __in
-#define __in_opt
-#define __in_bcount(x)
-#define __in_bcount_opt(x)
-#define __in_ecount(x)
-#define __in_ecount_opt(x)
-#define __out
-#define __out_opt
-#define __out_bcount(x)
-#define __out_bcount_opt(x)
-#define __out_ecount(x)
-#define __out_ecount_opt(x)
-#define __out_xcount(x)
-#define __inout
-#define __inout_opt
-// Android defines various fields on struct which are named __reserved[x]; for example, in wchar.h,
-// so we must prefix __reserved with __clr_
-#define __clr_reserved
-#else
-#define __clr_reserved __reserved
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//----------------------------------------------------------------------------
-//
-// GUIDs and interface forward declarations.
-//
-//----------------------------------------------------------------------------
-
-/* f2df5f53-071f-47bd-9de6-5734c3fed689 */
-DEFINE_GUID(IID_IDebugAdvanced, 0xf2df5f53, 0x071f, 0x47bd,
-            0x9d, 0xe6, 0x57, 0x34, 0xc3, 0xfe, 0xd6, 0x89);
-/* 716d14c9-119b-4ba5-af1f-0890e672416a */
-DEFINE_GUID(IID_IDebugAdvanced2, 0x716d14c9, 0x119b, 0x4ba5,
-            0xaf, 0x1f, 0x08, 0x90, 0xe6, 0x72, 0x41, 0x6a);
-/* cba4abb4-84c4-444d-87ca-a04e13286739 */
-DEFINE_GUID(IID_IDebugAdvanced3, 0xcba4abb4, 0x84c4, 0x444d,
-            0x87, 0xca, 0xa0, 0x4e, 0x13, 0x28, 0x67, 0x39);
-/* 5bd9d474-5975-423a-b88b-65a8e7110e65 */
-DEFINE_GUID(IID_IDebugBreakpoint, 0x5bd9d474, 0x5975, 0x423a,
-            0xb8, 0x8b, 0x65, 0xa8, 0xe7, 0x11, 0x0e, 0x65);
-/* 1b278d20-79f2-426e-a3f9-c1ddf375d48e */
-DEFINE_GUID(IID_IDebugBreakpoint2, 0x1b278d20, 0x79f2, 0x426e,
-            0xa3, 0xf9, 0xc1, 0xdd, 0xf3, 0x75, 0xd4, 0x8e);
-/* 27fe5639-8407-4f47-8364-ee118fb08ac8 */
-DEFINE_GUID(IID_IDebugClient, 0x27fe5639, 0x8407, 0x4f47,
-            0x83, 0x64, 0xee, 0x11, 0x8f, 0xb0, 0x8a, 0xc8);
-/* edbed635-372e-4dab-bbfe-ed0d2f63be81 */
-DEFINE_GUID(IID_IDebugClient2, 0xedbed635, 0x372e, 0x4dab,
-        0xbb, 0xfe, 0xed, 0x0d, 0x2f, 0x63, 0xbe, 0x81);
-/* dd492d7f-71b8-4ad6-a8dc-1c887479ff91 */
-DEFINE_GUID(IID_IDebugClient3, 0xdd492d7f, 0x71b8, 0x4ad6,
-            0xa8, 0xdc, 0x1c, 0x88, 0x74, 0x79, 0xff, 0x91);
-/* ca83c3de-5089-4cf8-93c8-d892387f2a5e */
-DEFINE_GUID(IID_IDebugClient4, 0xca83c3de, 0x5089, 0x4cf8,
-            0x93, 0xc8, 0xd8, 0x92, 0x38, 0x7f, 0x2a, 0x5e);
-/* e3acb9d7-7ec2-4f0c-a0da-e81e0cbbe628 */
-DEFINE_GUID(IID_IDebugClient5, 0xe3acb9d7, 0x7ec2, 0x4f0c,
-            0xa0, 0xda, 0xe8, 0x1e, 0x0c, 0xbb, 0xe6, 0x28);
-/* 5182e668-105e-416e-ad92-24ef800424ba */
-DEFINE_GUID(IID_IDebugControl, 0x5182e668, 0x105e, 0x416e,
-            0xad, 0x92, 0x24, 0xef, 0x80, 0x04, 0x24, 0xba);
-/* d4366723-44df-4bed-8c7e-4c05424f4588 */
-DEFINE_GUID(IID_IDebugControl2, 0xd4366723, 0x44df, 0x4bed,
-            0x8c, 0x7e, 0x4c, 0x05, 0x42, 0x4f, 0x45, 0x88);
-/* 7df74a86-b03f-407f-90ab-a20dadcead08 */
-DEFINE_GUID(IID_IDebugControl3, 0x7df74a86, 0xb03f, 0x407f,
-            0x90, 0xab, 0xa2, 0x0d, 0xad, 0xce, 0xad, 0x08);
-/* 94e60ce9-9b41-4b19-9fc0-6d9eb35272b3 */
-DEFINE_GUID(IID_IDebugControl4, 0x94e60ce9, 0x9b41, 0x4b19,
-            0x9f, 0xc0, 0x6d, 0x9e, 0xb3, 0x52, 0x72, 0xb3);
-/* 88f7dfab-3ea7-4c3a-aefb-c4e8106173aa */
-DEFINE_GUID(IID_IDebugDataSpaces, 0x88f7dfab, 0x3ea7, 0x4c3a,
-            0xae, 0xfb, 0xc4, 0xe8, 0x10, 0x61, 0x73, 0xaa);
-/* 7a5e852f-96e9-468f-ac1b-0b3addc4a049 */
-DEFINE_GUID(IID_IDebugDataSpaces2, 0x7a5e852f, 0x96e9, 0x468f,
-            0xac, 0x1b, 0x0b, 0x3a, 0xdd, 0xc4, 0xa0, 0x49);
-/* 23f79d6c-8aaf-4f7c-a607-9995f5407e63 */
-DEFINE_GUID(IID_IDebugDataSpaces3, 0x23f79d6c, 0x8aaf, 0x4f7c,
-            0xa6, 0x07, 0x99, 0x95, 0xf5, 0x40, 0x7e, 0x63);
-/* d98ada1f-29e9-4ef5-a6c0-e53349883212 */
-DEFINE_GUID(IID_IDebugDataSpaces4, 0xd98ada1f, 0x29e9, 0x4ef5,
-            0xa6, 0xc0, 0xe5, 0x33, 0x49, 0x88, 0x32, 0x12);
-/* 337be28b-5036-4d72-b6bf-c45fbb9f2eaa */
-DEFINE_GUID(IID_IDebugEventCallbacks, 0x337be28b, 0x5036, 0x4d72,
-            0xb6, 0xbf, 0xc4, 0x5f, 0xbb, 0x9f, 0x2e, 0xaa);
-/* 0690e046-9c23-45ac-a04f-987ac29ad0d3 */
-DEFINE_GUID(IID_IDebugEventCallbacksWide, 0x0690e046, 0x9c23, 0x45ac,
-            0xa0, 0x4f, 0x98, 0x7a, 0xc2, 0x9a, 0xd0, 0xd3);
-/* 9f50e42c-f136-499e-9a97-73036c94ed2d */
-DEFINE_GUID(IID_IDebugInputCallbacks, 0x9f50e42c, 0xf136, 0x499e,
-            0x9a, 0x97, 0x73, 0x03, 0x6c, 0x94, 0xed, 0x2d);
-/* 4bf58045-d654-4c40-b0af-683090f356dc */
-DEFINE_GUID(IID_IDebugOutputCallbacks, 0x4bf58045, 0xd654, 0x4c40,
-            0xb0, 0xaf, 0x68, 0x30, 0x90, 0xf3, 0x56, 0xdc);
-/* 4c7fd663-c394-4e26-8ef1-34ad5ed3764c */
-DEFINE_GUID(IID_IDebugOutputCallbacksWide, 0x4c7fd663, 0xc394, 0x4e26,
-            0x8e, 0xf1, 0x34, 0xad, 0x5e, 0xd3, 0x76, 0x4c);
-/* 67721fe9-56d2-4a44-a325-2b65513ce6eb */
-DEFINE_GUID(IID_IDebugOutputCallbacks2, 0x67721fe9, 0x56d2, 0x4a44,
-            0xa3, 0x25, 0x2b, 0x65, 0x51, 0x3c, 0xe6, 0xeb);
-/* ce289126-9e84-45a7-937e-67bb18691493 */
-DEFINE_GUID(IID_IDebugRegisters, 0xce289126, 0x9e84, 0x45a7,
-            0x93, 0x7e, 0x67, 0xbb, 0x18, 0x69, 0x14, 0x93);
-/* 1656afa9-19c6-4e3a-97e7-5dc9160cf9c4 */
-DEFINE_GUID(IID_IDebugRegisters2, 0x1656afa9, 0x19c6, 0x4e3a,
-            0x97, 0xe7, 0x5d, 0xc9, 0x16, 0x0c, 0xf9, 0xc4);
-/* f2528316-0f1a-4431-aeed-11d096e1e2ab */
-DEFINE_GUID(IID_IDebugSymbolGroup, 0xf2528316, 0x0f1a, 0x4431,
-            0xae, 0xed, 0x11, 0xd0, 0x96, 0xe1, 0xe2, 0xab);
-/* 6a7ccc5f-fb5e-4dcc-b41c-6c20307bccc7 */
-DEFINE_GUID(IID_IDebugSymbolGroup2, 0x6a7ccc5f, 0xfb5e, 0x4dcc,
-            0xb4, 0x1c, 0x6c, 0x20, 0x30, 0x7b, 0xcc, 0xc7);
-/* 8c31e98c-983a-48a5-9016-6fe5d667a950 */
-DEFINE_GUID(IID_IDebugSymbols, 0x8c31e98c, 0x983a, 0x48a5,
-            0x90, 0x16, 0x6f, 0xe5, 0xd6, 0x67, 0xa9, 0x50);
-/* 3a707211-afdd-4495-ad4f-56fecdf8163f */
-DEFINE_GUID(IID_IDebugSymbols2, 0x3a707211, 0xafdd, 0x4495,
-            0xad, 0x4f, 0x56, 0xfe, 0xcd, 0xf8, 0x16, 0x3f);
-/* f02fbecc-50ac-4f36-9ad9-c975e8f32ff8 */
-DEFINE_GUID(IID_IDebugSymbols3, 0xf02fbecc, 0x50ac, 0x4f36,
-            0x9a, 0xd9, 0xc9, 0x75, 0xe8, 0xf3, 0x2f, 0xf8);
-/* 6b86fe2c-2c4f-4f0c-9da2-174311acc327 */
-DEFINE_GUID(IID_IDebugSystemObjects, 0x6b86fe2c, 0x2c4f, 0x4f0c,
-            0x9d, 0xa2, 0x17, 0x43, 0x11, 0xac, 0xc3, 0x27);
-/* 0ae9f5ff-1852-4679-b055-494bee6407ee */
-DEFINE_GUID(IID_IDebugSystemObjects2, 0x0ae9f5ff, 0x1852, 0x4679,
-            0xb0, 0x55, 0x49, 0x4b, 0xee, 0x64, 0x07, 0xee);
-/* e9676e2f-e286-4ea3-b0f9-dfe5d9fc330e */
-DEFINE_GUID(IID_IDebugSystemObjects3, 0xe9676e2f, 0xe286, 0x4ea3,
-            0xb0, 0xf9, 0xdf, 0xe5, 0xd9, 0xfc, 0x33, 0x0e);
-/* 489468e6-7d0f-4af5-87ab-25207454d553 */
-DEFINE_GUID(IID_IDebugSystemObjects4, 0x489468e6, 0x7d0f, 0x4af5,
-            0x87, 0xab, 0x25, 0x20, 0x74, 0x54, 0xd5, 0x53);
-
-typedef interface DECLSPEC_UUID("f2df5f53-071f-47bd-9de6-5734c3fed689")
-    IDebugAdvanced* PDEBUG_ADVANCED;
-typedef interface DECLSPEC_UUID("716d14c9-119b-4ba5-af1f-0890e672416a")
-    IDebugAdvanced2* PDEBUG_ADVANCED2;
-typedef interface DECLSPEC_UUID("cba4abb4-84c4-444d-87ca-a04e13286739")
-    IDebugAdvanced3* PDEBUG_ADVANCED3;
-typedef interface DECLSPEC_UUID("5bd9d474-5975-423a-b88b-65a8e7110e65")
-    IDebugBreakpoint* PDEBUG_BREAKPOINT;
-typedef interface DECLSPEC_UUID("1b278d20-79f2-426e-a3f9-c1ddf375d48e")
-    IDebugBreakpoint2* PDEBUG_BREAKPOINT2;
-typedef interface DECLSPEC_UUID("27fe5639-8407-4f47-8364-ee118fb08ac8")
-    IDebugClient* PDEBUG_CLIENT;
-typedef interface DECLSPEC_UUID("edbed635-372e-4dab-bbfe-ed0d2f63be81")
-    IDebugClient2* PDEBUG_CLIENT2;
-typedef interface DECLSPEC_UUID("dd492d7f-71b8-4ad6-a8dc-1c887479ff91")
-    IDebugClient3* PDEBUG_CLIENT3;
-typedef interface DECLSPEC_UUID("ca83c3de-5089-4cf8-93c8-d892387f2a5e")
-    IDebugClient4* PDEBUG_CLIENT4;
-typedef interface DECLSPEC_UUID("e3acb9d7-7ec2-4f0c-a0da-e81e0cbbe628")
-    IDebugClient5* PDEBUG_CLIENT5;
-typedef interface DECLSPEC_UUID("5182e668-105e-416e-ad92-24ef800424ba")
-    IDebugControl* PDEBUG_CONTROL;
-typedef interface DECLSPEC_UUID("d4366723-44df-4bed-8c7e-4c05424f4588")
-    IDebugControl2* PDEBUG_CONTROL2;
-typedef interface DECLSPEC_UUID("7df74a86-b03f-407f-90ab-a20dadcead08")
-    IDebugControl3* PDEBUG_CONTROL3;
-typedef interface DECLSPEC_UUID("94e60ce9-9b41-4b19-9fc0-6d9eb35272b3")
-    IDebugControl4* PDEBUG_CONTROL4;
-typedef interface DECLSPEC_UUID("88f7dfab-3ea7-4c3a-aefb-c4e8106173aa")
-    IDebugDataSpaces* PDEBUG_DATA_SPACES;
-typedef interface DECLSPEC_UUID("7a5e852f-96e9-468f-ac1b-0b3addc4a049")
-    IDebugDataSpaces2* PDEBUG_DATA_SPACES2;
-typedef interface DECLSPEC_UUID("23f79d6c-8aaf-4f7c-a607-9995f5407e63")
-    IDebugDataSpaces3* PDEBUG_DATA_SPACES3;
-typedef interface DECLSPEC_UUID("d98ada1f-29e9-4ef5-a6c0-e53349883212")
-    IDebugDataSpaces4* PDEBUG_DATA_SPACES4;
-typedef interface DECLSPEC_UUID("337be28b-5036-4d72-b6bf-c45fbb9f2eaa")
-    IDebugEventCallbacks* PDEBUG_EVENT_CALLBACKS;
-typedef interface DECLSPEC_UUID("0690e046-9c23-45ac-a04f-987ac29ad0d3")
-    IDebugEventCallbacksWide* PDEBUG_EVENT_CALLBACKS_WIDE;
-typedef interface DECLSPEC_UUID("9f50e42c-f136-499e-9a97-73036c94ed2d")
-    IDebugInputCallbacks* PDEBUG_INPUT_CALLBACKS;
-typedef interface DECLSPEC_UUID("4bf58045-d654-4c40-b0af-683090f356dc")
-    IDebugOutputCallbacks* PDEBUG_OUTPUT_CALLBACKS;
-typedef interface DECLSPEC_UUID("4c7fd663-c394-4e26-8ef1-34ad5ed3764c")
-    IDebugOutputCallbacksWide* PDEBUG_OUTPUT_CALLBACKS_WIDE;
-typedef interface DECLSPEC_UUID("67721fe9-56d2-4a44-a325-2b65513ce6eb")
-    IDebugOutputCallbacks2* PDEBUG_OUTPUT_CALLBACKS2;
-typedef interface DECLSPEC_UUID("ce289126-9e84-45a7-937e-67bb18691493")
-    IDebugRegisters* PDEBUG_REGISTERS;
-typedef interface DECLSPEC_UUID("1656afa9-19c6-4e3a-97e7-5dc9160cf9c4")
-    IDebugRegisters2* PDEBUG_REGISTERS2;
-typedef interface DECLSPEC_UUID("f2528316-0f1a-4431-aeed-11d096e1e2ab")
-    IDebugSymbolGroup* PDEBUG_SYMBOL_GROUP;
-typedef interface DECLSPEC_UUID("6a7ccc5f-fb5e-4dcc-b41c-6c20307bccc7")
-    IDebugSymbolGroup2* PDEBUG_SYMBOL_GROUP2;
-typedef interface DECLSPEC_UUID("8c31e98c-983a-48a5-9016-6fe5d667a950")
-    IDebugSymbols* PDEBUG_SYMBOLS;
-typedef interface DECLSPEC_UUID("3a707211-afdd-4495-ad4f-56fecdf8163f")
-    IDebugSymbols2* PDEBUG_SYMBOLS2;
-typedef interface DECLSPEC_UUID("f02fbecc-50ac-4f36-9ad9-c975e8f32ff8")
-    IDebugSymbols3* PDEBUG_SYMBOLS3;
-typedef interface DECLSPEC_UUID("6b86fe2c-2c4f-4f0c-9da2-174311acc327")
-    IDebugSystemObjects* PDEBUG_SYSTEM_OBJECTS;
-typedef interface DECLSPEC_UUID("0ae9f5ff-1852-4679-b055-494bee6407ee")
-    IDebugSystemObjects2* PDEBUG_SYSTEM_OBJECTS2;
-typedef interface DECLSPEC_UUID("e9676e2f-e286-4ea3-b0f9-dfe5d9fc330e")
-    IDebugSystemObjects3* PDEBUG_SYSTEM_OBJECTS3;
-typedef interface DECLSPEC_UUID("489468e6-7d0f-4af5-87ab-25207454d553")
-    IDebugSystemObjects4* PDEBUG_SYSTEM_OBJECTS4;
-
-//----------------------------------------------------------------------------
-//
-// Macros.
-//
-//----------------------------------------------------------------------------
-
-// Extends a 32-bit address into a 64-bit address.
-#define DEBUG_EXTEND64(Addr) ((ULONG64)(LONG64)(LONG)(Addr))
-
-//----------------------------------------------------------------------------
-//
-// Client creation functions.
-//
-//----------------------------------------------------------------------------
-
-// RemoteOptions specifies connection types and
-// their parameters.  Supported strings are:
-//    npipe:Server=<Machine>,Pipe=<Pipe name>
-//    tcp:Server=<Machine>,Port=<IP port>
-STDAPI
-DebugConnect(
-    __in PCSTR RemoteOptions,
-    __in REFIID InterfaceId,
-    __out PVOID* Interface
-    );
-
-STDAPI
-DebugConnectWide(
-    __in PCWSTR RemoteOptions,
-    __in REFIID InterfaceId,
-    __out PVOID* Interface
-    );
-
-STDAPI
-DebugCreate(
-    __in REFIID InterfaceId,
-    __out PVOID* Interface
-    );
-
-//----------------------------------------------------------------------------
-//
-// IDebugAdvanced.
-//
-//----------------------------------------------------------------------------
-
-typedef struct _DEBUG_OFFSET_REGION
-{
-    ULONG64 Base;
-    ULONG64 Size;
-} DEBUG_OFFSET_REGION, *PDEBUG_OFFSET_REGION;
-
-#undef INTERFACE
-#define INTERFACE IDebugAdvanced
-DECLARE_INTERFACE_(IDebugAdvanced, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugAdvanced.
-
-    // Get/SetThreadContext offer control over
-    // the full processor context for a thread.
-    // Higher-level functions, such as the
-    // IDebugRegisters interface, allow similar
-    // access in simpler and more generic ways.
-    // Get/SetThreadContext are useful when
-    // large amounts of thread context must
-    // be changed and processor-specific code
-    // is not a problem.
-    STDMETHOD(GetThreadContext)(
-        THIS_
-        __out_bcount(ContextSize) /* align_is(16) */ PVOID Context,
-        __in ULONG ContextSize
-        ) PURE;
-    STDMETHOD(SetThreadContext)(
-        THIS_
-        __in_bcount(ContextSize) /* align_is(16) */ PVOID Context,
-        __in ULONG ContextSize
-        ) PURE;
-};
-
-typedef struct _DEBUG_READ_USER_MINIDUMP_STREAM
-{
-    IN ULONG StreamType;
-    IN ULONG Flags;
-    IN ULONG64 Offset;
-    OUT PVOID Buffer;
-    IN ULONG BufferSize;
-    OUT ULONG BufferUsed;
-} DEBUG_READ_USER_MINIDUMP_STREAM, *PDEBUG_READ_USER_MINIDUMP_STREAM;
-
-#define DEBUG_GET_TEXT_COMPLETIONS_NO_DOT_COMMANDS       0x00000001
-#define DEBUG_GET_TEXT_COMPLETIONS_NO_EXTENSION_COMMANDS 0x00000002
-#define DEBUG_GET_TEXT_COMPLETIONS_NO_SYMBOLS            0x00000004
-
-typedef struct _DEBUG_GET_TEXT_COMPLETIONS_IN
-{
-    ULONG Flags;
-    ULONG MatchCountLimit;
-    ULONG64 Reserved[3];
-    // Input text string follows.
-} DEBUG_GET_TEXT_COMPLETIONS_IN, *PDEBUG_GET_TEXT_COMPLETIONS_IN;
-
-#define DEBUG_GET_TEXT_COMPLETIONS_IS_DOT_COMMAND       0x00000001
-#define DEBUG_GET_TEXT_COMPLETIONS_IS_EXTENSION_COMMAND 0x00000002
-#define DEBUG_GET_TEXT_COMPLETIONS_IS_SYMBOL            0x00000004
-
-typedef struct _DEBUG_GET_TEXT_COMPLETIONS_OUT
-{
-    ULONG Flags;
-    // Char index in input string where completions start.
-    ULONG ReplaceIndex;
-    ULONG MatchCount;
-    ULONG Reserved1;
-    ULONG64 Reserved2[2];
-    // Completions follow.
-    // Completion data is zero-terminated strings ended
-    // by a final zero double-terminator.
-} DEBUG_GET_TEXT_COMPLETIONS_OUT, *PDEBUG_GET_TEXT_COMPLETIONS_OUT;
-
-typedef struct _DEBUG_CACHED_SYMBOL_INFO
-{
-    ULONG64 ModBase;
-    ULONG64 Arg1;
-    ULONG64 Arg2;
-    ULONG Id;
-    ULONG Arg3;
-} DEBUG_CACHED_SYMBOL_INFO, *PDEBUG_CACHED_SYMBOL_INFO;
-
-//
-// Request requests.
-//
-
-// InBuffer - Unused.
-// OutBuffer - Unused.
-#define DEBUG_REQUEST_SOURCE_PATH_HAS_SOURCE_SERVER 0
-
-// InBuffer - Unused.
-// OutBuffer - Machine-specific CONTEXT.
-#define DEBUG_REQUEST_TARGET_EXCEPTION_CONTEXT 1
-
-// InBuffer - Unused.
-// OutBuffer - ULONG system ID of thread.
-#define DEBUG_REQUEST_TARGET_EXCEPTION_THREAD 2
-
-// InBuffer - Unused.
-// OutBuffer - EXCEPTION_RECORD64.
-#define DEBUG_REQUEST_TARGET_EXCEPTION_RECORD 3
-
-// InBuffer - Unused.
-// OutBuffer - DEBUG_CREATE_PROCESS_OPTIONS.
-#define DEBUG_REQUEST_GET_ADDITIONAL_CREATE_OPTIONS 4
-
-// InBuffer - DEBUG_CREATE_PROCESS_OPTIONS.
-// OutBuffer - Unused.
-#define DEBUG_REQUEST_SET_ADDITIONAL_CREATE_OPTIONS 5
-
-// InBuffer - Unused.
-// OutBuffer - ULONG[2] major/minor.
-#define DEBUG_REQUEST_GET_WIN32_MAJOR_MINOR_VERSIONS 6
-
-// InBuffer - DEBUG_READ_USER_MINIDUMP_STREAM.
-// OutBuffer - Unused.
-#define DEBUG_REQUEST_READ_USER_MINIDUMP_STREAM 7
-
-// InBuffer - Unused.
-// OutBuffer - Unused.
-#define DEBUG_REQUEST_TARGET_CAN_DETACH 8
-
-// InBuffer - PTSTR.
-// OutBuffer - Unused.
-#define DEBUG_REQUEST_SET_LOCAL_IMPLICIT_COMMAND_LINE 9
-
-// InBuffer - Unused.
-// OutBuffer - Event code stream offset.
-#define DEBUG_REQUEST_GET_CAPTURED_EVENT_CODE_OFFSET 10
-
-// InBuffer - Unused.
-// OutBuffer - Event code stream information.
-#define DEBUG_REQUEST_READ_CAPTURED_EVENT_CODE_STREAM 11
-
-// InBuffer - Input data block.
-// OutBuffer - Processed data block.
-#define DEBUG_REQUEST_EXT_TYPED_DATA_ANSI 12
-
-// InBuffer - Unused.
-// OutBuffer - Returned path.
-#define DEBUG_REQUEST_GET_EXTENSION_SEARCH_PATH_WIDE 13
-
-// InBuffer - DEBUG_GET_TEXT_COMPLETIONS_IN.
-// OutBuffer - DEBUG_GET_TEXT_COMPLETIONS_OUT.
-#define DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE 14
-
-// InBuffer - ULONG64 cookie.
-// OutBuffer - DEBUG_CACHED_SYMBOL_INFO.
-#define DEBUG_REQUEST_GET_CACHED_SYMBOL_INFO 15
-
-// InBuffer - DEBUG_CACHED_SYMBOL_INFO.
-// OutBuffer - ULONG64 cookie.
-#define DEBUG_REQUEST_ADD_CACHED_SYMBOL_INFO 16
-
-// InBuffer - ULONG64 cookie.
-// OutBuffer - Unused.
-#define DEBUG_REQUEST_REMOVE_CACHED_SYMBOL_INFO 17
-
-// InBuffer - DEBUG_GET_TEXT_COMPLETIONS_IN.
-// OutBuffer - DEBUG_GET_TEXT_COMPLETIONS_OUT.
-#define DEBUG_REQUEST_GET_TEXT_COMPLETIONS_ANSI 18
-
-// InBuffer - Unused.
-// OutBuffer - Unused.
-#define DEBUG_REQUEST_CURRENT_OUTPUT_CALLBACKS_ARE_DML_AWARE 19
-
-// InBuffer - ULONG64 offset.
-// OutBuffer - Unwind information.
-#define DEBUG_REQUEST_GET_OFFSET_UNWIND_INFORMATION 20
-
-// InBuffer - Unused
-// OutBuffer - returned DUMP_HEADER32/DUMP_HEADER64 structure.
-#define DEBUG_REQUEST_GET_DUMP_HEADER 21
-
-// InBuffer - DUMP_HEADER32/DUMP_HEADER64 structure.
-// OutBuffer - Unused
-#define DEBUG_REQUEST_SET_DUMP_HEADER 22
-
-//
-// GetSourceFileInformation requests.
-//
-
-// Arg64 - Module base.
-// Arg32 - Unused.
-#define DEBUG_SRCFILE_SYMBOL_TOKEN 0
-
-// Arg64 - Module base.
-// Arg32 - Unused.
-#define DEBUG_SRCFILE_SYMBOL_TOKEN_SOURCE_COMMAND_WIDE 1
-
-//
-// GetSymbolInformation requests.
-//
-
-// Arg64 - Unused.
-// Arg32 - Breakpoint ID.
-// Buffer - ULONG line number.
-// String - File name.
-#define DEBUG_SYMINFO_BREAKPOINT_SOURCE_LINE 0
-
-// Arg64 - Module base.
-// Arg32 - Unused.
-// Buffer - IMAGEHLP_MODULEW64.
-// String - Unused.
-#define DEBUG_SYMINFO_IMAGEHLP_MODULEW64 1
-
-// Arg64 - Offset.
-// Arg32 - Symbol tag.
-// Buffer - Unicode symbol name strings.  Could have multiple strings.
-// String - Unused, strings are returned in Buffer as there
-//          may be more than one.
-#define DEBUG_SYMINFO_GET_SYMBOL_NAME_BY_OFFSET_AND_TAG_WIDE 2
-
-// Arg64 - Module base.
-// Arg32 - Symbol tag.
-// Buffer - Array of symbol addresses.
-// String - Concatenated symbol strings.  Individual symbol
-//          strings are zero-terminated and the final string in
-//          a symbol is double-zero-terminated.
-#define DEBUG_SYMINFO_GET_MODULE_SYMBOL_NAMES_AND_OFFSETS 3
-
-//
-// GetSystemObjectInformation requests.
-//
-
-// Arg64 - Unused.
-// Arg32 - Debugger thread ID.
-// Buffer - DEBUG_THREAD_BASIC_INFORMATION.
-#define DEBUG_SYSOBJINFO_THREAD_BASIC_INFORMATION 0
-
-// Arg64 - Unused.
-// Arg32 - Debugger thread ID.
-// Buffer - Unicode name string.
-#define DEBUG_SYSOBJINFO_THREAD_NAME_WIDE 1
-
-// Arg64 - Unused.
-// Arg32 - Unused.
-// Buffer - ULONG cookie value.
-#define DEBUG_SYSOBJINFO_CURRENT_PROCESS_COOKIE 2
-
-#define DEBUG_TBINFO_EXIT_STATUS    0x00000001
-#define DEBUG_TBINFO_PRIORITY_CLASS 0x00000002
-#define DEBUG_TBINFO_PRIORITY       0x00000004
-#define DEBUG_TBINFO_TIMES          0x00000008
-#define DEBUG_TBINFO_START_OFFSET   0x00000010
-#define DEBUG_TBINFO_AFFINITY       0x00000020
-#define DEBUG_TBINFO_ALL            0x0000003f
-
-typedef struct _DEBUG_THREAD_BASIC_INFORMATION
-{
-    // Valid members have a DEBUG_TBINFO bit set in Valid.
-    ULONG Valid;
-    ULONG ExitStatus;
-    ULONG PriorityClass;
-    ULONG Priority;
-    ULONG64 CreateTime;
-    ULONG64 ExitTime;
-    ULONG64 KernelTime;
-    ULONG64 UserTime;
-    ULONG64 StartOffset;
-    ULONG64 Affinity;
-} DEBUG_THREAD_BASIC_INFORMATION, *PDEBUG_THREAD_BASIC_INFORMATION;
-
-#undef INTERFACE
-#define INTERFACE IDebugAdvanced2
-DECLARE_INTERFACE_(IDebugAdvanced2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugAdvanced.
-
-    // Get/SetThreadContext offer control over
-    // the full processor context for a thread.
-    // Higher-level functions, such as the
-    // IDebugRegisters interface, allow similar
-    // access in simpler and more generic ways.
-    // Get/SetThreadContext are useful when
-    // large amounts of thread context must
-    // be changed and processor-specific code
-    // is not a problem.
-    STDMETHOD(GetThreadContext)(
-        THIS_
-        __out_bcount(ContextSize) /* align_is(16) */ PVOID Context,
-        __in ULONG ContextSize
-        ) PURE;
-    STDMETHOD(SetThreadContext)(
-        THIS_
-        __in_bcount(ContextSize) /* align_is(16) */ PVOID Context,
-        __in ULONG ContextSize
-        ) PURE;
-
-    // IDebugAdvanced2.
-
-    //
-    // Generalized open-ended methods for querying
-    // and manipulation.  The open-ended nature of
-    // these methods makes it easy to add new requests,
-    // although at a cost in convenience of calling.
-    // Sufficiently common requests may have more specific,
-    // simpler methods elsewhere.
-    //
-
-    STDMETHOD(Request)(
-        THIS_
-        __in ULONG Request,
-        __in_bcount_opt(InBufferSize) PVOID InBuffer,
-        __in ULONG InBufferSize,
-        __out_bcount_opt(OutBufferSize) PVOID OutBuffer,
-        __in ULONG OutBufferSize,
-        __out_opt PULONG OutSize
-        ) PURE;
-
-    STDMETHOD(GetSourceFileInformation)(
-        THIS_
-        __in ULONG Which,
-        __in PSTR SourceFile,
-        __in ULONG64 Arg64,
-        __in ULONG Arg32,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InfoSize
-        ) PURE;
-    STDMETHOD(FindSourceFileAndToken)(
-        THIS_
-        __in ULONG StartElement,
-        __in ULONG64 ModAddr,
-        __in PCSTR File,
-        __in ULONG Flags,
-        __in_bcount_opt(FileTokenSize) PVOID FileToken,
-        __in ULONG FileTokenSize,
-        __out_opt PULONG FoundElement,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FoundSize
-        ) PURE;
-
-    STDMETHOD(GetSymbolInformation)(
-        THIS_
-        __in ULONG Which,
-        __in ULONG64 Arg64,
-        __in ULONG Arg32,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InfoSize,
-        __out_ecount_opt(StringBufferSize) PSTR StringBuffer,
-        __in ULONG StringBufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-
-    STDMETHOD(GetSystemObjectInformation)(
-        THIS_
-        __in ULONG Which,
-        __in ULONG64 Arg64,
-        __in ULONG Arg32,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InfoSize
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugAdvanced3
-DECLARE_INTERFACE_(IDebugAdvanced3, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugAdvanced.
-
-    // Get/SetThreadContext offer control over
-    // the full processor context for a thread.
-    // Higher-level functions, such as the
-    // IDebugRegisters interface, allow similar
-    // access in simpler and more generic ways.
-    // Get/SetThreadContext are useful when
-    // large amounts of thread context must
-    // be changed and processor-specific code
-    // is not a problem.
-    STDMETHOD(GetThreadContext)(
-        THIS_
-        __out_bcount(ContextSize) /* align_is(16) */ PVOID Context,
-        __in ULONG ContextSize
-        ) PURE;
-    STDMETHOD(SetThreadContext)(
-        THIS_
-        __in_bcount(ContextSize) /* align_is(16) */ PVOID Context,
-        __in ULONG ContextSize
-        ) PURE;
-
-    // IDebugAdvanced2.
-
-    //
-    // Generalized open-ended methods for querying
-    // and manipulation.  The open-ended nature of
-    // these methods makes it easy to add new requests,
-    // although at a cost in convenience of calling.
-    // Sufficiently common requests may have more specific,
-    // simpler methods elsewhere.
-    //
-
-    STDMETHOD(Request)(
-        THIS_
-        __in ULONG Request,
-        __in_bcount_opt(InBufferSize) PVOID InBuffer,
-        __in ULONG InBufferSize,
-        __out_bcount_opt(OutBufferSize) PVOID OutBuffer,
-        __in ULONG OutBufferSize,
-        __out_opt PULONG OutSize
-        ) PURE;
-
-    STDMETHOD(GetSourceFileInformation)(
-        THIS_
-        __in ULONG Which,
-        __in PSTR SourceFile,
-        __in ULONG64 Arg64,
-        __in ULONG Arg32,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InfoSize
-        ) PURE;
-    STDMETHOD(FindSourceFileAndToken)(
-        THIS_
-        __in ULONG StartElement,
-        __in ULONG64 ModAddr,
-        __in PCSTR File,
-        __in ULONG Flags,
-        __in_bcount_opt(FileTokenSize) PVOID FileToken,
-        __in ULONG FileTokenSize,
-        __out_opt PULONG FoundElement,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FoundSize
-        ) PURE;
-
-    STDMETHOD(GetSymbolInformation)(
-        THIS_
-        __in ULONG Which,
-        __in ULONG64 Arg64,
-        __in ULONG Arg32,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InfoSize,
-        __out_ecount_opt(StringBufferSize) PSTR StringBuffer,
-        __in ULONG StringBufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-
-    STDMETHOD(GetSystemObjectInformation)(
-        THIS_
-        __in ULONG Which,
-        __in ULONG64 Arg64,
-        __in ULONG Arg32,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InfoSize
-        ) PURE;
-
-    // IDebugAdvanced3.
-
-    STDMETHOD(GetSourceFileInformationWide)(
-        THIS_
-        __in ULONG Which,
-        __in PWSTR SourceFile,
-        __in ULONG64 Arg64,
-        __in ULONG Arg32,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InfoSize
-        ) PURE;
-    STDMETHOD(FindSourceFileAndTokenWide)(
-        THIS_
-        __in ULONG StartElement,
-        __in ULONG64 ModAddr,
-        __in PCWSTR File,
-        __in ULONG Flags,
-        __in_bcount_opt(FileTokenSize) PVOID FileToken,
-        __in ULONG FileTokenSize,
-        __out_opt PULONG FoundElement,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FoundSize
-        ) PURE;
-
-    STDMETHOD(GetSymbolInformationWide)(
-        THIS_
-        __in ULONG Which,
-        __in ULONG64 Arg64,
-        __in ULONG Arg32,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InfoSize,
-        __out_ecount_opt(StringBufferSize) PWSTR StringBuffer,
-        __in ULONG StringBufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugBreakpoint.
-//
-//----------------------------------------------------------------------------
-
-// Types of breakpoints.
-#define DEBUG_BREAKPOINT_CODE 0
-#define DEBUG_BREAKPOINT_DATA 1
-#define DEBUG_BREAKPOINT_TIME 2
-
-// Breakpoint flags.
-// Go-only breakpoints are only active when
-// the engine is in unrestricted execution
-// mode.  They do not fire when the engine
-// is stepping.
-#define DEBUG_BREAKPOINT_GO_ONLY    0x00000001
-// A breakpoint is flagged as deferred as long as
-// its offset expression cannot be evaluated.
-// A deferred breakpoint is not active.
-#define DEBUG_BREAKPOINT_DEFERRED   0x00000002
-#define DEBUG_BREAKPOINT_ENABLED    0x00000004
-// The adder-only flag does not affect breakpoint
-// operation.  It is just a marker to restrict
-// output and notifications for the breakpoint to
-// the client that added the breakpoint.  Breakpoint
-// callbacks for adder-only breaks will only be delivered
-// to the adding client.  The breakpoint can not
-// be enumerated and accessed by other clients.
-#define DEBUG_BREAKPOINT_ADDER_ONLY 0x00000008
-// One-shot breakpoints automatically clear themselves
-// the first time they are hit.
-#define DEBUG_BREAKPOINT_ONE_SHOT   0x00000010
-
-// Data breakpoint access types.
-// Different architectures support different
-// sets of these bits.
-#define DEBUG_BREAK_READ    0x00000001
-#define DEBUG_BREAK_WRITE   0x00000002
-#define DEBUG_BREAK_EXECUTE 0x00000004
-#define DEBUG_BREAK_IO      0x00000008
-
-// Structure for querying breakpoint information
-// all at once.
-typedef struct _DEBUG_BREAKPOINT_PARAMETERS
-{
-    ULONG64 Offset;
-    ULONG Id;
-    ULONG BreakType;
-    ULONG ProcType;
-    ULONG Flags;
-    ULONG DataSize;
-    ULONG DataAccessType;
-    ULONG PassCount;
-    ULONG CurrentPassCount;
-    ULONG MatchThread;
-    ULONG CommandSize;
-    ULONG OffsetExpressionSize;
-} DEBUG_BREAKPOINT_PARAMETERS, *PDEBUG_BREAKPOINT_PARAMETERS;
-
-#undef INTERFACE
-#define INTERFACE IDebugBreakpoint
-DECLARE_INTERFACE_(IDebugBreakpoint, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugBreakpoint.
-
-    // Retrieves debugger engine unique ID
-    // for the breakpoint.  This ID is
-    // fixed as long as the breakpoint exists
-    // but after that may be reused.
-    STDMETHOD(GetId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    // Retrieves the type of break and
-    // processor type for the breakpoint.
-    STDMETHOD(GetType)(
-        THIS_
-        __out PULONG BreakType,
-        __out PULONG ProcType
-        ) PURE;
-    // Returns the client that called AddBreakpoint.
-    STDMETHOD(GetAdder)(
-        THIS_
-        __out PDEBUG_CLIENT* Adder
-        ) PURE;
-
-    STDMETHOD(GetFlags)(
-        THIS_
-        __out PULONG Flags
-        ) PURE;
-    // Only certain flags can be changed.  Flags
-    // are: GO_ONLY, ENABLE.
-    // Sets the given flags.
-    STDMETHOD(AddFlags)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Clears the given flags.
-    STDMETHOD(RemoveFlags)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Sets the flags.
-    STDMETHOD(SetFlags)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-
-    // Controls the offset of the breakpoint.  The
-    // interpretation of the offset value depends on
-    // the type of breakpoint and its settings.  It
-    // may be a code address, a data address, an
-    // I/O port, etc.
-    STDMETHOD(GetOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(SetOffset)(
-        THIS_
-        __in ULONG64 Offset
-        ) PURE;
-
-    // Data breakpoint methods will fail if the
-    // target platform does not support the
-    // parameters used.
-    // These methods only function for breakpoints
-    // created as data breakpoints.
-    STDMETHOD(GetDataParameters)(
-        THIS_
-        __out PULONG Size,
-        __out PULONG AccessType
-        ) PURE;
-    STDMETHOD(SetDataParameters)(
-        THIS_
-        __in ULONG Size,
-        __in ULONG AccessType
-        ) PURE;
-
-    // Pass count defaults to one.
-    STDMETHOD(GetPassCount)(
-        THIS_
-        __out PULONG Count
-        ) PURE;
-    STDMETHOD(SetPassCount)(
-        THIS_
-        __in ULONG Count
-        ) PURE;
-    // Gets the current number of times
-    // the breakpoint has been hit since
-    // it was last triggered.
-    STDMETHOD(GetCurrentPassCount)(
-        THIS_
-        __out PULONG Count
-        ) PURE;
-
-    // If a match thread is set this breakpoint will
-    // only trigger if it occurs on the match thread.
-    // Otherwise it triggers for all threads.
-    // Thread restrictions are not currently supported
-    // in kernel mode.
-    STDMETHOD(GetMatchThreadId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(SetMatchThreadId)(
-        THIS_
-        __in ULONG Thread
-        ) PURE;
-
-    // The command for a breakpoint is automatically
-    // executed by the engine before the event
-    // is propagated.  If the breakpoint continues
-    // execution the event will begin with a continue
-    // status.  If the breakpoint does not continue
-    // the event will begin with a break status.
-    // This allows breakpoint commands to participate
-    // in the normal event status voting.
-    // Breakpoint commands are only executed until
-    // the first command that alters the execution
-    // status, such as g, p and t.
-    STDMETHOD(GetCommand)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetCommand)(
-        THIS_
-        __in PCSTR Command
-        ) PURE;
-
-    // Offset expressions are evaluated immediately
-    // and at module load and unload events.  If the
-    // evaluation is successful the breakpoints
-    // offset is updated and the breakpoint is
-    // handled normally.  If the expression cannot
-    // be evaluated the breakpoint is deferred.
-    // Currently the only offset expression
-    // supported is a module-relative symbol
-    // of the form <Module>!<Symbol>.
-    STDMETHOD(GetOffsetExpression)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ExpressionSize
-        ) PURE;
-    STDMETHOD(SetOffsetExpression)(
-        THIS_
-        __in PCSTR Expression
-        ) PURE;
-
-    STDMETHOD(GetParameters)(
-        THIS_
-        __out PDEBUG_BREAKPOINT_PARAMETERS Params
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugBreakpoint2
-DECLARE_INTERFACE_(IDebugBreakpoint2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugBreakpoint.
-
-    // Retrieves debugger engine unique ID
-    // for the breakpoint.  This ID is
-    // fixed as long as the breakpoint exists
-    // but after that may be reused.
-    STDMETHOD(GetId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    // Retrieves the type of break and
-    // processor type for the breakpoint.
-    STDMETHOD(GetType)(
-        THIS_
-        __out PULONG BreakType,
-        __out PULONG ProcType
-        ) PURE;
-    // Returns the client that called AddBreakpoint.
-    STDMETHOD(GetAdder)(
-        THIS_
-        __out PDEBUG_CLIENT* Adder
-        ) PURE;
-
-    STDMETHOD(GetFlags)(
-        THIS_
-        __out PULONG Flags
-        ) PURE;
-    // Only certain flags can be changed.  Flags
-    // are: GO_ONLY, ENABLE.
-    // Sets the given flags.
-    STDMETHOD(AddFlags)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Clears the given flags.
-    STDMETHOD(RemoveFlags)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Sets the flags.
-    STDMETHOD(SetFlags)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-
-    // Controls the offset of the breakpoint.  The
-    // interpretation of the offset value depends on
-    // the type of breakpoint and its settings.  It
-    // may be a code address, a data address, an
-    // I/O port, etc.
-    STDMETHOD(GetOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(SetOffset)(
-        THIS_
-        __in ULONG64 Offset
-        ) PURE;
-
-    // Data breakpoint methods will fail if the
-    // target platform does not support the
-    // parameters used.
-    // These methods only function for breakpoints
-    // created as data breakpoints.
-    STDMETHOD(GetDataParameters)(
-        THIS_
-        __out PULONG Size,
-        __out PULONG AccessType
-        ) PURE;
-    STDMETHOD(SetDataParameters)(
-        THIS_
-        __in ULONG Size,
-        __in ULONG AccessType
-        ) PURE;
-
-    // Pass count defaults to one.
-    STDMETHOD(GetPassCount)(
-        THIS_
-        __out PULONG Count
-        ) PURE;
-    STDMETHOD(SetPassCount)(
-        THIS_
-        __in ULONG Count
-        ) PURE;
-    // Gets the current number of times
-    // the breakpoint has been hit since
-    // it was last triggered.
-    STDMETHOD(GetCurrentPassCount)(
-        THIS_
-        __out PULONG Count
-        ) PURE;
-
-    // If a match thread is set this breakpoint will
-    // only trigger if it occurs on the match thread.
-    // Otherwise it triggers for all threads.
-    // Thread restrictions are not currently supported
-    // in kernel mode.
-    STDMETHOD(GetMatchThreadId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(SetMatchThreadId)(
-        THIS_
-        __in ULONG Thread
-        ) PURE;
-
-    // The command for a breakpoint is automatically
-    // executed by the engine before the event
-    // is propagated.  If the breakpoint continues
-    // execution the event will begin with a continue
-    // status.  If the breakpoint does not continue
-    // the event will begin with a break status.
-    // This allows breakpoint commands to participate
-    // in the normal event status voting.
-    // Breakpoint commands are only executed until
-    // the first command that alters the execution
-    // status, such as g, p and t.
-    STDMETHOD(GetCommand)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetCommand)(
-        THIS_
-        __in PCSTR Command
-        ) PURE;
-
-    // Offset expressions are evaluated immediately
-    // and at module load and unload events.  If the
-    // evaluation is successful the breakpoints
-    // offset is updated and the breakpoint is
-    // handled normally.  If the expression cannot
-    // be evaluated the breakpoint is deferred.
-    // Currently the only offset expression
-    // supported is a module-relative symbol
-    // of the form <Module>!<Symbol>.
-    STDMETHOD(GetOffsetExpression)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ExpressionSize
-        ) PURE;
-    STDMETHOD(SetOffsetExpression)(
-        THIS_
-        __in PCSTR Expression
-        ) PURE;
-
-    STDMETHOD(GetParameters)(
-        THIS_
-        __out PDEBUG_BREAKPOINT_PARAMETERS Params
-        ) PURE;
-
-    // IDebugBreakpoint2.
-
-    STDMETHOD(GetCommandWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetCommandWide)(
-        THIS_
-        __in PCWSTR Command
-        ) PURE;
-
-    STDMETHOD(GetOffsetExpressionWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ExpressionSize
-        ) PURE;
-    STDMETHOD(SetOffsetExpressionWide)(
-        THIS_
-        __in PCWSTR Expression
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugClient.
-//
-//----------------------------------------------------------------------------
-
-// Kernel attach flags.
-#define DEBUG_ATTACH_KERNEL_CONNECTION 0x00000000
-// Attach to the local machine.  If this flag is not set
-// a connection is made to a separate target machine using
-// the given connection options.
-#define DEBUG_ATTACH_LOCAL_KERNEL      0x00000001
-// Attach to an eXDI driver.
-#define DEBUG_ATTACH_EXDI_DRIVER       0x00000002
-
-// GetRunningProcessSystemIdByExecutableName flags.
-// By default the match allows a tail match on
-// just the filename.  The match returns the first hit
-// even if multiple matches exist.
-#define DEBUG_GET_PROC_DEFAULT      0x00000000
-// The name must match fully.
-#define DEBUG_GET_PROC_FULL_MATCH   0x00000001
-// The match must be the only match.
-#define DEBUG_GET_PROC_ONLY_MATCH   0x00000002
-// The name is a service name instead of an executable name.
-#define DEBUG_GET_PROC_SERVICE_NAME 0x00000004
-
-// GetRunningProcessDescription flags.
-#define DEBUG_PROC_DESC_DEFAULT         0x00000000
-// Return only filenames, not full paths.
-#define DEBUG_PROC_DESC_NO_PATHS        0x00000001
-// Dont look up service names.
-#define DEBUG_PROC_DESC_NO_SERVICES     0x00000002
-// Dont look up MTS package names.
-#define DEBUG_PROC_DESC_NO_MTS_PACKAGES 0x00000004
-// Dont retrieve the command line.
-#define DEBUG_PROC_DESC_NO_COMMAND_LINE 0x00000008
-// Dont retrieve the session ID.
-#define DEBUG_PROC_DESC_NO_SESSION_ID   0x00000010
-// Dont retrieve the process's user name.
-#define DEBUG_PROC_DESC_NO_USER_NAME    0x00000020
-
-//
-// Attach flags.
-//
-
-// Call DebugActiveProcess when attaching.
-#define DEBUG_ATTACH_DEFAULT                   0x00000000
-// When attaching to a process just examine
-// the process state and suspend the threads.
-// DebugActiveProcess is not called so the process
-// is not actually being debugged.  This is useful
-// for debugging processes holding locks which
-// interfere with the operation of DebugActiveProcess
-// or in situations where it is not desirable to
-// actually set up as a debugger.
-#define DEBUG_ATTACH_NONINVASIVE               0x00000001
-// Attempt to attach to a process that was abandoned
-// when being debugged.  This is only supported in
-// some system versions.
-// This flag also allows multiple debuggers to
-// attach to the same process, which can result
-// in numerous problems unless very carefully
-// managed.
-#define DEBUG_ATTACH_EXISTING                  0x00000002
-// When attaching non-invasively, do not suspend
-// threads.  It is the callers responsibility
-// to either suspend the threads itself or be
-// aware that the attach state may not reflect
-// the current state of the process if threads
-// are still running.
-#define DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND    0x00000004
-// When doing an invasive attach do not inject
-// a break-in thread to generate the initial break-in
-// event.  This can be useful to save resources when
-// an initial break is not necessary or when injecting
-// a thread might affect the debuggee's state.  This
-// option is only supported on Windows XP and above.
-#define DEBUG_ATTACH_INVASIVE_NO_INITIAL_BREAK 0x00000008
-// When doing an invasive attach resume all threads at the
-// time of attach.  This makes it possible to attach
-// to a process created suspended and cause it to start running.
-#define DEBUG_ATTACH_INVASIVE_RESUME_PROCESS   0x00000010
-// When doing a non-invasive attach the engine must
-// recover information for all debuggee elements.  The
-// engine may not have permissions for all elements,
-// for example it may not be able to open all threads,
-// and that would ordinarily block the attach.  This
-// flag allows unusable elements to be ignored.
-#define DEBUG_ATTACH_NONINVASIVE_ALLOW_PARTIAL 0x00000020
-
-
-//
-// Process creation flags to merge with Win32 flags.
-//
-
-// On Windows XP this flag prevents the debug
-// heap from being used in the new process.
-#define DEBUG_CREATE_PROCESS_NO_DEBUG_HEAP CREATE_UNICODE_ENVIRONMENT
-// Indicates that the native NT RTL process creation
-// routines should be used instead of Win32.  This
-// is only meaningful for special processes that run
-// as NT native processes.
-#define DEBUG_CREATE_PROCESS_THROUGH_RTL   STACK_SIZE_PARAM_IS_A_RESERVATION
-
-//
-// Process creation flags specific to the debugger engine.
-//
-
-#define DEBUG_ECREATE_PROCESS_DEFAULT                   0x00000000
-#define DEBUG_ECREATE_PROCESS_INHERIT_HANDLES           0x00000001
-#define DEBUG_ECREATE_PROCESS_USE_VERIFIER_FLAGS        0x00000002
-#define DEBUG_ECREATE_PROCESS_USE_IMPLICIT_COMMAND_LINE 0x00000004
-
-typedef struct _DEBUG_CREATE_PROCESS_OPTIONS
-{
-    // Win32 create flags.
-    ULONG CreateFlags;
-    // DEBUG_ECREATE_PROCESS_* flags.
-    ULONG EngCreateFlags;
-    // Application Verifier flags,
-    // if DEBUG_ECREATE_PROCESS_USE_VERIFIER_FLAGS is set.
-    ULONG VerifierFlags;
-    // Must be zero.
-    ULONG Reserved;
-} DEBUG_CREATE_PROCESS_OPTIONS, *PDEBUG_CREATE_PROCESS_OPTIONS;
-
-//
-// Process options.
-//
-
-// Indicates that the debuggee process should be
-// automatically detached when the debugger exits.
-// A debugger can explicitly detach on exit or this
-// flag can be set so that detach occurs regardless
-// of how the debugger exits.
-// This is only supported on some system versions.
-#define DEBUG_PROCESS_DETACH_ON_EXIT    0x00000001
-// Indicates that processes created by the current
-// process should not be debugged.
-// Modifying this flag is only supported on some
-// system versions.
-#define DEBUG_PROCESS_ONLY_THIS_PROCESS 0x00000002
-
-// ConnectSession flags.
-// Default connect.
-#define DEBUG_CONNECT_SESSION_DEFAULT     0x00000000
-// Do not output the debugger version.
-#define DEBUG_CONNECT_SESSION_NO_VERSION  0x00000001
-// Do not announce the connection.
-#define DEBUG_CONNECT_SESSION_NO_ANNOUNCE 0x00000002
-
-// OutputServers flags.
-// Debugger servers from StartSever.
-#define DEBUG_SERVERS_DEBUGGER 0x00000001
-// Process servers from StartProcessServer.
-#define DEBUG_SERVERS_PROCESS  0x00000002
-#define DEBUG_SERVERS_ALL      0x00000003
-
-// EndSession flags.
-// Perform cleanup for the session.
-#define DEBUG_END_PASSIVE          0x00000000
-// Actively terminate the session and then perform cleanup.
-#define DEBUG_END_ACTIVE_TERMINATE 0x00000001
-// If possible, detach from all processes and then perform cleanup.
-#define DEBUG_END_ACTIVE_DETACH    0x00000002
-// Perform whatever cleanup is possible that doesn't require
-// acquiring any locks.  This is useful for situations where
-// a thread is currently using the engine but the application
-// needs to exit and still wants to give the engine
-// the opportunity to clean up as much as possible.
-// This may leave the engine in an indeterminate state so
-// further engine calls should not be made.
-// When making a reentrant EndSession call from a remote
-// client it is the callers responsibility to ensure
-// that the server can process the request.  It is best
-// to avoid making such calls.
-#define DEBUG_END_REENTRANT        0x00000003
-// Notify a server that a remote client is disconnecting.
-// This isnt required but if it isnt called then
-// no disconnect messages will be generated by the server.
-#define DEBUG_END_DISCONNECT       0x00000004
-
-// Output mask bits.
-// Normal output.
-#define DEBUG_OUTPUT_NORMAL            0x00000001
-// Error output.
-#define DEBUG_OUTPUT_ERROR             0x00000002
-// Warnings.
-#define DEBUG_OUTPUT_WARNING           0x00000004
-// Additional output.
-#define DEBUG_OUTPUT_VERBOSE           0x00000008
-// Prompt output.
-#define DEBUG_OUTPUT_PROMPT            0x00000010
-// Register dump before prompt.
-#define DEBUG_OUTPUT_PROMPT_REGISTERS  0x00000020
-// Warnings specific to extension operation.
-#define DEBUG_OUTPUT_EXTENSION_WARNING 0x00000040
-// Debuggee debug output, such as from OutputDebugString.
-#define DEBUG_OUTPUT_DEBUGGEE          0x00000080
-// Debuggee-generated prompt, such as from DbgPrompt.
-#define DEBUG_OUTPUT_DEBUGGEE_PROMPT   0x00000100
-// Symbol messages, such as for !sym noisy.
-#define DEBUG_OUTPUT_SYMBOLS           0x00000200
-
-// Internal debugger output, used mainly
-// for debugging the debugger.  Output
-// may only occur in debug builds.
-// KD protocol output.
-#define DEBUG_IOUTPUT_KD_PROTOCOL      0x80000000
-// Remoting output.
-#define DEBUG_IOUTPUT_REMOTING         0x40000000
-// Breakpoint output.
-#define DEBUG_IOUTPUT_BREAKPOINT       0x20000000
-// Event output.
-#define DEBUG_IOUTPUT_EVENT            0x10000000
-
-// OutputIdentity flags.
-#define DEBUG_OUTPUT_IDENTITY_DEFAULT 0x00000000
-
-#undef INTERFACE
-#define INTERFACE IDebugClient
-DECLARE_INTERFACE_(IDebugClient, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugClient.
-
-    // The following set of methods start
-    // the different kinds of debuggees.
-
-    // Begins a debug session using the kernel
-    // debugging protocol.  This method selects
-    // the protocol as the debuggee communication
-    // mechanism but does not initiate the communication
-    // itself.
-    STDMETHOD(AttachKernel)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PCSTR ConnectOptions
-        ) PURE;
-    STDMETHOD(GetKernelConnectionOptions)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG OptionsSize
-        ) PURE;
-    // Updates the connection options for a live
-    // kernel connection.  This can only be used
-    // to modify parameters for the connection, not
-    // to switch to a completely different kind of
-    // connection.
-    // This method is reentrant.
-    STDMETHOD(SetKernelConnectionOptions)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-
-    // Starts a process server for remote
-    // user-mode process control.
-    // The local process server is server zero.
-    STDMETHOD(StartProcessServer)(
-        THIS_
-        __in ULONG Flags,
-        __in PCSTR Options,
-        __in_opt __clr_reserved PVOID Reserved
-        ) PURE;
-    STDMETHOD(ConnectProcessServer)(
-        THIS_
-        __in PCSTR RemoteOptions,
-        __out PULONG64 Server
-        ) PURE;
-    STDMETHOD(DisconnectProcessServer)(
-        THIS_
-        __in ULONG64 Server
-        ) PURE;
-
-    // Enumerates and describes processes
-    // accessible through the given process server.
-    STDMETHOD(GetRunningProcessSystemIds)(
-        THIS_
-        __in ULONG64 Server,
-        __out_ecount_opt(Count) PULONG Ids,
-        __in ULONG Count,
-        __out_opt PULONG ActualCount
-        ) PURE;
-    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
-        THIS_
-        __in ULONG64 Server,
-        __in PCSTR ExeName,
-        __in ULONG Flags,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetRunningProcessDescription)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG SystemId,
-        __in ULONG Flags,
-        __out_ecount_opt(ExeNameSize) PSTR ExeName,
-        __in ULONG ExeNameSize,
-        __out_opt PULONG ActualExeNameSize,
-        __out_ecount_opt(DescriptionSize) PSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG ActualDescriptionSize
-        ) PURE;
-
-    // Attaches to a running user-mode process.
-    STDMETHOD(AttachProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Creates a new user-mode process for debugging.
-    // CreateFlags are as given to Win32s CreateProcess.
-    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
-    // must be specified.
-    STDMETHOD(CreateProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in PSTR CommandLine,
-        __in ULONG CreateFlags
-        ) PURE;
-    // Creates or attaches to a user-mode process, or both.
-    // If CommandLine is NULL this method operates as
-    // AttachProcess does.  If ProcessId is zero it
-    // operates as CreateProcess does.  If CommandLine is
-    // non-NULL and ProcessId is non-zero the method first
-    // starts a process with the given information but
-    // in a suspended state.  The engine then attaches to
-    // the indicated process.  Once the attach is successful
-    // the suspended process is resumed.  This provides
-    // synchronization between the new process and the
-    // attachment.
-    STDMETHOD(CreateProcessAndAttach)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PSTR CommandLine,
-        __in ULONG CreateFlags,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Gets and sets process control flags.
-    STDMETHOD(GetProcessOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Opens any kind of user- or kernel-mode dump file
-    // and begins a debug session with the information
-    // contained within it.
-    STDMETHOD(OpenDumpFile)(
-        THIS_
-        __in PCSTR DumpFile
-        ) PURE;
-    // Writes a dump file from the current session information.
-    // The kind of dump file written is determined by the
-    // kind of session and the type qualifier given.
-    // For example, if the current session is a kernel
-    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
-    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
-    STDMETHOD(WriteDumpFile)(
-        THIS_
-        __in PCSTR DumpFile,
-        __in ULONG Qualifier
-        ) PURE;
-
-    // Indicates that a remote client is ready to
-    // begin participating in the current session.
-    // HistoryLimit gives a character limit on
-    // the amount of output history to be sent.
-    STDMETHOD(ConnectSession)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG HistoryLimit
-        ) PURE;
-    // Indicates that the engine should start accepting
-    // remote connections. Options specifies connection types
-    // and their parameters.  Supported strings are:
-    //    npipe:Pipe=<Pipe name>
-    //    tcp:Port=<IP port>
-    STDMETHOD(StartServer)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-    // List the servers running on the given machine.
-    // Uses the line prefix.
-    STDMETHOD(OutputServers)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR Machine,
-        __in ULONG Flags
-        ) PURE;
-
-    // Attempts to terminate all processes in the debuggers list.
-    STDMETHOD(TerminateProcesses)(
-        THIS
-        ) PURE;
-    // Attempts to detach from all processes in the debuggers list.
-    // This requires OS support for debugger detach.
-    STDMETHOD(DetachProcesses)(
-        THIS
-        ) PURE;
-    // Stops the current debug session.  If a process
-    // was created or attached an active EndSession can
-    // terminate or detach from it.
-    // If a kernel connection was opened it will be closed but the
-    // target machine is otherwise unaffected.
-    STDMETHOD(EndSession)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // If a process was started and ran to completion
-    // this method can be used to retrieve its exit code.
-    STDMETHOD(GetExitCode)(
-        THIS_
-        __out PULONG Code
-        ) PURE;
-
-    // Client event callbacks are called on the thread
-    // of the client.  In order to give thread
-    // execution to the engine for callbacks all
-    // client threads should call DispatchCallbacks
-    // when they are idle.  Callbacks are only
-    // received when a thread calls DispatchCallbacks
-    // or WaitForEvent.  WaitForEvent can only be
-    // called by the thread that started the debug
-    // session so all other client threads should
-    // call DispatchCallbacks when possible.
-    // DispatchCallbacks returns when ExitDispatch is used
-    // to interrupt dispatch or when the timeout expires.
-    // DispatchCallbacks dispatches callbacks for all
-    // clients associated with the thread calling
-    // DispatchCallbacks.
-    // DispatchCallbacks returns S_FALSE when the
-    // timeout expires.
-    STDMETHOD(DispatchCallbacks)(
-        THIS_
-        __in ULONG Timeout
-        ) PURE;
-    // ExitDispatch can be used to interrupt callback
-    // dispatch when a client thread is needed by the
-    // client.  This method is reentrant and can
-    // be called from any thread.
-    STDMETHOD(ExitDispatch)(
-        THIS_
-        __in PDEBUG_CLIENT Client
-        ) PURE;
-
-    // Clients are specific to the thread that
-    // created them.  Calls from other threads
-    // fail immediately.  The CreateClient method
-    // is a notable exception; it allows creation
-    // of a new client for a new thread.
-    STDMETHOD(CreateClient)(
-        THIS_
-        __out PDEBUG_CLIENT* Client
-        ) PURE;
-
-    STDMETHOD(GetInputCallbacks)(
-        THIS_
-        __out PDEBUG_INPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetInputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_INPUT_CALLBACKS Callbacks
-        ) PURE;
-
-    // Output callback interfaces are described separately.
-    STDMETHOD(GetOutputCallbacks)(
-        THIS_
-        __out PDEBUG_OUTPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetOutputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_OUTPUT_CALLBACKS Callbacks
-        ) PURE;
-    // Output flags provide control over
-    // the distribution of output among clients.
-    // Output masks select which output streams
-    // should be sent to the output callbacks.
-    // Only Output calls with a mask that
-    // contains one of the output mask bits
-    // will be sent to the output callbacks.
-    // These methods are reentrant.
-    // If such access is not synchronized
-    // disruptions in output may occur.
-    STDMETHOD(GetOutputMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOutputMask)(
-        THIS_
-        __in ULONG Mask
-        ) PURE;
-    // These methods allow access to another clients
-    // output mask.  They are necessary for changing
-    // a clients output mask when it is
-    // waiting for events.  These methods are reentrant
-    // and can be called from any thread.
-    STDMETHOD(GetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __in ULONG Mask
-        ) PURE;
-    // Control the width of an output line for
-    // commands which produce formatted output.
-    // This setting is just a suggestion.
-    STDMETHOD(GetOutputWidth)(
-        THIS_
-        __out PULONG Columns
-        ) PURE;
-    STDMETHOD(SetOutputWidth)(
-        THIS_
-        __in ULONG Columns
-        ) PURE;
-    // Some of the engines output commands produce
-    // multiple lines of output.  A prefix can be
-    // set that the engine will automatically output
-    // for each line in that case, allowing a caller
-    // to control indentation or identifying marks.
-    // This is not a general setting for any output
-    // with a newline in it.  Methods which use
-    // the line prefix are marked in their documentation.
-    STDMETHOD(GetOutputLinePrefix)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PrefixSize
-        ) PURE;
-    STDMETHOD(SetOutputLinePrefix)(
-        THIS_
-        __in_opt PCSTR Prefix
-        ) PURE;
-
-    // Returns a string describing the machine
-    // and user this client represents.  The
-    // specific content of the string varies
-    // with operating system.  If the client is
-    // remotely connected some network information
-    // may also be present.
-    STDMETHOD(GetIdentity)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG IdentitySize
-        ) PURE;
-    // Format is a printf-like format string
-    // with one %s where the identity string should go.
-    STDMETHOD(OutputIdentity)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags,
-        __in PCSTR Format
-        ) PURE;
-
-    // Event callbacks allow a client to
-    // receive notification about changes
-    // during the debug session.
-    STDMETHOD(GetEventCallbacks)(
-        THIS_
-        __out PDEBUG_EVENT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetEventCallbacks)(
-        THIS_
-        __in_opt PDEBUG_EVENT_CALLBACKS Callbacks
-        ) PURE;
-
-    // The engine sometimes merges compatible callback
-    // requests to reduce callback overhead.  This is
-    // most noticeable with output as small pieces of
-    // output are collected into larger groups to
-    // reduce the overall number of output callback calls.
-    // A client can use this method to force all pending
-    // callbacks to be delivered.  This is rarely necessary.
-    STDMETHOD(FlushCallbacks)(
-        THIS
-        ) PURE;
-};
-
-// Per-dump-format control flags.
-#define DEBUG_FORMAT_DEFAULT                  0x00000000
-// When creating a CAB with secondary images do searches
-// for all image files, regardless of whether they're
-// needed for the current session or not.
-#define DEBUG_FORMAT_CAB_SECONDARY_ALL_IMAGES 0x10000000
-// Write dump to a temporary file, then package it
-// into a CAB file and delete the temporary file.
-#define DEBUG_FORMAT_WRITE_CAB                0x20000000
-// When creating a CAB add secondary files such as
-// current symbols and mapped images.
-#define DEBUG_FORMAT_CAB_SECONDARY_FILES      0x40000000
-// Don't overwrite existing files.
-#define DEBUG_FORMAT_NO_OVERWRITE             0x80000000
-
-#define DEBUG_FORMAT_USER_SMALL_FULL_MEMORY               0x00000001
-#define DEBUG_FORMAT_USER_SMALL_HANDLE_DATA               0x00000002
-#define DEBUG_FORMAT_USER_SMALL_UNLOADED_MODULES          0x00000004
-#define DEBUG_FORMAT_USER_SMALL_INDIRECT_MEMORY           0x00000008
-#define DEBUG_FORMAT_USER_SMALL_DATA_SEGMENTS             0x00000010
-#define DEBUG_FORMAT_USER_SMALL_FILTER_MEMORY             0x00000020
-#define DEBUG_FORMAT_USER_SMALL_FILTER_PATHS              0x00000040
-#define DEBUG_FORMAT_USER_SMALL_PROCESS_THREAD_DATA       0x00000080
-#define DEBUG_FORMAT_USER_SMALL_PRIVATE_READ_WRITE_MEMORY 0x00000100
-#define DEBUG_FORMAT_USER_SMALL_NO_OPTIONAL_DATA          0x00000200
-#define DEBUG_FORMAT_USER_SMALL_FULL_MEMORY_INFO          0x00000400
-#define DEBUG_FORMAT_USER_SMALL_THREAD_INFO               0x00000800
-#define DEBUG_FORMAT_USER_SMALL_CODE_SEGMENTS             0x00001000
-#define DEBUG_FORMAT_USER_SMALL_NO_AUXILIARY_STATE        0x00002000
-#define DEBUG_FORMAT_USER_SMALL_FULL_AUXILIARY_STATE      0x00004000
-
-//
-// Dump information file types.
-//
-
-// Base dump file, returned when querying for dump files.
-#define DEBUG_DUMP_FILE_BASE           0xffffffff
-// Single file containing packed page file information.
-#define DEBUG_DUMP_FILE_PAGE_FILE_DUMP 0x00000000
-
-#undef INTERFACE
-#define INTERFACE IDebugClient2
-DECLARE_INTERFACE_(IDebugClient2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugClient.
-
-    // The following set of methods start
-    // the different kinds of debuggees.
-
-    // Begins a debug session using the kernel
-    // debugging protocol.  This method selects
-    // the protocol as the debuggee communication
-    // mechanism but does not initiate the communication
-    // itself.
-    STDMETHOD(AttachKernel)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PCSTR ConnectOptions
-        ) PURE;
-    STDMETHOD(GetKernelConnectionOptions)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG OptionsSize
-        ) PURE;
-    // Updates the connection options for a live
-    // kernel connection.  This can only be used
-    // to modify parameters for the connection, not
-    // to switch to a completely different kind of
-    // connection.
-    // This method is reentrant.
-    STDMETHOD(SetKernelConnectionOptions)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-
-    // Starts a process server for remote
-    // user-mode process control.
-    // The local process server is server zero.
-    STDMETHOD(StartProcessServer)(
-        THIS_
-        __in ULONG Flags,
-        __in PCSTR Options,
-        __in_opt __clr_reserved PVOID Reserved
-        ) PURE;
-    STDMETHOD(ConnectProcessServer)(
-        THIS_
-        __in PCSTR RemoteOptions,
-        __out PULONG64 Server
-        ) PURE;
-    STDMETHOD(DisconnectProcessServer)(
-        THIS_
-        __in ULONG64 Server
-        ) PURE;
-
-    // Enumerates and describes processes
-    // accessible through the given process server.
-    STDMETHOD(GetRunningProcessSystemIds)(
-        THIS_
-        __in ULONG64 Server,
-        __out_ecount_opt(Count) PULONG Ids,
-        __in ULONG Count,
-        __out_opt PULONG ActualCount
-        ) PURE;
-    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
-        THIS_
-        __in ULONG64 Server,
-        __in PCSTR ExeName,
-        __in ULONG Flags,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetRunningProcessDescription)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG SystemId,
-        __in ULONG Flags,
-        __out_ecount_opt(ExeNameSize) PSTR ExeName,
-        __in ULONG ExeNameSize,
-        __out_opt PULONG ActualExeNameSize,
-        __out_ecount_opt(DescriptionSize) PSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG ActualDescriptionSize
-        ) PURE;
-
-    // Attaches to a running user-mode process.
-    STDMETHOD(AttachProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Creates a new user-mode process for debugging.
-    // CreateFlags are as given to Win32s CreateProcess.
-    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
-    // must be specified.
-    STDMETHOD(CreateProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in PSTR CommandLine,
-        __in ULONG CreateFlags
-        ) PURE;
-    // Creates or attaches to a user-mode process, or both.
-    // If CommandLine is NULL this method operates as
-    // AttachProcess does.  If ProcessId is zero it
-    // operates as CreateProcess does.  If CommandLine is
-    // non-NULL and ProcessId is non-zero the method first
-    // starts a process with the given information but
-    // in a suspended state.  The engine then attaches to
-    // the indicated process.  Once the attach is successful
-    // the suspended process is resumed.  This provides
-    // synchronization between the new process and the
-    // attachment.
-    STDMETHOD(CreateProcessAndAttach)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PSTR CommandLine,
-        __in ULONG CreateFlags,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Gets and sets process control flags.
-    STDMETHOD(GetProcessOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Opens any kind of user- or kernel-mode dump file
-    // and begins a debug session with the information
-    // contained within it.
-    STDMETHOD(OpenDumpFile)(
-        THIS_
-        __in PCSTR DumpFile
-        ) PURE;
-    // Writes a dump file from the current session information.
-    // The kind of dump file written is determined by the
-    // kind of session and the type qualifier given.
-    // For example, if the current session is a kernel
-    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
-    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
-    STDMETHOD(WriteDumpFile)(
-        THIS_
-        __in PCSTR DumpFile,
-        __in ULONG Qualifier
-        ) PURE;
-
-    // Indicates that a remote client is ready to
-    // begin participating in the current session.
-    // HistoryLimit gives a character limit on
-    // the amount of output history to be sent.
-    STDMETHOD(ConnectSession)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG HistoryLimit
-        ) PURE;
-    // Indicates that the engine should start accepting
-    // remote connections. Options specifies connection types
-    // and their parameters.  Supported strings are:
-    //    npipe:Pipe=<Pipe name>
-    //    tcp:Port=<IP port>
-    STDMETHOD(StartServer)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-    // List the servers running on the given machine.
-    // Uses the line prefix.
-    STDMETHOD(OutputServers)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR Machine,
-        __in ULONG Flags
-        ) PURE;
-
-    // Attempts to terminate all processes in the debuggers list.
-    STDMETHOD(TerminateProcesses)(
-        THIS
-        ) PURE;
-    // Attempts to detach from all processes in the debuggers list.
-    // This requires OS support for debugger detach.
-    STDMETHOD(DetachProcesses)(
-        THIS
-        ) PURE;
-    // Stops the current debug session.  If a process
-    // was created or attached an active EndSession can
-    // terminate or detach from it.
-    // If a kernel connection was opened it will be closed but the
-    // target machine is otherwise unaffected.
-    STDMETHOD(EndSession)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // If a process was started and ran to completion
-    // this method can be used to retrieve its exit code.
-    STDMETHOD(GetExitCode)(
-        THIS_
-        __out PULONG Code
-        ) PURE;
-
-    // Client event callbacks are called on the thread
-    // of the client.  In order to give thread
-    // execution to the engine for callbacks all
-    // client threads should call DispatchCallbacks
-    // when they are idle.  Callbacks are only
-    // received when a thread calls DispatchCallbacks
-    // or WaitForEvent.  WaitForEvent can only be
-    // called by the thread that started the debug
-    // session so all other client threads should
-    // call DispatchCallbacks when possible.
-    // DispatchCallbacks returns when ExitDispatch is used
-    // to interrupt dispatch or when the timeout expires.
-    // DispatchCallbacks dispatches callbacks for all
-    // clients associated with the thread calling
-    // DispatchCallbacks.
-    // DispatchCallbacks returns S_FALSE when the
-    // timeout expires.
-    STDMETHOD(DispatchCallbacks)(
-        THIS_
-        __in ULONG Timeout
-        ) PURE;
-    // ExitDispatch can be used to interrupt callback
-    // dispatch when a client thread is needed by the
-    // client.  This method is reentrant and can
-    // be called from any thread.
-    STDMETHOD(ExitDispatch)(
-        THIS_
-        __in PDEBUG_CLIENT Client
-        ) PURE;
-
-    // Clients are specific to the thread that
-    // created them.  Calls from other threads
-    // fail immediately.  The CreateClient method
-    // is a notable exception; it allows creation
-    // of a new client for a new thread.
-    STDMETHOD(CreateClient)(
-        THIS_
-        __out PDEBUG_CLIENT* Client
-        ) PURE;
-
-    STDMETHOD(GetInputCallbacks)(
-        THIS_
-        __out PDEBUG_INPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetInputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_INPUT_CALLBACKS Callbacks
-        ) PURE;
-
-    // Output callback interfaces are described separately.
-    STDMETHOD(GetOutputCallbacks)(
-        THIS_
-        __out PDEBUG_OUTPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetOutputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_OUTPUT_CALLBACKS Callbacks
-        ) PURE;
-    // Output flags provide control over
-    // the distribution of output among clients.
-    // Output masks select which output streams
-    // should be sent to the output callbacks.
-    // Only Output calls with a mask that
-    // contains one of the output mask bits
-    // will be sent to the output callbacks.
-    // These methods are reentrant.
-    // If such access is not synchronized
-    // disruptions in output may occur.
-    STDMETHOD(GetOutputMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOutputMask)(
-        THIS_
-        __in ULONG Mask
-        ) PURE;
-    // These methods allow access to another clients
-    // output mask.  They are necessary for changing
-    // a clients output mask when it is
-    // waiting for events.  These methods are reentrant
-    // and can be called from any thread.
-    STDMETHOD(GetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __in ULONG Mask
-        ) PURE;
-    // Control the width of an output line for
-    // commands which produce formatted output.
-    // This setting is just a suggestion.
-    STDMETHOD(GetOutputWidth)(
-        THIS_
-        __out PULONG Columns
-        ) PURE;
-    STDMETHOD(SetOutputWidth)(
-        THIS_
-        __in ULONG Columns
-        ) PURE;
-    // Some of the engines output commands produce
-    // multiple lines of output.  A prefix can be
-    // set that the engine will automatically output
-    // for each line in that case, allowing a caller
-    // to control indentation or identifying marks.
-    // This is not a general setting for any output
-    // with a newline in it.  Methods which use
-    // the line prefix are marked in their documentation.
-    STDMETHOD(GetOutputLinePrefix)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PrefixSize
-        ) PURE;
-    STDMETHOD(SetOutputLinePrefix)(
-        THIS_
-        __in_opt PCSTR Prefix
-        ) PURE;
-
-    // Returns a string describing the machine
-    // and user this client represents.  The
-    // specific content of the string varies
-    // with operating system.  If the client is
-    // remotely connected some network information
-    // may also be present.
-    STDMETHOD(GetIdentity)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG IdentitySize
-        ) PURE;
-    // Format is a printf-like format string
-    // with one %s where the identity string should go.
-    STDMETHOD(OutputIdentity)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags,
-        __in PCSTR Format
-        ) PURE;
-
-    // Event callbacks allow a client to
-    // receive notification about changes
-    // during the debug session.
-    STDMETHOD(GetEventCallbacks)(
-        THIS_
-        __out PDEBUG_EVENT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetEventCallbacks)(
-        THIS_
-        __in_opt PDEBUG_EVENT_CALLBACKS Callbacks
-        ) PURE;
-
-    // The engine sometimes merges compatible callback
-    // requests to reduce callback overhead.  This is
-    // most noticeable with output as small pieces of
-    // output are collected into larger groups to
-    // reduce the overall number of output callback calls.
-    // A client can use this method to force all pending
-    // callbacks to be delivered.  This is rarely necessary.
-    STDMETHOD(FlushCallbacks)(
-        THIS
-        ) PURE;
-
-    // IDebugClient2.
-
-    // Functions similarly to WriteDumpFile with
-    // the addition of the ability to specify
-    // per-dump-format write control flags.
-    // Comment is not supported in all formats.
-    STDMETHOD(WriteDumpFile2)(
-        THIS_
-        __in PCSTR DumpFile,
-        __in ULONG Qualifier,
-        __in ULONG FormatFlags,
-        __in_opt PCSTR Comment
-        ) PURE;
-    // Registers additional files of supporting information
-    // for a dump file open.  This method must be called
-    // before OpenDumpFile is called.
-    // The files registered may be opened at the time
-    // this method is called but generally will not
-    // be used until OpenDumpFile is called.
-    STDMETHOD(AddDumpInformationFile)(
-        THIS_
-        __in PCSTR InfoFile,
-        __in ULONG Type
-        ) PURE;
-
-    // Requests that the remote process server shut down.
-    STDMETHOD(EndProcessServer)(
-        THIS_
-        __in ULONG64 Server
-        ) PURE;
-    // Waits for a started process server to
-    // exit.  Allows an application running a
-    // process server to monitor the process
-    // server so that it can tell when a remote
-    // client has asked for it to exit.
-    // Returns S_OK if the process server has
-    // shut down and S_FALSE for a timeout.
-    STDMETHOD(WaitForProcessServerEnd)(
-        THIS_
-        __in ULONG Timeout
-        ) PURE;
-
-    // Returns S_OK if the system is configured
-    // to allow kernel debugging.
-    STDMETHOD(IsKernelDebuggerEnabled)(
-        THIS
-        ) PURE;
-
-    // Attempts to terminate the current process.
-    // Exit process events for the process may be generated.
-    STDMETHOD(TerminateCurrentProcess)(
-        THIS
-        ) PURE;
-    // Attempts to detach from the current process.
-    // This requires OS support for debugger detach.
-    STDMETHOD(DetachCurrentProcess)(
-        THIS
-        ) PURE;
-    // Removes the process from the debuggers process
-    // list without making any other changes.  The process
-    // will still be marked as being debugged and will
-    // not run.  This allows a debugger to be shut down
-    // and a new debugger attached without taking the
-    // process out of the debugged state.
-    // This is only supported on some system versions.
-    STDMETHOD(AbandonCurrentProcess)(
-        THIS
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugClient3
-DECLARE_INTERFACE_(IDebugClient3, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugClient.
-
-    // The following set of methods start
-    // the different kinds of debuggees.
-
-    // Begins a debug session using the kernel
-    // debugging protocol.  This method selects
-    // the protocol as the debuggee communication
-    // mechanism but does not initiate the communication
-    // itself.
-    STDMETHOD(AttachKernel)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PCSTR ConnectOptions
-        ) PURE;
-    STDMETHOD(GetKernelConnectionOptions)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG OptionsSize
-        ) PURE;
-    // Updates the connection options for a live
-    // kernel connection.  This can only be used
-    // to modify parameters for the connection, not
-    // to switch to a completely different kind of
-    // connection.
-    // This method is reentrant.
-    STDMETHOD(SetKernelConnectionOptions)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-
-    // Starts a process server for remote
-    // user-mode process control.
-    // The local process server is server zero.
-    STDMETHOD(StartProcessServer)(
-        THIS_
-        __in ULONG Flags,
-        __in PCSTR Options,
-        __in_opt __clr_reserved PVOID Reserved
-        ) PURE;
-    STDMETHOD(ConnectProcessServer)(
-        THIS_
-        __in PCSTR RemoteOptions,
-        __out PULONG64 Server
-        ) PURE;
-    STDMETHOD(DisconnectProcessServer)(
-        THIS_
-        __in ULONG64 Server
-        ) PURE;
-
-    // Enumerates and describes processes
-    // accessible through the given process server.
-    STDMETHOD(GetRunningProcessSystemIds)(
-        THIS_
-        __in ULONG64 Server,
-        __out_ecount_opt(Count) PULONG Ids,
-        __in ULONG Count,
-        __out_opt PULONG ActualCount
-        ) PURE;
-    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
-        THIS_
-        __in ULONG64 Server,
-        __in PCSTR ExeName,
-        __in ULONG Flags,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetRunningProcessDescription)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG SystemId,
-        __in ULONG Flags,
-        __out_ecount_opt(ExeNameSize) PSTR ExeName,
-        __in ULONG ExeNameSize,
-        __out_opt PULONG ActualExeNameSize,
-        __out_ecount_opt(DescriptionSize) PSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG ActualDescriptionSize
-        ) PURE;
-
-    // Attaches to a running user-mode process.
-    STDMETHOD(AttachProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Creates a new user-mode process for debugging.
-    // CreateFlags are as given to Win32s CreateProcess.
-    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
-    // must be specified.
-    STDMETHOD(CreateProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in PSTR CommandLine,
-        __in ULONG CreateFlags
-        ) PURE;
-    // Creates or attaches to a user-mode process, or both.
-    // If CommandLine is NULL this method operates as
-    // AttachProcess does.  If ProcessId is zero it
-    // operates as CreateProcess does.  If CommandLine is
-    // non-NULL and ProcessId is non-zero the method first
-    // starts a process with the given information but
-    // in a suspended state.  The engine then attaches to
-    // the indicated process.  Once the attach is successful
-    // the suspended process is resumed.  This provides
-    // synchronization between the new process and the
-    // attachment.
-    STDMETHOD(CreateProcessAndAttach)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PSTR CommandLine,
-        __in ULONG CreateFlags,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Gets and sets process control flags.
-    STDMETHOD(GetProcessOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Opens any kind of user- or kernel-mode dump file
-    // and begins a debug session with the information
-    // contained within it.
-    STDMETHOD(OpenDumpFile)(
-        THIS_
-        __in PCSTR DumpFile
-        ) PURE;
-    // Writes a dump file from the current session information.
-    // The kind of dump file written is determined by the
-    // kind of session and the type qualifier given.
-    // For example, if the current session is a kernel
-    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
-    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
-    STDMETHOD(WriteDumpFile)(
-        THIS_
-        __in PCSTR DumpFile,
-        __in ULONG Qualifier
-        ) PURE;
-
-    // Indicates that a remote client is ready to
-    // begin participating in the current session.
-    // HistoryLimit gives a character limit on
-    // the amount of output history to be sent.
-    STDMETHOD(ConnectSession)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG HistoryLimit
-        ) PURE;
-    // Indicates that the engine should start accepting
-    // remote connections. Options specifies connection types
-    // and their parameters.  Supported strings are:
-    //    npipe:Pipe=<Pipe name>
-    //    tcp:Port=<IP port>
-    STDMETHOD(StartServer)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-    // List the servers running on the given machine.
-    // Uses the line prefix.
-    STDMETHOD(OutputServers)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR Machine,
-        __in ULONG Flags
-        ) PURE;
-
-    // Attempts to terminate all processes in the debuggers list.
-    STDMETHOD(TerminateProcesses)(
-        THIS
-        ) PURE;
-    // Attempts to detach from all processes in the debuggers list.
-    // This requires OS support for debugger detach.
-    STDMETHOD(DetachProcesses)(
-        THIS
-        ) PURE;
-    // Stops the current debug session.  If a process
-    // was created or attached an active EndSession can
-    // terminate or detach from it.
-    // If a kernel connection was opened it will be closed but the
-    // target machine is otherwise unaffected.
-    STDMETHOD(EndSession)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // If a process was started and ran to completion
-    // this method can be used to retrieve its exit code.
-    STDMETHOD(GetExitCode)(
-        THIS_
-        __out PULONG Code
-        ) PURE;
-
-    // Client event callbacks are called on the thread
-    // of the client.  In order to give thread
-    // execution to the engine for callbacks all
-    // client threads should call DispatchCallbacks
-    // when they are idle.  Callbacks are only
-    // received when a thread calls DispatchCallbacks
-    // or WaitForEvent.  WaitForEvent can only be
-    // called by the thread that started the debug
-    // session so all other client threads should
-    // call DispatchCallbacks when possible.
-    // DispatchCallbacks returns when ExitDispatch is used
-    // to interrupt dispatch or when the timeout expires.
-    // DispatchCallbacks dispatches callbacks for all
-    // clients associated with the thread calling
-    // DispatchCallbacks.
-    // DispatchCallbacks returns S_FALSE when the
-    // timeout expires.
-    STDMETHOD(DispatchCallbacks)(
-        THIS_
-        __in ULONG Timeout
-        ) PURE;
-    // ExitDispatch can be used to interrupt callback
-    // dispatch when a client thread is needed by the
-    // client.  This method is reentrant and can
-    // be called from any thread.
-    STDMETHOD(ExitDispatch)(
-        THIS_
-        __in PDEBUG_CLIENT Client
-        ) PURE;
-
-    // Clients are specific to the thread that
-    // created them.  Calls from other threads
-    // fail immediately.  The CreateClient method
-    // is a notable exception; it allows creation
-    // of a new client for a new thread.
-    STDMETHOD(CreateClient)(
-        THIS_
-        __out PDEBUG_CLIENT* Client
-        ) PURE;
-
-    STDMETHOD(GetInputCallbacks)(
-        THIS_
-        __out PDEBUG_INPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetInputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_INPUT_CALLBACKS Callbacks
-        ) PURE;
-
-    // Output callback interfaces are described separately.
-    STDMETHOD(GetOutputCallbacks)(
-        THIS_
-        __out PDEBUG_OUTPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetOutputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_OUTPUT_CALLBACKS Callbacks
-        ) PURE;
-    // Output flags provide control over
-    // the distribution of output among clients.
-    // Output masks select which output streams
-    // should be sent to the output callbacks.
-    // Only Output calls with a mask that
-    // contains one of the output mask bits
-    // will be sent to the output callbacks.
-    // These methods are reentrant.
-    // If such access is not synchronized
-    // disruptions in output may occur.
-    STDMETHOD(GetOutputMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOutputMask)(
-        THIS_
-        __in ULONG Mask
-        ) PURE;
-    // These methods allow access to another clients
-    // output mask.  They are necessary for changing
-    // a clients output mask when it is
-    // waiting for events.  These methods are reentrant
-    // and can be called from any thread.
-    STDMETHOD(GetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __in ULONG Mask
-        ) PURE;
-    // Control the width of an output line for
-    // commands which produce formatted output.
-    // This setting is just a suggestion.
-    STDMETHOD(GetOutputWidth)(
-        THIS_
-        __out PULONG Columns
-        ) PURE;
-    STDMETHOD(SetOutputWidth)(
-        THIS_
-        __in ULONG Columns
-        ) PURE;
-    // Some of the engines output commands produce
-    // multiple lines of output.  A prefix can be
-    // set that the engine will automatically output
-    // for each line in that case, allowing a caller
-    // to control indentation or identifying marks.
-    // This is not a general setting for any output
-    // with a newline in it.  Methods which use
-    // the line prefix are marked in their documentation.
-    STDMETHOD(GetOutputLinePrefix)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PrefixSize
-        ) PURE;
-    STDMETHOD(SetOutputLinePrefix)(
-        THIS_
-        __in_opt PCSTR Prefix
-        ) PURE;
-
-    // Returns a string describing the machine
-    // and user this client represents.  The
-    // specific content of the string varies
-    // with operating system.  If the client is
-    // remotely connected some network information
-    // may also be present.
-    STDMETHOD(GetIdentity)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG IdentitySize
-        ) PURE;
-    // Format is a printf-like format string
-    // with one %s where the identity string should go.
-    STDMETHOD(OutputIdentity)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags,
-        __in PCSTR Format
-        ) PURE;
-
-    // Event callbacks allow a client to
-    // receive notification about changes
-    // during the debug session.
-    STDMETHOD(GetEventCallbacks)(
-        THIS_
-        __out PDEBUG_EVENT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetEventCallbacks)(
-        THIS_
-        __in_opt PDEBUG_EVENT_CALLBACKS Callbacks
-        ) PURE;
-
-    // The engine sometimes merges compatible callback
-    // requests to reduce callback overhead.  This is
-    // most noticeable with output as small pieces of
-    // output are collected into larger groups to
-    // reduce the overall number of output callback calls.
-    // A client can use this method to force all pending
-    // callbacks to be delivered.  This is rarely necessary.
-    STDMETHOD(FlushCallbacks)(
-        THIS
-        ) PURE;
-
-    // IDebugClient2.
-
-    // Functions similarly to WriteDumpFile with
-    // the addition of the ability to specify
-    // per-dump-format write control flags.
-    // Comment is not supported in all formats.
-    STDMETHOD(WriteDumpFile2)(
-        THIS_
-        __in PCSTR DumpFile,
-        __in ULONG Qualifier,
-        __in ULONG FormatFlags,
-        __in_opt PCSTR Comment
-        ) PURE;
-    // Registers additional files of supporting information
-    // for a dump file open.  This method must be called
-    // before OpenDumpFile is called.
-    // The files registered may be opened at the time
-    // this method is called but generally will not
-    // be used until OpenDumpFile is called.
-    STDMETHOD(AddDumpInformationFile)(
-        THIS_
-        __in PCSTR InfoFile,
-        __in ULONG Type
-        ) PURE;
-
-    // Requests that the remote process server shut down.
-    STDMETHOD(EndProcessServer)(
-        THIS_
-        __in ULONG64 Server
-        ) PURE;
-    // Waits for a started process server to
-    // exit.  Allows an application running a
-    // process server to monitor the process
-    // server so that it can tell when a remote
-    // client has asked for it to exit.
-    // Returns S_OK if the process server has
-    // shut down and S_FALSE for a timeout.
-    STDMETHOD(WaitForProcessServerEnd)(
-        THIS_
-        __in ULONG Timeout
-        ) PURE;
-
-    // Returns S_OK if the system is configured
-    // to allow kernel debugging.
-    STDMETHOD(IsKernelDebuggerEnabled)(
-        THIS
-        ) PURE;
-
-    // Attempts to terminate the current process.
-    // Exit process events for the process may be generated.
-    STDMETHOD(TerminateCurrentProcess)(
-        THIS
-        ) PURE;
-    // Attempts to detach from the current process.
-    // This requires OS support for debugger detach.
-    STDMETHOD(DetachCurrentProcess)(
-        THIS
-        ) PURE;
-    // Removes the process from the debuggers process
-    // list without making any other changes.  The process
-    // will still be marked as being debugged and will
-    // not run.  This allows a debugger to be shut down
-    // and a new debugger attached without taking the
-    // process out of the debugged state.
-    // This is only supported on some system versions.
-    STDMETHOD(AbandonCurrentProcess)(
-        THIS
-        ) PURE;
-
-    // IDebugClient3.
-
-    STDMETHOD(GetRunningProcessSystemIdByExecutableNameWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in PCWSTR ExeName,
-        __in ULONG Flags,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetRunningProcessDescriptionWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG SystemId,
-        __in ULONG Flags,
-        __out_ecount_opt(ExeNameSize) PWSTR ExeName,
-        __in ULONG ExeNameSize,
-        __out_opt PULONG ActualExeNameSize,
-        __out_ecount_opt(DescriptionSize) PWSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG ActualDescriptionSize
-        ) PURE;
-
-    STDMETHOD(CreateProcessWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in PWSTR CommandLine,
-        __in ULONG CreateFlags
-        ) PURE;
-    STDMETHOD(CreateProcessAndAttachWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PWSTR CommandLine,
-        __in ULONG CreateFlags,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-};
-
-//
-// Special indices for GetDumpFile to return
-// alternate filenames.
-//
-
-// Special index that returns the name of the last .dmp file
-// that failed to load (whether directly or from inside a
-// .cab file).
-#define DEBUG_DUMP_FILE_LOAD_FAILED_INDEX  0xffffffff
-// Index that returns last cab file opened, this is needed to
-// get the name of original CAB file since debugger returns the
-// extracted dump file in the GetDumpFile method.
-#define DEBUG_DUMP_FILE_ORIGINAL_CAB_INDEX 0xfffffffe
-
-#undef INTERFACE
-#define INTERFACE IDebugClient4
-DECLARE_INTERFACE_(IDebugClient4, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugClient.
-
-    // The following set of methods start
-    // the different kinds of debuggees.
-
-    // Begins a debug session using the kernel
-    // debugging protocol.  This method selects
-    // the protocol as the debuggee communication
-    // mechanism but does not initiate the communication
-    // itself.
-    STDMETHOD(AttachKernel)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PCSTR ConnectOptions
-        ) PURE;
-    STDMETHOD(GetKernelConnectionOptions)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG OptionsSize
-        ) PURE;
-    // Updates the connection options for a live
-    // kernel connection.  This can only be used
-    // to modify parameters for the connection, not
-    // to switch to a completely different kind of
-    // connection.
-    // This method is reentrant.
-    STDMETHOD(SetKernelConnectionOptions)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-
-    // Starts a process server for remote
-    // user-mode process control.
-    // The local process server is server zero.
-    STDMETHOD(StartProcessServer)(
-        THIS_
-        __in ULONG Flags,
-        __in PCSTR Options,
-        __in_opt __clr_reserved PVOID Reserved
-        ) PURE;
-    STDMETHOD(ConnectProcessServer)(
-        THIS_
-        __in PCSTR RemoteOptions,
-        __out PULONG64 Server
-        ) PURE;
-    STDMETHOD(DisconnectProcessServer)(
-        THIS_
-        __in ULONG64 Server
-        ) PURE;
-
-    // Enumerates and describes processes
-    // accessible through the given process server.
-    STDMETHOD(GetRunningProcessSystemIds)(
-        THIS_
-        __in ULONG64 Server,
-        __out_ecount_opt(Count) PULONG Ids,
-        __in ULONG Count,
-        __out_opt PULONG ActualCount
-        ) PURE;
-    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
-        THIS_
-        __in ULONG64 Server,
-        __in PCSTR ExeName,
-        __in ULONG Flags,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetRunningProcessDescription)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG SystemId,
-        __in ULONG Flags,
-        __out_ecount_opt(ExeNameSize) PSTR ExeName,
-        __in ULONG ExeNameSize,
-        __out_opt PULONG ActualExeNameSize,
-        __out_ecount_opt(DescriptionSize) PSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG ActualDescriptionSize
-        ) PURE;
-
-    // Attaches to a running user-mode process.
-    STDMETHOD(AttachProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Creates a new user-mode process for debugging.
-    // CreateFlags are as given to Win32s CreateProcess.
-    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
-    // must be specified.
-    STDMETHOD(CreateProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in PSTR CommandLine,
-        __in ULONG CreateFlags
-        ) PURE;
-    // Creates or attaches to a user-mode process, or both.
-    // If CommandLine is NULL this method operates as
-    // AttachProcess does.  If ProcessId is zero it
-    // operates as CreateProcess does.  If CommandLine is
-    // non-NULL and ProcessId is non-zero the method first
-    // starts a process with the given information but
-    // in a suspended state.  The engine then attaches to
-    // the indicated process.  Once the attach is successful
-    // the suspended process is resumed.  This provides
-    // synchronization between the new process and the
-    // attachment.
-    STDMETHOD(CreateProcessAndAttach)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PSTR CommandLine,
-        __in ULONG CreateFlags,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Gets and sets process control flags.
-    STDMETHOD(GetProcessOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Opens any kind of user- or kernel-mode dump file
-    // and begins a debug session with the information
-    // contained within it.
-    STDMETHOD(OpenDumpFile)(
-        THIS_
-        __in PCSTR DumpFile
-        ) PURE;
-    // Writes a dump file from the current session information.
-    // The kind of dump file written is determined by the
-    // kind of session and the type qualifier given.
-    // For example, if the current session is a kernel
-    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
-    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
-    STDMETHOD(WriteDumpFile)(
-        THIS_
-        __in PCSTR DumpFile,
-        __in ULONG Qualifier
-        ) PURE;
-
-    // Indicates that a remote client is ready to
-    // begin participating in the current session.
-    // HistoryLimit gives a character limit on
-    // the amount of output history to be sent.
-    STDMETHOD(ConnectSession)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG HistoryLimit
-        ) PURE;
-    // Indicates that the engine should start accepting
-    // remote connections. Options specifies connection types
-    // and their parameters.  Supported strings are:
-    //    npipe:Pipe=<Pipe name>
-    //    tcp:Port=<IP port>
-    STDMETHOD(StartServer)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-    // List the servers running on the given machine.
-    // Uses the line prefix.
-    STDMETHOD(OutputServers)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR Machine,
-        __in ULONG Flags
-        ) PURE;
-
-    // Attempts to terminate all processes in the debuggers list.
-    STDMETHOD(TerminateProcesses)(
-        THIS
-        ) PURE;
-    // Attempts to detach from all processes in the debuggers list.
-    // This requires OS support for debugger detach.
-    STDMETHOD(DetachProcesses)(
-        THIS
-        ) PURE;
-    // Stops the current debug session.  If a process
-    // was created or attached an active EndSession can
-    // terminate or detach from it.
-    // If a kernel connection was opened it will be closed but the
-    // target machine is otherwise unaffected.
-    STDMETHOD(EndSession)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // If a process was started and ran to completion
-    // this method can be used to retrieve its exit code.
-    STDMETHOD(GetExitCode)(
-        THIS_
-        __out PULONG Code
-        ) PURE;
-
-    // Client event callbacks are called on the thread
-    // of the client.  In order to give thread
-    // execution to the engine for callbacks all
-    // client threads should call DispatchCallbacks
-    // when they are idle.  Callbacks are only
-    // received when a thread calls DispatchCallbacks
-    // or WaitForEvent.  WaitForEvent can only be
-    // called by the thread that started the debug
-    // session so all other client threads should
-    // call DispatchCallbacks when possible.
-    // DispatchCallbacks returns when ExitDispatch is used
-    // to interrupt dispatch or when the timeout expires.
-    // DispatchCallbacks dispatches callbacks for all
-    // clients associated with the thread calling
-    // DispatchCallbacks.
-    // DispatchCallbacks returns S_FALSE when the
-    // timeout expires.
-    STDMETHOD(DispatchCallbacks)(
-        THIS_
-        __in ULONG Timeout
-        ) PURE;
-    // ExitDispatch can be used to interrupt callback
-    // dispatch when a client thread is needed by the
-    // client.  This method is reentrant and can
-    // be called from any thread.
-    STDMETHOD(ExitDispatch)(
-        THIS_
-        __in PDEBUG_CLIENT Client
-        ) PURE;
-
-    // Clients are specific to the thread that
-    // created them.  Calls from other threads
-    // fail immediately.  The CreateClient method
-    // is a notable exception; it allows creation
-    // of a new client for a new thread.
-    STDMETHOD(CreateClient)(
-        THIS_
-        __out PDEBUG_CLIENT* Client
-        ) PURE;
-
-    STDMETHOD(GetInputCallbacks)(
-        THIS_
-        __out PDEBUG_INPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetInputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_INPUT_CALLBACKS Callbacks
-        ) PURE;
-
-    // Output callback interfaces are described separately.
-    STDMETHOD(GetOutputCallbacks)(
-        THIS_
-        __out PDEBUG_OUTPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetOutputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_OUTPUT_CALLBACKS Callbacks
-        ) PURE;
-    // Output flags provide control over
-    // the distribution of output among clients.
-    // Output masks select which output streams
-    // should be sent to the output callbacks.
-    // Only Output calls with a mask that
-    // contains one of the output mask bits
-    // will be sent to the output callbacks.
-    // These methods are reentrant.
-    // If such access is not synchronized
-    // disruptions in output may occur.
-    STDMETHOD(GetOutputMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOutputMask)(
-        THIS_
-        __in ULONG Mask
-        ) PURE;
-    // These methods allow access to another clients
-    // output mask.  They are necessary for changing
-    // a clients output mask when it is
-    // waiting for events.  These methods are reentrant
-    // and can be called from any thread.
-    STDMETHOD(GetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __in ULONG Mask
-        ) PURE;
-    // Control the width of an output line for
-    // commands which produce formatted output.
-    // This setting is just a suggestion.
-    STDMETHOD(GetOutputWidth)(
-        THIS_
-        __out PULONG Columns
-        ) PURE;
-    STDMETHOD(SetOutputWidth)(
-        THIS_
-        __in ULONG Columns
-        ) PURE;
-    // Some of the engines output commands produce
-    // multiple lines of output.  A prefix can be
-    // set that the engine will automatically output
-    // for each line in that case, allowing a caller
-    // to control indentation or identifying marks.
-    // This is not a general setting for any output
-    // with a newline in it.  Methods which use
-    // the line prefix are marked in their documentation.
-    STDMETHOD(GetOutputLinePrefix)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PrefixSize
-        ) PURE;
-    STDMETHOD(SetOutputLinePrefix)(
-        THIS_
-        __in_opt PCSTR Prefix
-        ) PURE;
-
-    // Returns a string describing the machine
-    // and user this client represents.  The
-    // specific content of the string varies
-    // with operating system.  If the client is
-    // remotely connected some network information
-    // may also be present.
-    STDMETHOD(GetIdentity)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG IdentitySize
-        ) PURE;
-    // Format is a printf-like format string
-    // with one %s where the identity string should go.
-    STDMETHOD(OutputIdentity)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags,
-        __in PCSTR Format
-        ) PURE;
-
-    // Event callbacks allow a client to
-    // receive notification about changes
-    // during the debug session.
-    STDMETHOD(GetEventCallbacks)(
-        THIS_
-        __out PDEBUG_EVENT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetEventCallbacks)(
-        THIS_
-        __in_opt PDEBUG_EVENT_CALLBACKS Callbacks
-        ) PURE;
-
-    // The engine sometimes merges compatible callback
-    // requests to reduce callback overhead.  This is
-    // most noticeable with output as small pieces of
-    // output are collected into larger groups to
-    // reduce the overall number of output callback calls.
-    // A client can use this method to force all pending
-    // callbacks to be delivered.  This is rarely necessary.
-    STDMETHOD(FlushCallbacks)(
-        THIS
-        ) PURE;
-
-    // IDebugClient2.
-
-    // Functions similarly to WriteDumpFile with
-    // the addition of the ability to specify
-    // per-dump-format write control flags.
-    // Comment is not supported in all formats.
-    STDMETHOD(WriteDumpFile2)(
-        THIS_
-        __in PCSTR DumpFile,
-        __in ULONG Qualifier,
-        __in ULONG FormatFlags,
-        __in_opt PCSTR Comment
-        ) PURE;
-    // Registers additional files of supporting information
-    // for a dump file open.  This method must be called
-    // before OpenDumpFile is called.
-    // The files registered may be opened at the time
-    // this method is called but generally will not
-    // be used until OpenDumpFile is called.
-    STDMETHOD(AddDumpInformationFile)(
-        THIS_
-        __in PCSTR InfoFile,
-        __in ULONG Type
-        ) PURE;
-
-    // Requests that the remote process server shut down.
-    STDMETHOD(EndProcessServer)(
-        THIS_
-        __in ULONG64 Server
-        ) PURE;
-    // Waits for a started process server to
-    // exit.  Allows an application running a
-    // process server to monitor the process
-    // server so that it can tell when a remote
-    // client has asked for it to exit.
-    // Returns S_OK if the process server has
-    // shut down and S_FALSE for a timeout.
-    STDMETHOD(WaitForProcessServerEnd)(
-        THIS_
-        __in ULONG Timeout
-        ) PURE;
-
-    // Returns S_OK if the system is configured
-    // to allow kernel debugging.
-    STDMETHOD(IsKernelDebuggerEnabled)(
-        THIS
-        ) PURE;
-
-    // Attempts to terminate the current process.
-    // Exit process events for the process may be generated.
-    STDMETHOD(TerminateCurrentProcess)(
-        THIS
-        ) PURE;
-    // Attempts to detach from the current process.
-    // This requires OS support for debugger detach.
-    STDMETHOD(DetachCurrentProcess)(
-        THIS
-        ) PURE;
-    // Removes the process from the debuggers process
-    // list without making any other changes.  The process
-    // will still be marked as being debugged and will
-    // not run.  This allows a debugger to be shut down
-    // and a new debugger attached without taking the
-    // process out of the debugged state.
-    // This is only supported on some system versions.
-    STDMETHOD(AbandonCurrentProcess)(
-        THIS
-        ) PURE;
-
-    // IDebugClient3.
-
-    STDMETHOD(GetRunningProcessSystemIdByExecutableNameWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in PCWSTR ExeName,
-        __in ULONG Flags,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetRunningProcessDescriptionWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG SystemId,
-        __in ULONG Flags,
-        __out_ecount_opt(ExeNameSize) PWSTR ExeName,
-        __in ULONG ExeNameSize,
-        __out_opt PULONG ActualExeNameSize,
-        __out_ecount_opt(DescriptionSize) PWSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG ActualDescriptionSize
-        ) PURE;
-
-    STDMETHOD(CreateProcessWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in PWSTR CommandLine,
-        __in ULONG CreateFlags
-        ) PURE;
-    STDMETHOD(CreateProcessAndAttachWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PWSTR CommandLine,
-        __in ULONG CreateFlags,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-
-    // IDebugClient4.
-
-    // In the following methods both a filename and a file
-    // handle can be passed in.  If a file handle is given
-    // the filename may be omitted, although providing it
-    // allows the debugger to properly report the name when
-    // queried.
-    // File handles cannot be used in remote calls.
-    STDMETHOD(OpenDumpFileWide)(
-        THIS_
-        __in_opt PCWSTR FileName,
-        __in ULONG64 FileHandle
-        ) PURE;
-    STDMETHOD(WriteDumpFileWide)(
-        THIS_
-        __in_opt PCWSTR FileName,
-        __in ULONG64 FileHandle,
-        __in ULONG Qualifier,
-        __in ULONG FormatFlags,
-        __in_opt PCWSTR Comment
-        ) PURE;
-    STDMETHOD(AddDumpInformationFileWide)(
-        THIS_
-        __in_opt PCWSTR FileName,
-        __in ULONG64 FileHandle,
-        __in ULONG Type
-        ) PURE;
-    // These methods can be used to retrieve
-    // file information for all targets that
-    // involve files.
-    STDMETHOD(GetNumberDumpFiles)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetDumpFile)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Handle,
-        __out PULONG Type
-        ) PURE;
-    STDMETHOD(GetDumpFileWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Handle,
-        __out PULONG Type
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugClient5
-DECLARE_INTERFACE_(IDebugClient5, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugClient.
-
-    // The following set of methods start
-    // the different kinds of debuggees.
-
-    // Begins a debug session using the kernel
-    // debugging protocol.  This method selects
-    // the protocol as the debuggee communication
-    // mechanism but does not initiate the communication
-    // itself.
-    STDMETHOD(AttachKernel)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PCSTR ConnectOptions
-        ) PURE;
-    STDMETHOD(GetKernelConnectionOptions)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG OptionsSize
-        ) PURE;
-    // Updates the connection options for a live
-    // kernel connection.  This can only be used
-    // to modify parameters for the connection, not
-    // to switch to a completely different kind of
-    // connection.
-    // This method is reentrant.
-    STDMETHOD(SetKernelConnectionOptions)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-
-    // Starts a process server for remote
-    // user-mode process control.
-    // The local process server is server zero.
-    STDMETHOD(StartProcessServer)(
-        THIS_
-        __in ULONG Flags,
-        __in PCSTR Options,
-        __in_opt __clr_reserved PVOID Reserved
-        ) PURE;
-    STDMETHOD(ConnectProcessServer)(
-        THIS_
-        __in PCSTR RemoteOptions,
-        __out PULONG64 Server
-        ) PURE;
-    STDMETHOD(DisconnectProcessServer)(
-        THIS_
-        __in ULONG64 Server
-        ) PURE;
-
-    // Enumerates and describes processes
-    // accessible through the given process server.
-    STDMETHOD(GetRunningProcessSystemIds)(
-        THIS_
-        __in ULONG64 Server,
-        __out_ecount_opt(Count) PULONG Ids,
-        __in ULONG Count,
-        __out_opt PULONG ActualCount
-        ) PURE;
-    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
-        THIS_
-        __in ULONG64 Server,
-        __in PCSTR ExeName,
-        __in ULONG Flags,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetRunningProcessDescription)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG SystemId,
-        __in ULONG Flags,
-        __out_ecount_opt(ExeNameSize) PSTR ExeName,
-        __in ULONG ExeNameSize,
-        __out_opt PULONG ActualExeNameSize,
-        __out_ecount_opt(DescriptionSize) PSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG ActualDescriptionSize
-        ) PURE;
-
-    // Attaches to a running user-mode process.
-    STDMETHOD(AttachProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Creates a new user-mode process for debugging.
-    // CreateFlags are as given to Win32s CreateProcess.
-    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
-    // must be specified.
-    STDMETHOD(CreateProcess)(
-        THIS_
-        __in ULONG64 Server,
-        __in PSTR CommandLine,
-        __in ULONG CreateFlags
-        ) PURE;
-    // Creates or attaches to a user-mode process, or both.
-    // If CommandLine is NULL this method operates as
-    // AttachProcess does.  If ProcessId is zero it
-    // operates as CreateProcess does.  If CommandLine is
-    // non-NULL and ProcessId is non-zero the method first
-    // starts a process with the given information but
-    // in a suspended state.  The engine then attaches to
-    // the indicated process.  Once the attach is successful
-    // the suspended process is resumed.  This provides
-    // synchronization between the new process and the
-    // attachment.
-    STDMETHOD(CreateProcessAndAttach)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PSTR CommandLine,
-        __in ULONG CreateFlags,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    // Gets and sets process control flags.
-    STDMETHOD(GetProcessOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetProcessOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Opens any kind of user- or kernel-mode dump file
-    // and begins a debug session with the information
-    // contained within it.
-    STDMETHOD(OpenDumpFile)(
-        THIS_
-        __in PCSTR DumpFile
-        ) PURE;
-    // Writes a dump file from the current session information.
-    // The kind of dump file written is determined by the
-    // kind of session and the type qualifier given.
-    // For example, if the current session is a kernel
-    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
-    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
-    STDMETHOD(WriteDumpFile)(
-        THIS_
-        __in PCSTR DumpFile,
-        __in ULONG Qualifier
-        ) PURE;
-
-    // Indicates that a remote client is ready to
-    // begin participating in the current session.
-    // HistoryLimit gives a character limit on
-    // the amount of output history to be sent.
-    STDMETHOD(ConnectSession)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG HistoryLimit
-        ) PURE;
-    // Indicates that the engine should start accepting
-    // remote connections. Options specifies connection types
-    // and their parameters.  Supported strings are:
-    //    npipe:Pipe=<Pipe name>
-    //    tcp:Port=<IP port>
-    STDMETHOD(StartServer)(
-        THIS_
-        __in PCSTR Options
-        ) PURE;
-    // List the servers running on the given machine.
-    // Uses the line prefix.
-    STDMETHOD(OutputServers)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR Machine,
-        __in ULONG Flags
-        ) PURE;
-
-    // Attempts to terminate all processes in the debuggers list.
-    STDMETHOD(TerminateProcesses)(
-        THIS
-        ) PURE;
-    // Attempts to detach from all processes in the debuggers list.
-    // This requires OS support for debugger detach.
-    STDMETHOD(DetachProcesses)(
-        THIS
-        ) PURE;
-    // Stops the current debug session.  If a process
-    // was created or attached an active EndSession can
-    // terminate or detach from it.
-    // If a kernel connection was opened it will be closed but the
-    // target machine is otherwise unaffected.
-    STDMETHOD(EndSession)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // If a process was started and ran to completion
-    // this method can be used to retrieve its exit code.
-    STDMETHOD(GetExitCode)(
-        THIS_
-        __out PULONG Code
-        ) PURE;
-
-    // Client event callbacks are called on the thread
-    // of the client.  In order to give thread
-    // execution to the engine for callbacks all
-    // client threads should call DispatchCallbacks
-    // when they are idle.  Callbacks are only
-    // received when a thread calls DispatchCallbacks
-    // or WaitForEvent.  WaitForEvent can only be
-    // called by the thread that started the debug
-    // session so all other client threads should
-    // call DispatchCallbacks when possible.
-    // DispatchCallbacks returns when ExitDispatch is used
-    // to interrupt dispatch or when the timeout expires.
-    // DispatchCallbacks dispatches callbacks for all
-    // clients associated with the thread calling
-    // DispatchCallbacks.
-    // DispatchCallbacks returns S_FALSE when the
-    // timeout expires.
-    STDMETHOD(DispatchCallbacks)(
-        THIS_
-        __in ULONG Timeout
-        ) PURE;
-    // ExitDispatch can be used to interrupt callback
-    // dispatch when a client thread is needed by the
-    // client.  This method is reentrant and can
-    // be called from any thread.
-    STDMETHOD(ExitDispatch)(
-        THIS_
-        __in PDEBUG_CLIENT Client
-        ) PURE;
-
-    // Clients are specific to the thread that
-    // created them.  Calls from other threads
-    // fail immediately.  The CreateClient method
-    // is a notable exception; it allows creation
-    // of a new client for a new thread.
-    STDMETHOD(CreateClient)(
-        THIS_
-        __out PDEBUG_CLIENT* Client
-        ) PURE;
-
-    STDMETHOD(GetInputCallbacks)(
-        THIS_
-        __out PDEBUG_INPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetInputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_INPUT_CALLBACKS Callbacks
-        ) PURE;
-
-    // Output callback interfaces are described separately.
-    STDMETHOD(GetOutputCallbacks)(
-        THIS_
-        __out PDEBUG_OUTPUT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetOutputCallbacks)(
-        THIS_
-        __in_opt PDEBUG_OUTPUT_CALLBACKS Callbacks
-        ) PURE;
-    // Output flags provide control over
-    // the distribution of output among clients.
-    // Output masks select which output streams
-    // should be sent to the output callbacks.
-    // Only Output calls with a mask that
-    // contains one of the output mask bits
-    // will be sent to the output callbacks.
-    // These methods are reentrant.
-    // If such access is not synchronized
-    // disruptions in output may occur.
-    STDMETHOD(GetOutputMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOutputMask)(
-        THIS_
-        __in ULONG Mask
-        ) PURE;
-    // These methods allow access to another clients
-    // output mask.  They are necessary for changing
-    // a clients output mask when it is
-    // waiting for events.  These methods are reentrant
-    // and can be called from any thread.
-    STDMETHOD(GetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetOtherOutputMask)(
-        THIS_
-        __in PDEBUG_CLIENT Client,
-        __in ULONG Mask
-        ) PURE;
-    // Control the width of an output line for
-    // commands which produce formatted output.
-    // This setting is just a suggestion.
-    STDMETHOD(GetOutputWidth)(
-        THIS_
-        __out PULONG Columns
-        ) PURE;
-    STDMETHOD(SetOutputWidth)(
-        THIS_
-        __in ULONG Columns
-        ) PURE;
-    // Some of the engines output commands produce
-    // multiple lines of output.  A prefix can be
-    // set that the engine will automatically output
-    // for each line in that case, allowing a caller
-    // to control indentation or identifying marks.
-    // This is not a general setting for any output
-    // with a newline in it.  Methods which use
-    // the line prefix are marked in their documentation.
-    STDMETHOD(GetOutputLinePrefix)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PrefixSize
-        ) PURE;
-    STDMETHOD(SetOutputLinePrefix)(
-        THIS_
-        __in_opt PCSTR Prefix
-        ) PURE;
-
-    // Returns a string describing the machine
-    // and user this client represents.  The
-    // specific content of the string varies
-    // with operating system.  If the client is
-    // remotely connected some network information
-    // may also be present.
-    STDMETHOD(GetIdentity)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG IdentitySize
-        ) PURE;
-    // Format is a printf-like format string
-    // with one %s where the identity string should go.
-    STDMETHOD(OutputIdentity)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags,
-        __in PCSTR Format
-        ) PURE;
-
-    // Event callbacks allow a client to
-    // receive notification about changes
-    // during the debug session.
-    STDMETHOD(GetEventCallbacks)(
-        THIS_
-        __out PDEBUG_EVENT_CALLBACKS* Callbacks
-        ) PURE;
-    STDMETHOD(SetEventCallbacks)(
-        THIS_
-        __in_opt PDEBUG_EVENT_CALLBACKS Callbacks
-        ) PURE;
-
-    // The engine sometimes merges compatible callback
-    // requests to reduce callback overhead.  This is
-    // most noticeable with output as small pieces of
-    // output are collected into larger groups to
-    // reduce the overall number of output callback calls.
-    // A client can use this method to force all pending
-    // callbacks to be delivered.  This is rarely necessary.
-    STDMETHOD(FlushCallbacks)(
-        THIS
-        ) PURE;
-
-    // IDebugClient2.
-
-    // Functions similarly to WriteDumpFile with
-    // the addition of the ability to specify
-    // per-dump-format write control flags.
-    // Comment is not supported in all formats.
-    STDMETHOD(WriteDumpFile2)(
-        THIS_
-        __in PCSTR DumpFile,
-        __in ULONG Qualifier,
-        __in ULONG FormatFlags,
-        __in_opt PCSTR Comment
-        ) PURE;
-    // Registers additional files of supporting information
-    // for a dump file open.  This method must be called
-    // before OpenDumpFile is called.
-    // The files registered may be opened at the time
-    // this method is called but generally will not
-    // be used until OpenDumpFile is called.
-    STDMETHOD(AddDumpInformationFile)(
-        THIS_
-        __in PCSTR InfoFile,
-        __in ULONG Type
-        ) PURE;
-
-    // Requests that the remote process server shut down.
-    STDMETHOD(EndProcessServer)(
-        THIS_
-        __in ULONG64 Server
-        ) PURE;
-    // Waits for a started process server to
-    // exit.  Allows an application running a
-    // process server to monitor the process
-    // server so that it can tell when a remote
-    // client has asked for it to exit.
-    // Returns S_OK if the process server has
-    // shut down and S_FALSE for a timeout.
-    STDMETHOD(WaitForProcessServerEnd)(
-        THIS_
-        __in ULONG Timeout
-        ) PURE;
-
-    // Returns S_OK if the system is configured
-    // to allow kernel debugging.
-    STDMETHOD(IsKernelDebuggerEnabled)(
-        THIS
-        ) PURE;
-
-    // Attempts to terminate the current process.
-    // Exit process events for the process may be generated.
-    STDMETHOD(TerminateCurrentProcess)(
-        THIS
-        ) PURE;
-    // Attempts to detach from the current process.
-    // This requires OS support for debugger detach.
-    STDMETHOD(DetachCurrentProcess)(
-        THIS
-        ) PURE;
-    // Removes the process from the debuggers process
-    // list without making any other changes.  The process
-    // will still be marked as being debugged and will
-    // not run.  This allows a debugger to be shut down
-    // and a new debugger attached without taking the
-    // process out of the debugged state.
-    // This is only supported on some system versions.
-    STDMETHOD(AbandonCurrentProcess)(
-        THIS
-        ) PURE;
-
-    // IDebugClient3.
-
-    STDMETHOD(GetRunningProcessSystemIdByExecutableNameWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in PCWSTR ExeName,
-        __in ULONG Flags,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetRunningProcessDescriptionWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in ULONG SystemId,
-        __in ULONG Flags,
-        __out_ecount_opt(ExeNameSize) PWSTR ExeName,
-        __in ULONG ExeNameSize,
-        __out_opt PULONG ActualExeNameSize,
-        __out_ecount_opt(DescriptionSize) PWSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG ActualDescriptionSize
-        ) PURE;
-
-    STDMETHOD(CreateProcessWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in PWSTR CommandLine,
-        __in ULONG CreateFlags
-        ) PURE;
-    STDMETHOD(CreateProcessAndAttachWide)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PWSTR CommandLine,
-        __in ULONG CreateFlags,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-
-    // IDebugClient4.
-
-    // In the following methods both a filename and a file
-    // handle can be passed in.  If a file handle is given
-    // the filename may be omitted, although providing it
-    // allows the debugger to properly report the name when
-    // queried.
-    // File handles cannot be used in remote calls.
-    STDMETHOD(OpenDumpFileWide)(
-        THIS_
-        __in_opt PCWSTR FileName,
-        __in ULONG64 FileHandle
-        ) PURE;
-    STDMETHOD(WriteDumpFileWide)(
-        THIS_
-        __in_opt PCWSTR FileName,
-        __in ULONG64 FileHandle,
-        __in ULONG Qualifier,
-        __in ULONG FormatFlags,
-        __in_opt PCWSTR Comment
-        ) PURE;
-    STDMETHOD(AddDumpInformationFileWide)(
-        THIS_
-        __in_opt PCWSTR FileName,
-        __in ULONG64 FileHandle,
-        __in ULONG Type
-        ) PURE;
-    // These methods can be used to retrieve
-    // file information for all targets that
-    // involve files.
-    STDMETHOD(GetNumberDumpFiles)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetDumpFile)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Handle,
-        __out PULONG Type
-        ) PURE;
-    STDMETHOD(GetDumpFileWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Handle,
-        __out PULONG Type
-        ) PURE;
-
-    // IDebugClient5.
-
-    STDMETHOD(AttachKernelWide)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PCWSTR ConnectOptions
-        ) PURE;
-    STDMETHOD(GetKernelConnectionOptionsWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG OptionsSize
-        ) PURE;
-    STDMETHOD(SetKernelConnectionOptionsWide)(
-        THIS_
-        __in PCWSTR Options
-        ) PURE;
-
-    STDMETHOD(StartProcessServerWide)(
-        THIS_
-        __in ULONG Flags,
-        __in PCWSTR Options,
-        __in_opt __clr_reserved PVOID Reserved
-        ) PURE;
-    STDMETHOD(ConnectProcessServerWide)(
-        THIS_
-        __in PCWSTR RemoteOptions,
-        __out PULONG64 Server
-        ) PURE;
-
-    STDMETHOD(StartServerWide)(
-        THIS_
-        __in PCWSTR Options
-        ) PURE;
-    STDMETHOD(OutputServersWide)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCWSTR Machine,
-        __in ULONG Flags
-        ) PURE;
-
-    STDMETHOD(GetOutputCallbacksWide)(
-        THIS_
-        __out PDEBUG_OUTPUT_CALLBACKS_WIDE* Callbacks
-        ) PURE;
-    STDMETHOD(SetOutputCallbacksWide)(
-        THIS_
-        __in PDEBUG_OUTPUT_CALLBACKS_WIDE Callbacks
-        ) PURE;
-    STDMETHOD(GetOutputLinePrefixWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PrefixSize
-        ) PURE;
-    STDMETHOD(SetOutputLinePrefixWide)(
-        THIS_
-        __in_opt PCWSTR Prefix
-        ) PURE;
-
-    STDMETHOD(GetIdentityWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG IdentitySize
-        ) PURE;
-    STDMETHOD(OutputIdentityWide)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags,
-        __in PCWSTR Format
-        ) PURE;
-
-    STDMETHOD(GetEventCallbacksWide)(
-        THIS_
-        __out PDEBUG_EVENT_CALLBACKS_WIDE* Callbacks
-        ) PURE;
-    STDMETHOD(SetEventCallbacksWide)(
-        THIS_
-        __in PDEBUG_EVENT_CALLBACKS_WIDE Callbacks
-        ) PURE;
-
-    STDMETHOD(CreateProcess2)(
-        THIS_
-        __in ULONG64 Server,
-        __in PSTR CommandLine,
-        __in_bcount(OptionsBufferSize) PVOID OptionsBuffer,
-        __in ULONG OptionsBufferSize,
-        __in_opt PCSTR InitialDirectory,
-        __in_opt PCSTR Environment
-        ) PURE;
-    STDMETHOD(CreateProcess2Wide)(
-        THIS_
-        __in ULONG64 Server,
-        __in PWSTR CommandLine,
-        __in_bcount(OptionsBufferSize) PVOID OptionsBuffer,
-        __in ULONG OptionsBufferSize,
-        __in_opt PCWSTR InitialDirectory,
-        __in_opt PCWSTR Environment
-        ) PURE;
-    STDMETHOD(CreateProcessAndAttach2)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PSTR CommandLine,
-        __in_bcount(OptionsBufferSize) PVOID OptionsBuffer,
-        __in ULONG OptionsBufferSize,
-        __in_opt PCSTR InitialDirectory,
-        __in_opt PCSTR Environment,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-    STDMETHOD(CreateProcessAndAttach2Wide)(
-        THIS_
-        __in ULONG64 Server,
-        __in_opt PWSTR CommandLine,
-        __in_bcount(OptionsBufferSize) PVOID OptionsBuffer,
-        __in ULONG OptionsBufferSize,
-        __in_opt PCWSTR InitialDirectory,
-        __in_opt PCWSTR Environment,
-        __in ULONG ProcessId,
-        __in ULONG AttachFlags
-        ) PURE;
-
-    // Helpers for saving and restoring the
-    // current output line prefix.
-    STDMETHOD(PushOutputLinePrefix)(
-        THIS_
-        __in_opt PCSTR NewPrefix,
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(PushOutputLinePrefixWide)(
-        THIS_
-        __in_opt PCWSTR NewPrefix,
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(PopOutputLinePrefix)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-
-    // Queries to determine if any clients
-    // could potentially respond to the given callback.
-    STDMETHOD(GetNumberInputCallbacks)(
-        THIS_
-        __out PULONG Count
-        ) PURE;
-    STDMETHOD(GetNumberOutputCallbacks)(
-        THIS_
-        __out PULONG Count
-        ) PURE;
-    STDMETHOD(GetNumberEventCallbacks)(
-        THIS_
-        __in ULONG EventFlags,
-        __out PULONG Count
-        ) PURE;
-
-    // Control over locking the session against
-    // undesired quits.  The quit lock string
-    // cannot be retrieved from a secure session.
-    STDMETHOD(GetQuitLockString)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-    STDMETHOD(SetQuitLockString)(
-        THIS_
-        __in PCSTR String
-        ) PURE;
-    STDMETHOD(GetQuitLockStringWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-    STDMETHOD(SetQuitLockStringWide)(
-        THIS_
-        __in PCWSTR String
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugControl.
-//
-//----------------------------------------------------------------------------
-
-// Execution status codes used for waiting,
-// for returning current status and for
-// event method return values.
-#define DEBUG_STATUS_NO_CHANGE           0
-#define DEBUG_STATUS_GO                  1
-#define DEBUG_STATUS_GO_HANDLED          2
-#define DEBUG_STATUS_GO_NOT_HANDLED      3
-#define DEBUG_STATUS_STEP_OVER           4
-#define DEBUG_STATUS_STEP_INTO           5
-#define DEBUG_STATUS_BREAK               6
-#define DEBUG_STATUS_NO_DEBUGGEE         7
-#define DEBUG_STATUS_STEP_BRANCH         8
-#define DEBUG_STATUS_IGNORE_EVENT        9
-#define DEBUG_STATUS_RESTART_REQUESTED   10
-#define DEBUG_STATUS_REVERSE_GO          11
-#define DEBUG_STATUS_REVERSE_STEP_BRANCH 12
-#define DEBUG_STATUS_REVERSE_STEP_OVER   13
-#define DEBUG_STATUS_REVERSE_STEP_INTO   14
-
-#define DEBUG_STATUS_MASK                0xf
-
-// This bit is added in DEBUG_CES_EXECUTION_STATUS
-// notifications when the engines execution status
-// is changing due to operations performed during
-// a wait, such as making synchronous callbacks.  If
-// the bit is not set the execution status is changing
-// due to a wait being satisfied.
-#define DEBUG_STATUS_INSIDE_WAIT  0x100000000
-// This bit is added in DEBUG_CES_EXECUTION_STATUS
-// notifications when the engines execution status
-// update is coming after a wait has timed-out.
-// It indicates that the execution status change
-// was not due to an actual event.
-#define DEBUG_STATUS_WAIT_TIMEOUT 0x200000000
-
-// Output control flags.
-// Output generated by methods called by this
-// client will be sent only to this clients
-// output callbacks.
-#define DEBUG_OUTCTL_THIS_CLIENT       0x00000000
-// Output will be sent to all clients.
-#define DEBUG_OUTCTL_ALL_CLIENTS       0x00000001
-// Output will be sent to all clients except
-// the client generating the output.
-#define DEBUG_OUTCTL_ALL_OTHER_CLIENTS 0x00000002
-// Output will be discarded immediately and will not
-// be logged or sent to callbacks.
-#define DEBUG_OUTCTL_IGNORE            0x00000003
-// Output will be logged but not sent to callbacks.
-#define DEBUG_OUTCTL_LOG_ONLY          0x00000004
-// All send control bits.
-#define DEBUG_OUTCTL_SEND_MASK         0x00000007
-// Do not place output from this client in
-// the global log file.
-#define DEBUG_OUTCTL_NOT_LOGGED        0x00000008
-// Send output to clients regardless of whether the
-// mask allows it or not.
-#define DEBUG_OUTCTL_OVERRIDE_MASK     0x00000010
-// Text is markup instead of plain text.
-#define DEBUG_OUTCTL_DML               0x00000020
-
-// Special values which mean leave the output settings
-// unchanged.
-#define DEBUG_OUTCTL_AMBIENT_DML       0xfffffffe
-#define DEBUG_OUTCTL_AMBIENT_TEXT      0xffffffff
-
-// Old ambient flag which maps to text.
-#define DEBUG_OUTCTL_AMBIENT           DEBUG_OUTCTL_AMBIENT_TEXT
-
-// Interrupt types.
-// Force a break in if the debuggee is running.
-#define DEBUG_INTERRUPT_ACTIVE  0
-// Notify but do not force a break in.
-#define DEBUG_INTERRUPT_PASSIVE 1
-// Try and get the current engine operation to
-// complete so that the engine will be available
-// again.  If no wait is active this is the same
-// as a passive interrupt.  If a wait is active
-// this will try to cause the wait to fail without
-// breaking in to the debuggee.  There is
-// no guarantee that issuing an exit interrupt
-// will cause the engine to become available
-// as not all operations are arbitrarily
-// interruptible.
-#define DEBUG_INTERRUPT_EXIT    2
-
-// OutputCurrentState flags.  These flags
-// allow a particular type of information
-// to be displayed but do not guarantee
-// that it will be displayed.  Other global
-// settings may override these flags or
-// the particular state may not be available.
-// For example, source line information may
-// not be present so source line information
-// may not be displayed.
-#define DEBUG_CURRENT_DEFAULT     0x0000000f
-#define DEBUG_CURRENT_SYMBOL      0x00000001
-#define DEBUG_CURRENT_DISASM      0x00000002
-#define DEBUG_CURRENT_REGISTERS   0x00000004
-#define DEBUG_CURRENT_SOURCE_LINE 0x00000008
-
-//
-// Disassemble flags.
-//
-
-// Compute the effective address from current register
-// information and display it.
-#define DEBUG_DISASM_EFFECTIVE_ADDRESS  0x00000001
-// If the current disassembly offset has an exact
-// symbol match output the symbol.
-#define DEBUG_DISASM_MATCHING_SYMBOLS   0x00000002
-// Output the source line number for each disassembly offset.
-#define DEBUG_DISASM_SOURCE_LINE_NUMBER 0x00000004
-// Output the source file name (no path) for each disassembly offset.
-#define DEBUG_DISASM_SOURCE_FILE_NAME   0x00000008
-
-// Code interpretation levels for stepping
-// and other operations.
-#define DEBUG_LEVEL_SOURCE   0
-#define DEBUG_LEVEL_ASSEMBLY 1
-
-// Engine control flags.
-#define DEBUG_ENGOPT_IGNORE_DBGHELP_VERSION      0x00000001
-#define DEBUG_ENGOPT_IGNORE_EXTENSION_VERSIONS   0x00000002
-// If neither allow nor disallow is specified
-// the engine will pick one based on what kind
-// of debugging is going on.
-#define DEBUG_ENGOPT_ALLOW_NETWORK_PATHS         0x00000004
-#define DEBUG_ENGOPT_DISALLOW_NETWORK_PATHS      0x00000008
-#define DEBUG_ENGOPT_NETWORK_PATHS               (0x00000004 | 0x00000008)
-// Ignore loader-generated first-chance exceptions.
-#define DEBUG_ENGOPT_IGNORE_LOADER_EXCEPTIONS    0x00000010
-// Break in on a debuggees initial event.  In user-mode
-// this will break at the initial system breakpoint
-// for every created process.  In kernel-mode it
-// will attempt break in on the target at the first
-// WaitForEvent.
-#define DEBUG_ENGOPT_INITIAL_BREAK               0x00000020
-// Break in on the first module load for a debuggee.
-#define DEBUG_ENGOPT_INITIAL_MODULE_BREAK        0x00000040
-// Break in on a debuggees final event.  In user-mode
-// this will break on process exit for every process.
-// In kernel-mode it currently does nothing.
-#define DEBUG_ENGOPT_FINAL_BREAK                 0x00000080
-// By default Execute will repeat the last command
-// if it is given an empty string.  The flags to
-// Execute can override this behavior for a single
-// command or this engine option can be used to
-// change the default globally.
-#define DEBUG_ENGOPT_NO_EXECUTE_REPEAT           0x00000100
-// Disable places in the engine that have fallback
-// code when presented with incomplete information.
-//   1. Fails minidump module loads unless matching
-//      executables can be mapped.
-#define DEBUG_ENGOPT_FAIL_INCOMPLETE_INFORMATION 0x00000200
-// Allow the debugger to manipulate page protections
-// in order to insert code breakpoints on pages that
-// do not have write access.  This option is not on
-// by default as it allows breakpoints to be set
-// in potentially hazardous memory areas.
-#define DEBUG_ENGOPT_ALLOW_READ_ONLY_BREAKPOINTS 0x00000400
-// When using a software (bp/bu) breakpoint in code
-// that will be executed by multiple threads it is
-// possible for breakpoint management to cause the
-// breakpoint to be missed or for spurious single-step
-// exceptions to be generated.  This flag suspends
-// all but the active thread when doing breakpoint
-// management and thereby avoids multithreading
-// problems.  Care must be taken when using it, though,
-// as the suspension of threads can cause deadlocks
-// if the suspended threads are holding resources that
-// the active thread needs.  Additionally, there
-// are still rare situations where problems may
-// occur, but setting this flag corrects nearly
-// all multithreading issues with software breakpoints.
-// Thread-restricted stepping and execution supersedes
-// this flags effect.
-// This flag is ignored in kernel sessions as there
-// is no way to restrict processor execution.
-#define DEBUG_ENGOPT_SYNCHRONIZE_BREAKPOINTS     0x00000800
-// Disallows executing shell commands through the
-// engine with .shell (!!).
-#define DEBUG_ENGOPT_DISALLOW_SHELL_COMMANDS     0x00001000
-// Turns on "quiet mode", a somewhat less verbose mode
-// of operation supported in the debuggers that were
-// superseded by dbgeng.dll.  This equates to the KDQUIET
-// environment variable.
-#define DEBUG_ENGOPT_KD_QUIET_MODE               0x00002000
-// Disables managed code debugging support in the engine.
-// If managed support is already in use this flag has no effect.
-#define DEBUG_ENGOPT_DISABLE_MANAGED_SUPPORT     0x00004000
-// Disables symbol loading for all modules created
-// after this flag is set.
-#define DEBUG_ENGOPT_DISABLE_MODULE_SYMBOL_LOAD  0x00008000
-// Disables execution commands.
-#define DEBUG_ENGOPT_DISABLE_EXECUTION_COMMANDS  0x00010000
-// Disallows mapping of image files from disk for any use.
-// For example, this disallows image mapping for memory
-// content when debugging minidumps.
-// Does not affect existing mappings, only future attempts.
-#define DEBUG_ENGOPT_DISALLOW_IMAGE_FILE_MAPPING 0x00020000
-// Requests that dbgeng run DML-enhanced versions of commands
-// and operations by default.
-#define DEBUG_ENGOPT_PREFER_DML                  0x00040000
-#define DEBUG_ENGOPT_ALL                         0x0007FFFF
-
-// General unspecified ID constant.
-#define DEBUG_ANY_ID 0xffffffff
-
-typedef struct _DEBUG_STACK_FRAME
-{
-    ULONG64 InstructionOffset;
-    ULONG64 ReturnOffset;
-    ULONG64 FrameOffset;
-    ULONG64 StackOffset;
-    ULONG64 FuncTableEntry;
-    ULONG64 Params[4];
-    ULONG64 Reserved[6];
-    BOOL    Virtual;
-    ULONG   FrameNumber;
-} DEBUG_STACK_FRAME, *PDEBUG_STACK_FRAME;
-
-// OutputStackTrace flags.
-// Display a small number of arguments for each call.
-// These may or may not be the actual arguments depending
-// on the architecture, particular function and
-// point during the execution of the function.
-// If the current code level is assembly arguments
-// are dumped as hex values.  If the code level is
-// source the engine attempts to provide symbolic
-// argument information.
-#define DEBUG_STACK_ARGUMENTS               0x00000001
-// Displays information about the functions
-// frame such as __stdcall arguments, FPO
-// information and whatever else is available.
-#define DEBUG_STACK_FUNCTION_INFO           0x00000002
-// Displays source line information for each
-// frame of the stack trace.
-#define DEBUG_STACK_SOURCE_LINE             0x00000004
-// Show return, previous frame and other relevant address
-// values for each frame.
-#define DEBUG_STACK_FRAME_ADDRESSES         0x00000008
-// Show column names.
-#define DEBUG_STACK_COLUMN_NAMES            0x00000010
-// Show non-volatile register context for each
-// frame.  This is only meaningful for some platforms.
-#define DEBUG_STACK_NONVOLATILE_REGISTERS   0x00000020
-// Show frame numbers
-#define DEBUG_STACK_FRAME_NUMBERS           0x00000040
-// Show typed source parameters.
-#define DEBUG_STACK_PARAMETERS              0x00000080
-// Show just return address in stack frame addresses.
-#define DEBUG_STACK_FRAME_ADDRESSES_RA_ONLY 0x00000100
-// Show frame-to-frame memory usage.
-#define DEBUG_STACK_FRAME_MEMORY_USAGE      0x00000200
-// Show typed source parameters one to a line.
-#define DEBUG_STACK_PARAMETERS_NEWLINE      0x00000400
-// Produce stack output enhanced with DML content.
-#define DEBUG_STACK_DML                     0x00000800
-
-// Classes of debuggee.  Each class
-// has different qualifiers for specific
-// kinds of debuggees.
-#define DEBUG_CLASS_UNINITIALIZED 0
-#define DEBUG_CLASS_KERNEL        1
-#define DEBUG_CLASS_USER_WINDOWS  2
-#define DEBUG_CLASS_IMAGE_FILE    3
-
-// Generic dump types.  These can be used
-// with either user or kernel sessions.
-// Session-type-specific aliases are also
-// provided.
-#define DEBUG_DUMP_SMALL      1024
-#define DEBUG_DUMP_DEFAULT    1025
-#define DEBUG_DUMP_FULL       1026
-#define DEBUG_DUMP_IMAGE_FILE 1027
-#define DEBUG_DUMP_TRACE_LOG  1028
-#define DEBUG_DUMP_WINDOWS_CE 1029
-
-// Specific types of kernel debuggees.
-#define DEBUG_KERNEL_CONNECTION  0
-#define DEBUG_KERNEL_LOCAL       1
-#define DEBUG_KERNEL_EXDI_DRIVER 2
-#define DEBUG_KERNEL_IDNA        3
-
-#define DEBUG_KERNEL_SMALL_DUMP  DEBUG_DUMP_SMALL
-#define DEBUG_KERNEL_DUMP        DEBUG_DUMP_DEFAULT
-#define DEBUG_KERNEL_FULL_DUMP   DEBUG_DUMP_FULL
-
-#define DEBUG_KERNEL_TRACE_LOG   DEBUG_DUMP_TRACE_LOG
-
-// Specific types of Windows user debuggees.
-#define DEBUG_USER_WINDOWS_PROCESS         0
-#define DEBUG_USER_WINDOWS_PROCESS_SERVER  1
-#define DEBUG_USER_WINDOWS_IDNA            2
-#define DEBUG_USER_WINDOWS_SMALL_DUMP      DEBUG_DUMP_SMALL
-#define DEBUG_USER_WINDOWS_DUMP            DEBUG_DUMP_DEFAULT
-#define DEBUG_USER_WINDOWS_DUMP_WINDOWS_CE DEBUG_DUMP_WINDOWS_CE
-
-// Extension flags.
-#define DEBUG_EXTENSION_AT_ENGINE 0x00000000
-
-// Execute and ExecuteCommandFile flags.
-// These flags only apply to the command
-// text itself; output from the executed
-// command is controlled by the output
-// control parameter.
-// Default execution.  Command is logged
-// but not output.
-#define DEBUG_EXECUTE_DEFAULT    0x00000000
-// Echo commands during execution.  In
-// ExecuteCommandFile also echoes the prompt
-// for each line of the file.
-#define DEBUG_EXECUTE_ECHO       0x00000001
-// Do not log or output commands during execution.
-// Overridden by DEBUG_EXECUTE_ECHO.
-#define DEBUG_EXECUTE_NOT_LOGGED 0x00000002
-// If this flag is not set an empty string
-// to Execute will repeat the last Execute
-// string.
-#define DEBUG_EXECUTE_NO_REPEAT  0x00000004
-
-// Specific event filter types.  Some event
-// filters have optional arguments to further
-// qualify their operation.
-#define DEBUG_FILTER_CREATE_THREAD       0x00000000
-#define DEBUG_FILTER_EXIT_THREAD         0x00000001
-#define DEBUG_FILTER_CREATE_PROCESS      0x00000002
-#define DEBUG_FILTER_EXIT_PROCESS        0x00000003
-// Argument is the name of a module to break on.
-#define DEBUG_FILTER_LOAD_MODULE         0x00000004
-// Argument is the base address of a specific module to break on.
-#define DEBUG_FILTER_UNLOAD_MODULE       0x00000005
-#define DEBUG_FILTER_SYSTEM_ERROR        0x00000006
-// Initial breakpoint and initial module load are one-shot
-// events that are triggered at the appropriate points in
-// the beginning of a session.  Their commands are executed
-// and then further processing is controlled by the normal
-// exception and load module filters.
-#define DEBUG_FILTER_INITIAL_BREAKPOINT  0x00000007
-#define DEBUG_FILTER_INITIAL_MODULE_LOAD 0x00000008
-// The debug output filter allows the debugger to stop
-// when output is produced so that the code causing
-// output can be tracked down or synchronized with.
-// This filter is not supported for live dual-machine
-// kernel debugging.
-#define DEBUG_FILTER_DEBUGGEE_OUTPUT     0x00000009
-
-// Event filter execution options.
-// Break in always.
-#define DEBUG_FILTER_BREAK               0x00000000
-// Break in on second-chance exceptions.  For events
-// that are not exceptions this is the same as BREAK.
-#define DEBUG_FILTER_SECOND_CHANCE_BREAK 0x00000001
-// Output a message about the event but continue.
-#define DEBUG_FILTER_OUTPUT              0x00000002
-// Continue the event.
-#define DEBUG_FILTER_IGNORE              0x00000003
-// Used to remove general exception filters.
-#define DEBUG_FILTER_REMOVE              0x00000004
-
-// Event filter continuation options.  These options are
-// only used when DEBUG_STATUS_GO is used to continue
-// execution.  If a specific go status such as
-// DEBUG_STATUS_GO_NOT_HANDLED is used it controls
-// the continuation.
-#define DEBUG_FILTER_GO_HANDLED          0x00000000
-#define DEBUG_FILTER_GO_NOT_HANDLED      0x00000001
-
-// Specific event filter settings.
-typedef struct _DEBUG_SPECIFIC_FILTER_PARAMETERS
-{
-    ULONG ExecutionOption;
-    ULONG ContinueOption;
-    ULONG TextSize;
-    ULONG CommandSize;
-    // If ArgumentSize is zero this filter does
-    // not have an argument.  An empty argument for
-    // a filter which does have an argument will take
-    // one byte for the terminator.
-    ULONG ArgumentSize;
-} DEBUG_SPECIFIC_FILTER_PARAMETERS, *PDEBUG_SPECIFIC_FILTER_PARAMETERS;
-
-// Exception event filter settings.
-typedef struct _DEBUG_EXCEPTION_FILTER_PARAMETERS
-{
-    ULONG ExecutionOption;
-    ULONG ContinueOption;
-    ULONG TextSize;
-    ULONG CommandSize;
-    ULONG SecondCommandSize;
-    ULONG ExceptionCode;
-} DEBUG_EXCEPTION_FILTER_PARAMETERS, *PDEBUG_EXCEPTION_FILTER_PARAMETERS;
-
-// Wait flags.
-#define DEBUG_WAIT_DEFAULT 0x00000000
-
-// Last event information structures.
-typedef struct _DEBUG_LAST_EVENT_INFO_BREAKPOINT
-{
-    ULONG Id;
-} DEBUG_LAST_EVENT_INFO_BREAKPOINT, *PDEBUG_LAST_EVENT_INFO_BREAKPOINT;
-
-typedef struct _DEBUG_LAST_EVENT_INFO_EXCEPTION
-{
-    EXCEPTION_RECORD64 ExceptionRecord;
-    ULONG FirstChance;
-} DEBUG_LAST_EVENT_INFO_EXCEPTION, *PDEBUG_LAST_EVENT_INFO_EXCEPTION;
-
-typedef struct _DEBUG_LAST_EVENT_INFO_EXIT_THREAD
-{
-    ULONG ExitCode;
-} DEBUG_LAST_EVENT_INFO_EXIT_THREAD, *PDEBUG_LAST_EVENT_INFO_EXIT_THREAD;
-
-typedef struct _DEBUG_LAST_EVENT_INFO_EXIT_PROCESS
-{
-    ULONG ExitCode;
-} DEBUG_LAST_EVENT_INFO_EXIT_PROCESS, *PDEBUG_LAST_EVENT_INFO_EXIT_PROCESS;
-
-typedef struct _DEBUG_LAST_EVENT_INFO_LOAD_MODULE
-{
-    ULONG64 Base;
-} DEBUG_LAST_EVENT_INFO_LOAD_MODULE, *PDEBUG_LAST_EVENT_INFO_LOAD_MODULE;
-
-typedef struct _DEBUG_LAST_EVENT_INFO_UNLOAD_MODULE
-{
-    ULONG64 Base;
-} DEBUG_LAST_EVENT_INFO_UNLOAD_MODULE, *PDEBUG_LAST_EVENT_INFO_UNLOAD_MODULE;
-
-typedef struct _DEBUG_LAST_EVENT_INFO_SYSTEM_ERROR
-{
-    ULONG Error;
-    ULONG Level;
-} DEBUG_LAST_EVENT_INFO_SYSTEM_ERROR, *PDEBUG_LAST_EVENT_INFO_SYSTEM_ERROR;
-
-// DEBUG_VALUE types.
-#define DEBUG_VALUE_INVALID      0
-#define DEBUG_VALUE_INT8         1
-#define DEBUG_VALUE_INT16        2
-#define DEBUG_VALUE_INT32        3
-#define DEBUG_VALUE_INT64        4
-#define DEBUG_VALUE_FLOAT32      5
-#define DEBUG_VALUE_FLOAT64      6
-#define DEBUG_VALUE_FLOAT80      7
-#define DEBUG_VALUE_FLOAT82      8
-#define DEBUG_VALUE_FLOAT128     9
-#define DEBUG_VALUE_VECTOR64     10
-#define DEBUG_VALUE_VECTOR128    11
-// Count of type indices.
-#define DEBUG_VALUE_TYPES        12
-
-#if defined(_MSC_VER)
-#if _MSC_VER >= 800
-#if _MSC_VER >= 1200
-#pragma warning(push)
-#endif
-#pragma warning(disable:4201)    /* Nameless struct/union */
-#endif
-#endif
-
-// We want the DEBUG_VALUE structure to have 8-byte alignment
-// and be 32 bytes total.  This is tricky because the compiler
-// wants to pad the union of values out to a even 8-byte multiple,
-// pushing the type out too far.  We can't use 4-packing because
-// then the 8-byte alignment requirement is lost, so instead
-// we shrink the union to 24 bytes and have a reserved field
-// before the type field.  The same amount of space is available
-// and everybody's happy, but the structure is somewhat unusual.
-
-typedef struct _DEBUG_VALUE
-{
-    union
-    {
-        UCHAR I8;
-        USHORT I16;
-        ULONG I32;
-        struct
-        {
-            // Extra NAT indicator for IA64
-            // integer registers.  NAT will
-            // always be false for other CPUs.
-            ULONG64 I64;
-            BOOL Nat;
-        };
-        float F32;
-        double F64;
-        UCHAR F80Bytes[10];
-        UCHAR F82Bytes[11];
-        UCHAR F128Bytes[16];
-        // Vector interpretations.  The actual number
-        // of valid elements depends on the vector length.
-        UCHAR VI8[16];
-        USHORT VI16[8];
-        ULONG VI32[4];
-        ULONG64 VI64[2];
-        float VF32[4];
-        double VF64[2];
-        struct
-        {
-            ULONG LowPart;
-            ULONG HighPart;
-        } I64Parts32;
-        struct
-        {
-            ULONG64 LowPart;
-            LONG64 HighPart;
-        } F128Parts64;
-        // Allows raw byte access to content.  Array
-        // can be indexed for as much data as Type
-        // describes.  This array also serves to pad
-        // the structure out to 32 bytes and reserves
-        // space for future members.
-        UCHAR RawBytes[24];
-    };
-    ULONG TailOfRawBytes;
-  ULONG Type;
-} DEBUG_VALUE, *PDEBUG_VALUE;
-
-#if defined(_MSC_VER)
-#if _MSC_VER >= 800
-#if _MSC_VER >= 1200
-#pragma warning(pop)
-#else
-#pragma warning(default:4201)    /* Nameless struct/union */
-#endif
-#endif
-#endif
-
-#undef INTERFACE
-#define INTERFACE IDebugControl
-DECLARE_INTERFACE_(IDebugControl, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugControl.
-
-    // Checks for a user interrupt, such a Ctrl-C
-    // or stop button.
-    // This method is reentrant.
-    STDMETHOD(GetInterrupt)(
-        THIS
-        ) PURE;
-    // Registers a user interrupt.
-    // This method is reentrant.
-    STDMETHOD(SetInterrupt)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Interrupting a user-mode process requires
-    // access to some system resources that the
-    // process may hold itself, preventing the
-    // interrupt from occurring.  The engine
-    // will time-out pending interrupt requests
-    // and simulate an interrupt if necessary.
-    // These methods control the interrupt timeout.
-    STDMETHOD(GetInterruptTimeout)(
-        THIS_
-        __out PULONG Seconds
-        ) PURE;
-    STDMETHOD(SetInterruptTimeout)(
-        THIS_
-        __in ULONG Seconds
-        ) PURE;
-
-    STDMETHOD(GetLogFile)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FileSize,
-        __out PBOOL Append
-        ) PURE;
-    // Opens a log file which collects all
-    // output.  Output from every client except
-    // those that explicitly disable logging
-    // goes into the log.
-    // Opening a log file closes any log file
-    // already open.
-    STDMETHOD(OpenLogFile)(
-        THIS_
-        __in PCSTR File,
-        __in BOOL Append
-        ) PURE;
-    STDMETHOD(CloseLogFile)(
-        THIS
-        ) PURE;
-    // Controls what output is logged.
-    STDMETHOD(GetLogMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetLogMask)(
-        THIS_
-        __in ULONG Mask
-        ) PURE;
-
-    // Input requests input from all clients.
-    // The first input that is returned is used
-    // to satisfy the call.  Other returned
-    // input is discarded.
-    STDMETHOD(Input)(
-        THIS_
-        __out_ecount(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InputSize
-        ) PURE;
-    // This method is used by clients to return
-    // input when it is available.  It will
-    // return S_OK if the input is used to
-    // satisfy an Input call and S_FALSE if
-    // the input is ignored.
-    // This method is reentrant.
-    STDMETHOD(ReturnInput)(
-        THIS_
-        __in PCSTR Buffer
-        ) PURE;
-
-    // Sends output through clients
-    // output callbacks if the mask is allowed
-    // by the current output control mask and
-    // according to the output distribution
-    // settings.
-    STDMETHODV(Output)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputVaList)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Format,
-        __in va_list Args
-        ) PURE;
-    // The following methods allow direct control
-    // over the distribution of the given output
-    // for situations where something other than
-    // the default is desired.  These methods require
-    // extra work in the engine so they should
-    // only be used when necessary.
-    STDMETHODV(ControlledOutput)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(ControlledOutputVaList)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCSTR Format,
-        __in va_list Args
-        ) PURE;
-
-    // Displays the standard command-line prompt
-    // followed by the given output.  If Format
-    // is NULL no additional output is produced.
-    // Output is produced under the
-    // DEBUG_OUTPUT_PROMPT mask.
-    // This method only outputs the prompt; it
-    // does not get input.
-    STDMETHODV(OutputPrompt)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputPromptVaList)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCSTR Format,
-        __in va_list Args
-        ) PURE;
-    // Gets the text that would be displayed by OutputPrompt.
-    STDMETHOD(GetPromptText)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-    // Outputs information about the current
-    // debuggee state such as a register
-    // summary, disassembly at the current PC,
-    // closest symbol and others.
-    // Uses the line prefix.
-    STDMETHOD(OutputCurrentState)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags
-        ) PURE;
-
-    // Outputs the debugger and extension version
-    // information.  This method is reentrant.
-    // Uses the line prefix.
-    STDMETHOD(OutputVersionInformation)(
-        THIS_
-        __in ULONG OutputControl
-        ) PURE;
-
-    // In user-mode debugging sessions the
-    // engine will set an event when
-    // exceptions are continued.  This can
-    // be used to synchronize other processes
-    // with the debuggers handling of events.
-    // For example, this is used to support
-    // the e argument to ntsd.
-    STDMETHOD(GetNotifyEventHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(SetNotifyEventHandle)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-
-    STDMETHOD(Assemble)(
-        THIS_
-        __in ULONG64 Offset,
-        __in PCSTR Instr,
-        __out PULONG64 EndOffset
-        ) PURE;
-    STDMETHOD(Disassemble)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DisassemblySize,
-        __out PULONG64 EndOffset
-        ) PURE;
-    // Returns the value of the effective address
-    // computed for the last Disassemble, if there
-    // was one.
-    STDMETHOD(GetDisassembleEffectiveOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Uses the line prefix if necessary.
-    STDMETHOD(OutputDisassembly)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out PULONG64 EndOffset
-        ) PURE;
-    // Produces multiple lines of disassembly output.
-    // There will be PreviousLines of disassembly before
-    // the given offset if a valid disassembly exists.
-    // In all, there will be TotalLines of output produced.
-    // The first and last line offsets are returned
-    // specially and all lines offsets can be retrieved
-    // through LineOffsets.  LineOffsets will contain
-    // offsets for each line where disassembly started.
-    // When disassembly of a single instruction takes
-    // multiple lines the initial offset will be followed
-    // by DEBUG_INVALID_OFFSET.
-    // Uses the line prefix.
-    STDMETHOD(OutputDisassemblyLines)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG PreviousLines,
-        __in ULONG TotalLines,
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_opt PULONG OffsetLine,
-        __out_opt PULONG64 StartOffset,
-        __out_opt PULONG64 EndOffset,
-        __out_ecount_opt(TotalLines) PULONG64 LineOffsets
-        ) PURE;
-    // Returns the offset of the start of
-    // the instruction thats the given
-    // delta away from the instruction
-    // at the initial offset.
-    // This routine does not check for
-    // validity of the instruction or
-    // the memory containing it.
-    STDMETHOD(GetNearInstruction)(
-        THIS_
-        __in ULONG64 Offset,
-        __in LONG Delta,
-        __out PULONG64 NearOffset
-        ) PURE;
-
-    // Offsets can be passed in as zero to use the current
-    // thread state.
-    STDMETHOD(GetStackTrace)(
-        THIS_
-        __in ULONG64 FrameOffset,
-        __in ULONG64 StackOffset,
-        __in ULONG64 InstructionOffset,
-        __out_ecount(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __out_opt PULONG FramesFilled
-        ) PURE;
-    // Does a simple stack trace to determine
-    // what the current return address is.
-    STDMETHOD(GetReturnOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // If Frames is NULL OutputStackTrace will
-    // use GetStackTrace to get FramesSize frames
-    // and then output them.  The current register
-    // values for frame, stack and instruction offsets
-    // are used.
-    // Uses the line prefix.
-    STDMETHOD(OutputStackTrace)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_ecount_opt(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __in ULONG Flags
-        ) PURE;
-
-    // Returns information about the debuggee such
-    // as user vs. kernel, dump vs. live, etc.
-    STDMETHOD(GetDebuggeeType)(
-        THIS_
-        __out PULONG Class,
-        __out PULONG Qualifier
-        ) PURE;
-    // Returns the type of physical processors in
-    // the machine.
-    // Returns one of the IMAGE_FILE_MACHINE values.
-    STDMETHOD(GetActualProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    // Returns the type of processor used in the
-    // current processor context.
-    STDMETHOD(GetExecutingProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    // Query all the possible processor types that
-    // may be encountered during this debug session.
-    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetPossibleExecutingProcessorTypes)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Types
-        ) PURE;
-    // Get the number of actual processors in
-    // the machine.
-    STDMETHOD(GetNumberProcessors)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // PlatformId is one of the VER_PLATFORM values.
-    // Major and minor are as given in the NT
-    // kernel debugger protocol.
-    // ServicePackString and ServicePackNumber indicate the
-    // system service pack level.  ServicePackNumber is not
-    // available in some sessions where the service pack level
-    // is only expressed as a string.  The service pack information
-    // will be empty if the system does not have a service pack
-    // applied.
-    // The build string is string information identifying the
-    // particular build of the system.  The build string is
-    // empty if the system has no particular identifying
-    // information.
-    STDMETHOD(GetSystemVersion)(
-        THIS_
-        __out PULONG PlatformId,
-        __out PULONG Major,
-        __out PULONG Minor,
-        __out_ecount_opt(ServicePackStringSize) PSTR ServicePackString,
-        __in ULONG ServicePackStringSize,
-        __out_opt PULONG ServicePackStringUsed,
-        __out PULONG ServicePackNumber,
-        __out_ecount_opt(BuildStringSize) PSTR BuildString,
-        __in ULONG BuildStringSize,
-        __out_opt PULONG BuildStringUsed
-        ) PURE;
-    // Returns the page size for the currently executing
-    // processor context.  The page size may vary between
-    // processor types.
-    STDMETHOD(GetPageSize)(
-        THIS_
-        __out PULONG Size
-        ) PURE;
-    // Returns S_OK if the current processor context uses
-    // 64-bit addresses, otherwise S_FALSE.
-    STDMETHOD(IsPointer64Bit)(
-        THIS
-        ) PURE;
-    // Reads the bugcheck data area and returns the
-    // current contents.  This method only works
-    // in kernel debugging sessions.
-    STDMETHOD(ReadBugCheckData)(
-        THIS_
-        __out PULONG Code,
-        __out PULONG64 Arg1,
-        __out PULONG64 Arg2,
-        __out PULONG64 Arg3,
-        __out PULONG64 Arg4
-        ) PURE;
-
-    // Query all the processor types supported by
-    // the engine.  This is a complete list and is
-    // not related to the machine running the engine
-    // or the debuggee.
-    STDMETHOD(GetNumberSupportedProcessorTypes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetSupportedProcessorTypes)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Types
-        ) PURE;
-    // Returns a full, descriptive name and an
-    // abbreviated name for a processor type.
-    STDMETHOD(GetProcessorTypeNames)(
-        THIS_
-        __in ULONG Type,
-        __out_ecount_opt(FullNameBufferSize) PSTR FullNameBuffer,
-        __in ULONG FullNameBufferSize,
-        __out_opt PULONG FullNameSize,
-        __out_ecount_opt(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
-        __in ULONG AbbrevNameBufferSize,
-        __out_opt PULONG AbbrevNameSize
-        ) PURE;
-
-    // Gets and sets the type of processor to
-    // use when doing things like setting
-    // breakpoints, accessing registers,
-    // getting stack traces and so on.
-    STDMETHOD(GetEffectiveProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    STDMETHOD(SetEffectiveProcessorType)(
-        THIS_
-        __in ULONG Type
-        ) PURE;
-
-    // Returns information about whether and how
-    // the debuggee is running.  Status will
-    // be GO if the debuggee is running and
-    // BREAK if it isnt.
-    // If no debuggee exists the status is
-    // NO_DEBUGGEE.
-    // This method is reentrant.
-    STDMETHOD(GetExecutionStatus)(
-        THIS_
-        __out PULONG Status
-        ) PURE;
-    // Changes the execution status of the
-    // engine from stopped to running.
-    // Status must be one of the go or step
-    // status values.
-    STDMETHOD(SetExecutionStatus)(
-        THIS_
-        __in ULONG Status
-        ) PURE;
-
-    // Controls what code interpretation level the debugger
-    // runs at.  The debugger checks the code level when
-    // deciding whether to step by a source line or
-    // assembly instruction along with other related operations.
-    STDMETHOD(GetCodeLevel)(
-        THIS_
-        __out PULONG Level
-        ) PURE;
-    STDMETHOD(SetCodeLevel)(
-        THIS_
-        __in ULONG Level
-        ) PURE;
-
-    // Gets and sets engine control flags.
-    // These methods are reentrant.
-    STDMETHOD(GetEngineOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Gets and sets control values for
-    // handling system error events.
-    // If the system error level is less
-    // than or equal to the given levels
-    // the error may be displayed and
-    // the default break for the event
-    // may be set.
-    STDMETHOD(GetSystemErrorControl)(
-        THIS_
-        __out PULONG OutputLevel,
-        __out PULONG BreakLevel
-        ) PURE;
-    STDMETHOD(SetSystemErrorControl)(
-        THIS_
-        __in ULONG OutputLevel,
-        __in ULONG BreakLevel
-        ) PURE;
-
-    // The command processor supports simple
-    // string replacement macros in Evaluate and
-    // Execute.  There are currently ten macro
-    // slots available.  Slots 0-9 map to
-    // the command invocations $u0-$u9.
-    STDMETHOD(GetTextMacro)(
-        THIS_
-        __in ULONG Slot,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG MacroSize
-        ) PURE;
-    STDMETHOD(SetTextMacro)(
-        THIS_
-        __in ULONG Slot,
-        __in PCSTR Macro
-        ) PURE;
-
-    // Controls the default number radix used
-    // in expressions and commands.
-    STDMETHOD(GetRadix)(
-        THIS_
-        __out PULONG Radix
-        ) PURE;
-    STDMETHOD(SetRadix)(
-        THIS_
-        __in ULONG Radix
-        ) PURE;
-
-    // Evaluates the given expression string and
-    // returns the resulting value.
-    // If DesiredType is DEBUG_VALUE_INVALID then
-    // the natural type is used.
-    // RemainderIndex, if provided, is set to the index
-    // of the first character in the input string that was
-    // not used when evaluating the expression.
-    STDMETHOD(Evaluate)(
-        THIS_
-        __in PCSTR Expression,
-        __in ULONG DesiredType,
-        __out PDEBUG_VALUE Value,
-        __out_opt PULONG RemainderIndex
-        ) PURE;
-    // Attempts to convert the input value to a value
-    // of the requested type in the output value.
-    // Conversions can fail if no conversion exists.
-    // Successful conversions may be lossy.
-    STDMETHOD(CoerceValue)(
-        THIS_
-        __in PDEBUG_VALUE In,
-        __in ULONG OutType,
-        __out PDEBUG_VALUE Out
-        ) PURE;
-    STDMETHOD(CoerceValues)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_VALUE In,
-        __in_ecount(Count) PULONG OutTypes,
-        __out_ecount(Count) PDEBUG_VALUE Out
-        ) PURE;
-
-    // Executes the given command string.
-    // If the string has multiple commands
-    // Execute will not return until all
-    // of them have been executed.  If this
-    // requires waiting for the debuggee to
-    // execute an internal wait will be done
-    // so Execute can take an arbitrary amount
-    // of time.
-    STDMETHOD(Execute)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR Command,
-        __in ULONG Flags
-        ) PURE;
-    // Executes the given command file by
-    // reading a line at a time and processing
-    // it with Execute.
-    STDMETHOD(ExecuteCommandFile)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR CommandFile,
-        __in ULONG Flags
-        ) PURE;
-
-    // Breakpoint interfaces are described
-    // elsewhere in this section.
-    STDMETHOD(GetNumberBreakpoints)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // It is possible for this retrieval function to
-    // fail even with an index within the number of
-    // existing breakpoints if the breakpoint is
-    // a private breakpoint.
-    STDMETHOD(GetBreakpointByIndex)(
-        THIS_
-        __in ULONG Index,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    STDMETHOD(GetBreakpointById)(
-        THIS_
-        __in ULONG Id,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    // If Ids is non-NULL the Count breakpoints
-    // referred to in the Ids array are returned,
-    // otherwise breakpoints from index Start to
-    // Start + Count  1 are returned.
-    STDMETHOD(GetBreakpointParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Ids,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
-        ) PURE;
-    // Breakpoints are created empty and disabled.
-    // When their parameters have been set they
-    // should be enabled by setting the ENABLE flag.
-    // If DesiredId is DEBUG_ANY_ID then the
-    // engine picks an unused ID.  If DesiredId
-    // is any other number the engine attempts
-    // to use the given ID for the breakpoint.
-    // If another breakpoint exists with that ID
-    // the call will fail.
-    STDMETHOD(AddBreakpoint)(
-        THIS_
-        __in ULONG Type,
-        __in ULONG DesiredId,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    // Breakpoint interface is invalid after this call.
-    STDMETHOD(RemoveBreakpoint)(
-        THIS_
-        __in PDEBUG_BREAKPOINT Bp
-        ) PURE;
-
-    // Control and use extension DLLs.
-    STDMETHOD(AddExtension)(
-        THIS_
-        __in PCSTR Path,
-        __in ULONG Flags,
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(RemoveExtension)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-    STDMETHOD(GetExtensionByPath)(
-        THIS_
-        __in PCSTR Path,
-        __out PULONG64 Handle
-        ) PURE;
-    // If Handle is zero the extension
-    // chain is walked searching for the
-    // function.
-    STDMETHOD(CallExtension)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCSTR Function,
-        __in_opt PCSTR Arguments
-        ) PURE;
-    // GetExtensionFunction works like
-    // GetProcAddress on extension DLLs
-    // to allow raw function-call-level
-    // interaction with extension DLLs.
-    // Such functions do not need to
-    // follow the standard extension prototype
-    // if they are not going to be called
-    // through the text extension interface.
-    // _EFN_ is automatically prepended to
-    // the name string given.
-    // This function cannot be called remotely.
-    STDMETHOD(GetExtensionFunction)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCSTR FuncName,
-        __out FARPROC* Function
-        ) PURE;
-    // These methods return alternate
-    // extension interfaces in order to allow
-    // interface-style extension DLLs to mix in
-    // older extension calls.
-    // Structure sizes must be initialized before
-    // the call.
-    // These methods cannot be called remotely.
-    STDMETHOD(GetWindbgExtensionApis32)(
-        THIS_
-        __inout PWINDBG_EXTENSION_APIS32 Api
-        ) PURE;
-    STDMETHOD(GetWindbgExtensionApis64)(
-        THIS_
-        __inout PWINDBG_EXTENSION_APIS64 Api
-        ) PURE;
-
-    // The engine provides a simple mechanism
-    // to filter common events.  Arbitrarily complicated
-    // filtering can be done by registering event callbacks
-    // but simple event filtering only requires
-    // setting the options of one of the predefined
-    // event filters.
-    // Simple event filters are either for specific
-    // events and therefore have an enumerant or
-    // they are for an exception and are based on
-    // the exceptions code.  Exception filters
-    // are further divided into exceptions specially
-    // handled by the engine, which is a fixed set,
-    // and arbitrary exceptions.
-    // All three groups of filters are indexed together
-    // with the specific filters first, then the specific
-    // exception filters and finally the arbitrary
-    // exception filters.
-    // The first specific exception is the default
-    // exception.  If an exception event occurs for
-    // an exception without settings the default
-    // exception settings are used.
-    STDMETHOD(GetNumberEventFilters)(
-        THIS_
-        __out PULONG SpecificEvents,
-        __out PULONG SpecificExceptions,
-        __out PULONG ArbitraryExceptions
-        ) PURE;
-    // Some filters have descriptive text associated with them.
-    STDMETHOD(GetEventFilterText)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-    // All filters support executing a command when the
-    // event occurs.
-    STDMETHOD(GetEventFilterCommand)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetEventFilterCommand)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Command
-        ) PURE;
-    STDMETHOD(GetSpecificFilterParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
-        ) PURE;
-    STDMETHOD(SetSpecificFilterParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
-        ) PURE;
-    // Some specific filters have arguments to further
-    // qualify their operation.
-    STDMETHOD(GetSpecificFilterArgument)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ArgumentSize
-        ) PURE;
-    STDMETHOD(SetSpecificFilterArgument)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Argument
-        ) PURE;
-    // If Codes is non-NULL Start is ignored.
-    STDMETHOD(GetExceptionFilterParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Codes,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
-        ) PURE;
-    // The codes in the parameter data control the application
-    // of the parameter data.  If a code is not already in
-    // the set of filters it is added.  If the ExecutionOption
-    // for a code is REMOVE then the filter is removed.
-    // Specific exception filters cannot be removed.
-    STDMETHOD(SetExceptionFilterParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
-        ) PURE;
-    // Exception filters support an additional command for
-    // second-chance events.
-    STDMETHOD(GetExceptionFilterSecondCommand)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetExceptionFilterSecondCommand)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Command
-        ) PURE;
-
-    // Yields processing to the engine until
-    // an event occurs.  This method may
-    // only be called by the thread that started
-    // the debug session.
-    // When an event occurs the engine carries
-    // out all event processing such as calling
-    // callbacks.
-    // If the callbacks indicate that execution should
-    // break the wait will return, otherwise it
-    // goes back to waiting for a new event.
-    // If the timeout expires, S_FALSE is returned.
-    // The timeout is not currently supported for
-    // kernel debugging.
-    STDMETHOD(WaitForEvent)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG Timeout
-        ) PURE;
-
-    // Retrieves information about the last event that occurred.
-    // EventType is one of the event callback mask bits.
-    // ExtraInformation contains additional event-specific
-    // information.  Not all events have additional information.
-    STDMETHOD(GetLastEventInformation)(
-        THIS_
-        __out PULONG Type,
-        __out PULONG ProcessId,
-        __out PULONG ThreadId,
-        __out_bcount_opt(ExtraInformationSize) PVOID ExtraInformation,
-        __in ULONG ExtraInformationSize,
-        __out_opt PULONG ExtraInformationUsed,
-        __out_ecount_opt(DescriptionSize) PSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG DescriptionUsed
-        ) PURE;
-};
-
-// OutputTextReplacements flags.
-#define DEBUG_OUT_TEXT_REPL_DEFAULT 0x00000000
-
-#undef INTERFACE
-#define INTERFACE IDebugControl2
-DECLARE_INTERFACE_(IDebugControl2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugControl.
-
-    // Checks for a user interrupt, such a Ctrl-C
-    // or stop button.
-    // This method is reentrant.
-    STDMETHOD(GetInterrupt)(
-        THIS
-        ) PURE;
-    // Registers a user interrupt.
-    // This method is reentrant.
-    STDMETHOD(SetInterrupt)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Interrupting a user-mode process requires
-    // access to some system resources that the
-    // process may hold itself, preventing the
-    // interrupt from occurring.  The engine
-    // will time-out pending interrupt requests
-    // and simulate an interrupt if necessary.
-    // These methods control the interrupt timeout.
-    STDMETHOD(GetInterruptTimeout)(
-        THIS_
-        __out PULONG Seconds
-        ) PURE;
-    STDMETHOD(SetInterruptTimeout)(
-        THIS_
-        __in ULONG Seconds
-        ) PURE;
-
-    STDMETHOD(GetLogFile)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FileSize,
-        __out PBOOL Append
-        ) PURE;
-    // Opens a log file which collects all
-    // output.  Output from every client except
-    // those that explicitly disable logging
-    // goes into the log.
-    // Opening a log file closes any log file
-    // already open.
-    STDMETHOD(OpenLogFile)(
-        THIS_
-        __in PCSTR File,
-        __in BOOL Append
-        ) PURE;
-    STDMETHOD(CloseLogFile)(
-        THIS
-        ) PURE;
-    // Controls what output is logged.
-    STDMETHOD(GetLogMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetLogMask)(
-        THIS_
-        __in ULONG Mask
-        ) PURE;
-
-    // Input requests input from all clients.
-    // The first input that is returned is used
-    // to satisfy the call.  Other returned
-    // input is discarded.
-    STDMETHOD(Input)(
-        THIS_
-        __out_ecount(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InputSize
-        ) PURE;
-    // This method is used by clients to return
-    // input when it is available.  It will
-    // return S_OK if the input is used to
-    // satisfy an Input call and S_FALSE if
-    // the input is ignored.
-    // This method is reentrant.
-    STDMETHOD(ReturnInput)(
-        THIS_
-        __in PCSTR Buffer
-        ) PURE;
-
-    // Sends output through clients
-    // output callbacks if the mask is allowed
-    // by the current output control mask and
-    // according to the output distribution
-    // settings.
-    STDMETHODV(Output)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputVaList)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Format,
-        __in va_list Args
-        ) PURE;
-    // The following methods allow direct control
-    // over the distribution of the given output
-    // for situations where something other than
-    // the default is desired.  These methods require
-    // extra work in the engine so they should
-    // only be used when necessary.
-    STDMETHODV(ControlledOutput)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(ControlledOutputVaList)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCSTR Format,
-        __in va_list Args
-        ) PURE;
-
-    // Displays the standard command-line prompt
-    // followed by the given output.  If Format
-    // is NULL no additional output is produced.
-    // Output is produced under the
-    // DEBUG_OUTPUT_PROMPT mask.
-    // This method only outputs the prompt; it
-    // does not get input.
-    STDMETHODV(OutputPrompt)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputPromptVaList)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCSTR Format,
-        __in va_list Args
-        ) PURE;
-    // Gets the text that would be displayed by OutputPrompt.
-    STDMETHOD(GetPromptText)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-    // Outputs information about the current
-    // debuggee state such as a register
-    // summary, disassembly at the current PC,
-    // closest symbol and others.
-    // Uses the line prefix.
-    STDMETHOD(OutputCurrentState)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags
-        ) PURE;
-
-    // Outputs the debugger and extension version
-    // information.  This method is reentrant.
-    // Uses the line prefix.
-    STDMETHOD(OutputVersionInformation)(
-        THIS_
-        __in ULONG OutputControl
-        ) PURE;
-
-    // In user-mode debugging sessions the
-    // engine will set an event when
-    // exceptions are continued.  This can
-    // be used to synchronize other processes
-    // with the debuggers handling of events.
-    // For example, this is used to support
-    // the e argument to ntsd.
-    STDMETHOD(GetNotifyEventHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(SetNotifyEventHandle)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-
-    STDMETHOD(Assemble)(
-        THIS_
-        __in ULONG64 Offset,
-        __in PCSTR Instr,
-        __out PULONG64 EndOffset
-        ) PURE;
-    STDMETHOD(Disassemble)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DisassemblySize,
-        __out PULONG64 EndOffset
-        ) PURE;
-    // Returns the value of the effective address
-    // computed for the last Disassemble, if there
-    // was one.
-    STDMETHOD(GetDisassembleEffectiveOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Uses the line prefix if necessary.
-    STDMETHOD(OutputDisassembly)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out PULONG64 EndOffset
-        ) PURE;
-    // Produces multiple lines of disassembly output.
-    // There will be PreviousLines of disassembly before
-    // the given offset if a valid disassembly exists.
-    // In all, there will be TotalLines of output produced.
-    // The first and last line offsets are returned
-    // specially and all lines offsets can be retrieved
-    // through LineOffsets.  LineOffsets will contain
-    // offsets for each line where disassembly started.
-    // When disassembly of a single instruction takes
-    // multiple lines the initial offset will be followed
-    // by DEBUG_INVALID_OFFSET.
-    // Uses the line prefix.
-    STDMETHOD(OutputDisassemblyLines)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG PreviousLines,
-        __in ULONG TotalLines,
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_opt PULONG OffsetLine,
-        __out_opt PULONG64 StartOffset,
-        __out_opt PULONG64 EndOffset,
-        __out_ecount_opt(TotalLines) PULONG64 LineOffsets
-        ) PURE;
-    // Returns the offset of the start of
-    // the instruction thats the given
-    // delta away from the instruction
-    // at the initial offset.
-    // This routine does not check for
-    // validity of the instruction or
-    // the memory containing it.
-    STDMETHOD(GetNearInstruction)(
-        THIS_
-        __in ULONG64 Offset,
-        __in LONG Delta,
-        __out PULONG64 NearOffset
-        ) PURE;
-
-    // Offsets can be passed in as zero to use the current
-    // thread state.
-    STDMETHOD(GetStackTrace)(
-        THIS_
-        __in ULONG64 FrameOffset,
-        __in ULONG64 StackOffset,
-        __in ULONG64 InstructionOffset,
-        __out_ecount(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __out_opt PULONG FramesFilled
-        ) PURE;
-    // Does a simple stack trace to determine
-    // what the current return address is.
-    STDMETHOD(GetReturnOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // If Frames is NULL OutputStackTrace will
-    // use GetStackTrace to get FramesSize frames
-    // and then output them.  The current register
-    // values for frame, stack and instruction offsets
-    // are used.
-    // Uses the line prefix.
-    STDMETHOD(OutputStackTrace)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_ecount_opt(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __in ULONG Flags
-        ) PURE;
-
-    // Returns information about the debuggee such
-    // as user vs. kernel, dump vs. live, etc.
-    STDMETHOD(GetDebuggeeType)(
-        THIS_
-        __out PULONG Class,
-        __out PULONG Qualifier
-        ) PURE;
-    // Returns the type of physical processors in
-    // the machine.
-    // Returns one of the IMAGE_FILE_MACHINE values.
-    STDMETHOD(GetActualProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    // Returns the type of processor used in the
-    // current processor context.
-    STDMETHOD(GetExecutingProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    // Query all the possible processor types that
-    // may be encountered during this debug session.
-    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetPossibleExecutingProcessorTypes)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Types
-        ) PURE;
-    // Get the number of actual processors in
-    // the machine.
-    STDMETHOD(GetNumberProcessors)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // PlatformId is one of the VER_PLATFORM values.
-    // Major and minor are as given in the NT
-    // kernel debugger protocol.
-    // ServicePackString and ServicePackNumber indicate the
-    // system service pack level.  ServicePackNumber is not
-    // available in some sessions where the service pack level
-    // is only expressed as a string.  The service pack information
-    // will be empty if the system does not have a service pack
-    // applied.
-    // The build string is string information identifying the
-    // particular build of the system.  The build string is
-    // empty if the system has no particular identifying
-    // information.
-    STDMETHOD(GetSystemVersion)(
-        THIS_
-        __out PULONG PlatformId,
-        __out PULONG Major,
-        __out PULONG Minor,
-        __out_ecount_opt(ServicePackStringSize) PSTR ServicePackString,
-        __in ULONG ServicePackStringSize,
-        __out_opt PULONG ServicePackStringUsed,
-        __out PULONG ServicePackNumber,
-        __out_ecount_opt(BuildStringSize) PSTR BuildString,
-        __in ULONG BuildStringSize,
-        __out_opt PULONG BuildStringUsed
-        ) PURE;
-    // Returns the page size for the currently executing
-    // processor context.  The page size may vary between
-    // processor types.
-    STDMETHOD(GetPageSize)(
-        THIS_
-        __out PULONG Size
-        ) PURE;
-    // Returns S_OK if the current processor context uses
-    // 64-bit addresses, otherwise S_FALSE.
-    STDMETHOD(IsPointer64Bit)(
-        THIS
-        ) PURE;
-    // Reads the bugcheck data area and returns the
-    // current contents.  This method only works
-    // in kernel debugging sessions.
-    STDMETHOD(ReadBugCheckData)(
-        THIS_
-        __out PULONG Code,
-        __out PULONG64 Arg1,
-        __out PULONG64 Arg2,
-        __out PULONG64 Arg3,
-        __out PULONG64 Arg4
-        ) PURE;
-
-    // Query all the processor types supported by
-    // the engine.  This is a complete list and is
-    // not related to the machine running the engine
-    // or the debuggee.
-    STDMETHOD(GetNumberSupportedProcessorTypes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetSupportedProcessorTypes)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Types
-        ) PURE;
-    // Returns a full, descriptive name and an
-    // abbreviated name for a processor type.
-    STDMETHOD(GetProcessorTypeNames)(
-        THIS_
-        __in ULONG Type,
-        __out_ecount_opt(FullNameBufferSize) PSTR FullNameBuffer,
-        __in ULONG FullNameBufferSize,
-        __out_opt PULONG FullNameSize,
-        __out_ecount_opt(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
-        __in ULONG AbbrevNameBufferSize,
-        __out_opt PULONG AbbrevNameSize
-        ) PURE;
-
-    // Gets and sets the type of processor to
-    // use when doing things like setting
-    // breakpoints, accessing registers,
-    // getting stack traces and so on.
-    STDMETHOD(GetEffectiveProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    STDMETHOD(SetEffectiveProcessorType)(
-        THIS_
-        __in ULONG Type
-        ) PURE;
-
-    // Returns information about whether and how
-    // the debuggee is running.  Status will
-    // be GO if the debuggee is running and
-    // BREAK if it isnt.
-    // If no debuggee exists the status is
-    // NO_DEBUGGEE.
-    // This method is reentrant.
-    STDMETHOD(GetExecutionStatus)(
-        THIS_
-        __out PULONG Status
-        ) PURE;
-    // Changes the execution status of the
-    // engine from stopped to running.
-    // Status must be one of the go or step
-    // status values.
-    STDMETHOD(SetExecutionStatus)(
-        THIS_
-        __in ULONG Status
-        ) PURE;
-
-    // Controls what code interpretation level the debugger
-    // runs at.  The debugger checks the code level when
-    // deciding whether to step by a source line or
-    // assembly instruction along with other related operations.
-    STDMETHOD(GetCodeLevel)(
-        THIS_
-        __out PULONG Level
-        ) PURE;
-    STDMETHOD(SetCodeLevel)(
-        THIS_
-        __in ULONG Level
-        ) PURE;
-
-    // Gets and sets engine control flags.
-    // These methods are reentrant.
-    STDMETHOD(GetEngineOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Gets and sets control values for
-    // handling system error events.
-    // If the system error level is less
-    // than or equal to the given levels
-    // the error may be displayed and
-    // the default break for the event
-    // may be set.
-    STDMETHOD(GetSystemErrorControl)(
-        THIS_
-        __out PULONG OutputLevel,
-        __out PULONG BreakLevel
-        ) PURE;
-    STDMETHOD(SetSystemErrorControl)(
-        THIS_
-        __in ULONG OutputLevel,
-        __in ULONG BreakLevel
-        ) PURE;
-
-    // The command processor supports simple
-    // string replacement macros in Evaluate and
-    // Execute.  There are currently ten macro
-    // slots available.  Slots 0-9 map to
-    // the command invocations $u0-$u9.
-    STDMETHOD(GetTextMacro)(
-        THIS_
-        __in ULONG Slot,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG MacroSize
-        ) PURE;
-    STDMETHOD(SetTextMacro)(
-        THIS_
-        __in ULONG Slot,
-        __in PCSTR Macro
-        ) PURE;
-
-    // Controls the default number radix used
-    // in expressions and commands.
-    STDMETHOD(GetRadix)(
-        THIS_
-        __out PULONG Radix
-        ) PURE;
-    STDMETHOD(SetRadix)(
-        THIS_
-        __in ULONG Radix
-        ) PURE;
-
-    // Evaluates the given expression string and
-    // returns the resulting value.
-    // If DesiredType is DEBUG_VALUE_INVALID then
-    // the natural type is used.
-    // RemainderIndex, if provided, is set to the index
-    // of the first character in the input string that was
-    // not used when evaluating the expression.
-    STDMETHOD(Evaluate)(
-        THIS_
-        __in PCSTR Expression,
-        __in ULONG DesiredType,
-        __out PDEBUG_VALUE Value,
-        __out_opt PULONG RemainderIndex
-        ) PURE;
-    // Attempts to convert the input value to a value
-    // of the requested type in the output value.
-    // Conversions can fail if no conversion exists.
-    // Successful conversions may be lossy.
-    STDMETHOD(CoerceValue)(
-        THIS_
-        __in PDEBUG_VALUE In,
-        __in ULONG OutType,
-        __out PDEBUG_VALUE Out
-        ) PURE;
-    STDMETHOD(CoerceValues)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_VALUE In,
-        __in_ecount(Count) PULONG OutTypes,
-        __out_ecount(Count) PDEBUG_VALUE Out
-        ) PURE;
-
-    // Executes the given command string.
-    // If the string has multiple commands
-    // Execute will not return until all
-    // of them have been executed.  If this
-    // requires waiting for the debuggee to
-    // execute an internal wait will be done
-    // so Execute can take an arbitrary amount
-    // of time.
-    STDMETHOD(Execute)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR Command,
-        __in ULONG Flags
-        ) PURE;
-    // Executes the given command file by
-    // reading a line at a time and processing
-    // it with Execute.
-    STDMETHOD(ExecuteCommandFile)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR CommandFile,
-        __in ULONG Flags
-        ) PURE;
-
-    // Breakpoint interfaces are described
-    // elsewhere in this section.
-    STDMETHOD(GetNumberBreakpoints)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // It is possible for this retrieval function to
-    // fail even with an index within the number of
-    // existing breakpoints if the breakpoint is
-    // a private breakpoint.
-    STDMETHOD(GetBreakpointByIndex)(
-        THIS_
-        __in ULONG Index,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    STDMETHOD(GetBreakpointById)(
-        THIS_
-        __in ULONG Id,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    // If Ids is non-NULL the Count breakpoints
-    // referred to in the Ids array are returned,
-    // otherwise breakpoints from index Start to
-    // Start + Count  1 are returned.
-    STDMETHOD(GetBreakpointParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Ids,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
-        ) PURE;
-    // Breakpoints are created empty and disabled.
-    // When their parameters have been set they
-    // should be enabled by setting the ENABLE flag.
-    // If DesiredId is DEBUG_ANY_ID then the
-    // engine picks an unused ID.  If DesiredId
-    // is any other number the engine attempts
-    // to use the given ID for the breakpoint.
-    // If another breakpoint exists with that ID
-    // the call will fail.
-    STDMETHOD(AddBreakpoint)(
-        THIS_
-        __in ULONG Type,
-        __in ULONG DesiredId,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    // Breakpoint interface is invalid after this call.
-    STDMETHOD(RemoveBreakpoint)(
-        THIS_
-        __in PDEBUG_BREAKPOINT Bp
-        ) PURE;
-
-    // Control and use extension DLLs.
-    STDMETHOD(AddExtension)(
-        THIS_
-        __in PCSTR Path,
-        __in ULONG Flags,
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(RemoveExtension)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-    STDMETHOD(GetExtensionByPath)(
-        THIS_
-        __in PCSTR Path,
-        __out PULONG64 Handle
-        ) PURE;
-    // If Handle is zero the extension
-    // chain is walked searching for the
-    // function.
-    STDMETHOD(CallExtension)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCSTR Function,
-        __in_opt PCSTR Arguments
-        ) PURE;
-    // GetExtensionFunction works like
-    // GetProcAddress on extension DLLs
-    // to allow raw function-call-level
-    // interaction with extension DLLs.
-    // Such functions do not need to
-    // follow the standard extension prototype
-    // if they are not going to be called
-    // through the text extension interface.
-    // This function cannot be called remotely.
-    STDMETHOD(GetExtensionFunction)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCSTR FuncName,
-        __out FARPROC* Function
-        ) PURE;
-    // These methods return alternate
-    // extension interfaces in order to allow
-    // interface-style extension DLLs to mix in
-    // older extension calls.
-    // Structure sizes must be initialized before
-    // the call.
-    // These methods cannot be called remotely.
-    STDMETHOD(GetWindbgExtensionApis32)(
-        THIS_
-        __inout PWINDBG_EXTENSION_APIS32 Api
-        ) PURE;
-    STDMETHOD(GetWindbgExtensionApis64)(
-        THIS_
-        __inout PWINDBG_EXTENSION_APIS64 Api
-        ) PURE;
-
-    // The engine provides a simple mechanism
-    // to filter common events.  Arbitrarily complicated
-    // filtering can be done by registering event callbacks
-    // but simple event filtering only requires
-    // setting the options of one of the predefined
-    // event filters.
-    // Simple event filters are either for specific
-    // events and therefore have an enumerant or
-    // they are for an exception and are based on
-    // the exceptions code.  Exception filters
-    // are further divided into exceptions specially
-    // handled by the engine, which is a fixed set,
-    // and arbitrary exceptions.
-    // All three groups of filters are indexed together
-    // with the specific filters first, then the specific
-    // exception filters and finally the arbitrary
-    // exception filters.
-    // The first specific exception is the default
-    // exception.  If an exception event occurs for
-    // an exception without settings the default
-    // exception settings are used.
-    STDMETHOD(GetNumberEventFilters)(
-        THIS_
-        __out PULONG SpecificEvents,
-        __out PULONG SpecificExceptions,
-        __out PULONG ArbitraryExceptions
-        ) PURE;
-    // Some filters have descriptive text associated with them.
-    STDMETHOD(GetEventFilterText)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-    // All filters support executing a command when the
-    // event occurs.
-    STDMETHOD(GetEventFilterCommand)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetEventFilterCommand)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Command
-        ) PURE;
-    STDMETHOD(GetSpecificFilterParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
-        ) PURE;
-    STDMETHOD(SetSpecificFilterParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
-        ) PURE;
-    // Some specific filters have arguments to further
-    // qualify their operation.
-    STDMETHOD(GetSpecificFilterArgument)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ArgumentSize
-        ) PURE;
-    STDMETHOD(SetSpecificFilterArgument)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Argument
-        ) PURE;
-    // If Codes is non-NULL Start is ignored.
-    STDMETHOD(GetExceptionFilterParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Codes,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
-        ) PURE;
-    // The codes in the parameter data control the application
-    // of the parameter data.  If a code is not already in
-    // the set of filters it is added.  If the ExecutionOption
-    // for a code is REMOVE then the filter is removed.
-    // Specific exception filters cannot be removed.
-    STDMETHOD(SetExceptionFilterParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
-        ) PURE;
-    // Exception filters support an additional command for
-    // second-chance events.
-    STDMETHOD(GetExceptionFilterSecondCommand)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetExceptionFilterSecondCommand)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Command
-        ) PURE;
-
-    // Yields processing to the engine until
-    // an event occurs.  This method may
-    // only be called by the thread that started
-    // the debug session.
-    // When an event occurs the engine carries
-    // out all event processing such as calling
-    // callbacks.
-    // If the callbacks indicate that execution should
-    // break the wait will return, otherwise it
-    // goes back to waiting for a new event.
-    // If the timeout expires, S_FALSE is returned.
-    // The timeout is not currently supported for
-    // kernel debugging.
-    STDMETHOD(WaitForEvent)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG Timeout
-        ) PURE;
-
-    // Retrieves information about the last event that occurred.
-    // EventType is one of the event callback mask bits.
-    // ExtraInformation contains additional event-specific
-    // information.  Not all events have additional information.
-    STDMETHOD(GetLastEventInformation)(
-        THIS_
-        __out PULONG Type,
-        __out PULONG ProcessId,
-        __out PULONG ThreadId,
-        __out_bcount_opt(ExtraInformationSize) PVOID ExtraInformation,
-        __in ULONG ExtraInformationSize,
-        __out_opt PULONG ExtraInformationUsed,
-        __out_ecount_opt(DescriptionSize) PSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG DescriptionUsed
-        ) PURE;
-
-    // IDebugControl2.
-
-    STDMETHOD(GetCurrentTimeDate)(
-        THIS_
-        __out PULONG TimeDate
-        ) PURE;
-    // Retrieves the number of seconds since the
-    // machine started running.
-    STDMETHOD(GetCurrentSystemUpTime)(
-        THIS_
-        __out PULONG UpTime
-        ) PURE;
-
-    // If the current session is a dump session,
-    // retrieves any extended format information.
-    STDMETHOD(GetDumpFormatFlags)(
-        THIS_
-        __out PULONG FormatFlags
-        ) PURE;
-
-    // The debugger has been enhanced to allow
-    // arbitrary text replacements in addition
-    // to the simple $u0-$u9 text macros.
-    // Text replacement takes a given source
-    // text in commands and converts it to the
-    // given destination text.  Replacements
-    // are named by their source text so that
-    // only one replacement for a source text
-    // string can exist.
-    STDMETHOD(GetNumberTextReplacements)(
-        THIS_
-        __out PULONG NumRepl
-        ) PURE;
-    // If SrcText is non-NULL the replacement
-    // is looked up by source text, otherwise
-    // Index is used to get the Nth replacement.
-    STDMETHOD(GetTextReplacement)(
-        THIS_
-        __in_opt PCSTR SrcText,
-        __in ULONG Index,
-        __out_ecount_opt(SrcBufferSize) PSTR SrcBuffer,
-        __in ULONG SrcBufferSize,
-        __out_opt PULONG SrcSize,
-        __out_ecount_opt(DstBufferSize) PSTR DstBuffer,
-        __in ULONG DstBufferSize,
-        __out_opt PULONG DstSize
-        ) PURE;
-    // Setting the destination text to
-    // NULL removes the alias.
-    STDMETHOD(SetTextReplacement)(
-        THIS_
-        __in PCSTR SrcText,
-        __in_opt PCSTR DstText
-        ) PURE;
-    STDMETHOD(RemoveTextReplacements)(
-        THIS
-        ) PURE;
-    // Outputs the complete list of current
-    // replacements.
-    STDMETHOD(OutputTextReplacements)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags
-        ) PURE;
-};
-
-//
-// Assembly/disassembly options.
-//
-// The specific effects of these flags varies depending
-// on the particular instruction set.
-//
-
-#define DEBUG_ASMOPT_DEFAULT             0x00000000
-// Display additional information in disassembly.
-#define DEBUG_ASMOPT_VERBOSE             0x00000001
-// Do not display raw code bytes in disassembly.
-#define DEBUG_ASMOPT_NO_CODE_BYTES       0x00000002
-// Do not take the output width into account when
-// formatting disassembly.
-#define DEBUG_ASMOPT_IGNORE_OUTPUT_WIDTH 0x00000004
-// Display source file line number before each line if available.
-#define DEBUG_ASMOPT_SOURCE_LINE_NUMBER  0x00000008
-
-//
-// Expression syntax options.
-//
-
-// MASM-style expression evaluation.
-#define DEBUG_EXPR_MASM      0x00000000
-// C++-style expression evaluation.
-#define DEBUG_EXPR_CPLUSPLUS 0x00000001
-
-//
-// Event index description information.
-//
-
-#define DEBUG_EINDEX_NAME 0x00000000
-
-//
-// SetNextEventIndex relation options.
-//
-
-// Value increases forward from the first index.
-#define DEBUG_EINDEX_FROM_START   0x00000000
-// Value increases backwards from the last index.
-#define DEBUG_EINDEX_FROM_END     0x00000001
-// Value is a signed delta from the current index.
-#define DEBUG_EINDEX_FROM_CURRENT 0x00000002
-
-#undef INTERFACE
-#define INTERFACE IDebugControl3
-DECLARE_INTERFACE_(IDebugControl3, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugControl.
-
-    // Checks for a user interrupt, such a Ctrl-C
-    // or stop button.
-    // This method is reentrant.
-    STDMETHOD(GetInterrupt)(
-        THIS
-        ) PURE;
-    // Registers a user interrupt.
-    // This method is reentrant.
-    STDMETHOD(SetInterrupt)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Interrupting a user-mode process requires
-    // access to some system resources that the
-    // process may hold itself, preventing the
-    // interrupt from occurring.  The engine
-    // will time-out pending interrupt requests
-    // and simulate an interrupt if necessary.
-    // These methods control the interrupt timeout.
-    STDMETHOD(GetInterruptTimeout)(
-        THIS_
-        __out PULONG Seconds
-        ) PURE;
-    STDMETHOD(SetInterruptTimeout)(
-        THIS_
-        __in ULONG Seconds
-        ) PURE;
-
-    STDMETHOD(GetLogFile)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FileSize,
-        __out PBOOL Append
-        ) PURE;
-    // Opens a log file which collects all
-    // output.  Output from every client except
-    // those that explicitly disable logging
-    // goes into the log.
-    // Opening a log file closes any log file
-    // already open.
-    STDMETHOD(OpenLogFile)(
-        THIS_
-        __in PCSTR File,
-        __in BOOL Append
-        ) PURE;
-    STDMETHOD(CloseLogFile)(
-        THIS
-        ) PURE;
-    // Controls what output is logged.
-    STDMETHOD(GetLogMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetLogMask)(
-        THIS_
-        __in ULONG Mask
-        ) PURE;
-
-    // Input requests input from all clients.
-    // The first input that is returned is used
-    // to satisfy the call.  Other returned
-    // input is discarded.
-    STDMETHOD(Input)(
-        THIS_
-        __out_ecount(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InputSize
-        ) PURE;
-    // This method is used by clients to return
-    // input when it is available.  It will
-    // return S_OK if the input is used to
-    // satisfy an Input call and S_FALSE if
-    // the input is ignored.
-    // This method is reentrant.
-    STDMETHOD(ReturnInput)(
-        THIS_
-        __in PCSTR Buffer
-        ) PURE;
-
-    // Sends output through clients
-    // output callbacks if the mask is allowed
-    // by the current output control mask and
-    // according to the output distribution
-    // settings.
-    STDMETHODV(Output)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputVaList)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Format,
-        __in va_list Args
-        ) PURE;
-    // The following methods allow direct control
-    // over the distribution of the given output
-    // for situations where something other than
-    // the default is desired.  These methods require
-    // extra work in the engine so they should
-    // only be used when necessary.
-    STDMETHODV(ControlledOutput)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(ControlledOutputVaList)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCSTR Format,
-        __in va_list Args
-        ) PURE;
-
-    // Displays the standard command-line prompt
-    // followed by the given output.  If Format
-    // is NULL no additional output is produced.
-    // Output is produced under the
-    // DEBUG_OUTPUT_PROMPT mask.
-    // This method only outputs the prompt; it
-    // does not get input.
-    STDMETHODV(OutputPrompt)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputPromptVaList)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCSTR Format,
-        __in va_list Args
-        ) PURE;
-    // Gets the text that would be displayed by OutputPrompt.
-    STDMETHOD(GetPromptText)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-    // Outputs information about the current
-    // debuggee state such as a register
-    // summary, disassembly at the current PC,
-    // closest symbol and others.
-    // Uses the line prefix.
-    STDMETHOD(OutputCurrentState)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags
-        ) PURE;
-
-    // Outputs the debugger and extension version
-    // information.  This method is reentrant.
-    // Uses the line prefix.
-    STDMETHOD(OutputVersionInformation)(
-        THIS_
-        __in ULONG OutputControl
-        ) PURE;
-
-    // In user-mode debugging sessions the
-    // engine will set an event when
-    // exceptions are continued.  This can
-    // be used to synchronize other processes
-    // with the debuggers handling of events.
-    // For example, this is used to support
-    // the e argument to ntsd.
-    STDMETHOD(GetNotifyEventHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(SetNotifyEventHandle)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-
-    STDMETHOD(Assemble)(
-        THIS_
-        __in ULONG64 Offset,
-        __in PCSTR Instr,
-        __out PULONG64 EndOffset
-        ) PURE;
-    STDMETHOD(Disassemble)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DisassemblySize,
-        __out PULONG64 EndOffset
-        ) PURE;
-    // Returns the value of the effective address
-    // computed for the last Disassemble, if there
-    // was one.
-    STDMETHOD(GetDisassembleEffectiveOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Uses the line prefix if necessary.
-    STDMETHOD(OutputDisassembly)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out PULONG64 EndOffset
-        ) PURE;
-    // Produces multiple lines of disassembly output.
-    // There will be PreviousLines of disassembly before
-    // the given offset if a valid disassembly exists.
-    // In all, there will be TotalLines of output produced.
-    // The first and last line offsets are returned
-    // specially and all lines offsets can be retrieved
-    // through LineOffsets.  LineOffsets will contain
-    // offsets for each line where disassembly started.
-    // When disassembly of a single instruction takes
-    // multiple lines the initial offset will be followed
-    // by DEBUG_INVALID_OFFSET.
-    // Uses the line prefix.
-    STDMETHOD(OutputDisassemblyLines)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG PreviousLines,
-        __in ULONG TotalLines,
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_opt PULONG OffsetLine,
-        __out_opt PULONG64 StartOffset,
-        __out_opt PULONG64 EndOffset,
-        __out_ecount_opt(TotalLines) PULONG64 LineOffsets
-        ) PURE;
-    // Returns the offset of the start of
-    // the instruction thats the given
-    // delta away from the instruction
-    // at the initial offset.
-    // This routine does not check for
-    // validity of the instruction or
-    // the memory containing it.
-    STDMETHOD(GetNearInstruction)(
-        THIS_
-        __in ULONG64 Offset,
-        __in LONG Delta,
-        __out PULONG64 NearOffset
-        ) PURE;
-
-    // Offsets can be passed in as zero to use the current
-    // thread state.
-    STDMETHOD(GetStackTrace)(
-        THIS_
-        __in ULONG64 FrameOffset,
-        __in ULONG64 StackOffset,
-        __in ULONG64 InstructionOffset,
-        __out_ecount(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __out_opt PULONG FramesFilled
-        ) PURE;
-    // Does a simple stack trace to determine
-    // what the current return address is.
-    STDMETHOD(GetReturnOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // If Frames is NULL OutputStackTrace will
-    // use GetStackTrace to get FramesSize frames
-    // and then output them.  The current register
-    // values for frame, stack and instruction offsets
-    // are used.
-    // Uses the line prefix.
-    STDMETHOD(OutputStackTrace)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_ecount_opt(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __in ULONG Flags
-        ) PURE;
-
-    // Returns information about the debuggee such
-    // as user vs. kernel, dump vs. live, etc.
-    STDMETHOD(GetDebuggeeType)(
-        THIS_
-        __out PULONG Class,
-        __out PULONG Qualifier
-        ) PURE;
-    // Returns the type of physical processors in
-    // the machine.
-    // Returns one of the IMAGE_FILE_MACHINE values.
-    STDMETHOD(GetActualProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    // Returns the type of processor used in the
-    // current processor context.
-    STDMETHOD(GetExecutingProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    // Query all the possible processor types that
-    // may be encountered during this debug session.
-    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetPossibleExecutingProcessorTypes)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Types
-        ) PURE;
-    // Get the number of actual processors in
-    // the machine.
-    STDMETHOD(GetNumberProcessors)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // PlatformId is one of the VER_PLATFORM values.
-    // Major and minor are as given in the NT
-    // kernel debugger protocol.
-    // ServicePackString and ServicePackNumber indicate the
-    // system service pack level.  ServicePackNumber is not
-    // available in some sessions where the service pack level
-    // is only expressed as a string.  The service pack information
-    // will be empty if the system does not have a service pack
-    // applied.
-    // The build string is string information identifying the
-    // particular build of the system.  The build string is
-    // empty if the system has no particular identifying
-    // information.
-    STDMETHOD(GetSystemVersion)(
-        THIS_
-        __out PULONG PlatformId,
-        __out PULONG Major,
-        __out PULONG Minor,
-        __out_ecount_opt(ServicePackStringSize) PSTR ServicePackString,
-        __in ULONG ServicePackStringSize,
-        __out_opt PULONG ServicePackStringUsed,
-        __out PULONG ServicePackNumber,
-        __out_ecount_opt(BuildStringSize) PSTR BuildString,
-        __in ULONG BuildStringSize,
-        __out_opt PULONG BuildStringUsed
-        ) PURE;
-    // Returns the page size for the currently executing
-    // processor context.  The page size may vary between
-    // processor types.
-    STDMETHOD(GetPageSize)(
-        THIS_
-        __out PULONG Size
-        ) PURE;
-    // Returns S_OK if the current processor context uses
-    // 64-bit addresses, otherwise S_FALSE.
-    STDMETHOD(IsPointer64Bit)(
-        THIS
-        ) PURE;
-    // Reads the bugcheck data area and returns the
-    // current contents.  This method only works
-    // in kernel debugging sessions.
-    STDMETHOD(ReadBugCheckData)(
-        THIS_
-        __out PULONG Code,
-        __out PULONG64 Arg1,
-        __out PULONG64 Arg2,
-        __out PULONG64 Arg3,
-        __out PULONG64 Arg4
-        ) PURE;
-
-    // Query all the processor types supported by
-    // the engine.  This is a complete list and is
-    // not related to the machine running the engine
-    // or the debuggee.
-    STDMETHOD(GetNumberSupportedProcessorTypes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetSupportedProcessorTypes)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Types
-        ) PURE;
-    // Returns a full, descriptive name and an
-    // abbreviated name for a processor type.
-    STDMETHOD(GetProcessorTypeNames)(
-        THIS_
-        __in ULONG Type,
-        __out_ecount_opt(FullNameBufferSize) PSTR FullNameBuffer,
-        __in ULONG FullNameBufferSize,
-        __out_opt PULONG FullNameSize,
-        __out_ecount_opt(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
-        __in ULONG AbbrevNameBufferSize,
-        __out_opt PULONG AbbrevNameSize
-        ) PURE;
-
-    // Gets and sets the type of processor to
-    // use when doing things like setting
-    // breakpoints, accessing registers,
-    // getting stack traces and so on.
-    STDMETHOD(GetEffectiveProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    STDMETHOD(SetEffectiveProcessorType)(
-        THIS_
-        __in ULONG Type
-        ) PURE;
-
-    // Returns information about whether and how
-    // the debuggee is running.  Status will
-    // be GO if the debuggee is running and
-    // BREAK if it isnt.
-    // If no debuggee exists the status is
-    // NO_DEBUGGEE.
-    // This method is reentrant.
-    STDMETHOD(GetExecutionStatus)(
-        THIS_
-        __out PULONG Status
-        ) PURE;
-    // Changes the execution status of the
-    // engine from stopped to running.
-    // Status must be one of the go or step
-    // status values.
-    STDMETHOD(SetExecutionStatus)(
-        THIS_
-        __in ULONG Status
-        ) PURE;
-
-    // Controls what code interpretation level the debugger
-    // runs at.  The debugger checks the code level when
-    // deciding whether to step by a source line or
-    // assembly instruction along with other related operations.
-    STDMETHOD(GetCodeLevel)(
-        THIS_
-        __out PULONG Level
-        ) PURE;
-    STDMETHOD(SetCodeLevel)(
-        THIS_
-        __in ULONG Level
-        ) PURE;
-
-    // Gets and sets engine control flags.
-    // These methods are reentrant.
-    STDMETHOD(GetEngineOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Gets and sets control values for
-    // handling system error events.
-    // If the system error level is less
-    // than or equal to the given levels
-    // the error may be displayed and
-    // the default break for the event
-    // may be set.
-    STDMETHOD(GetSystemErrorControl)(
-        THIS_
-        __out PULONG OutputLevel,
-        __out PULONG BreakLevel
-        ) PURE;
-    STDMETHOD(SetSystemErrorControl)(
-        THIS_
-        __in ULONG OutputLevel,
-        __in ULONG BreakLevel
-        ) PURE;
-
-    // The command processor supports simple
-    // string replacement macros in Evaluate and
-    // Execute.  There are currently ten macro
-    // slots available.  Slots 0-9 map to
-    // the command invocations $u0-$u9.
-    STDMETHOD(GetTextMacro)(
-        THIS_
-        __in ULONG Slot,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG MacroSize
-        ) PURE;
-    STDMETHOD(SetTextMacro)(
-        THIS_
-        __in ULONG Slot,
-        __in PCSTR Macro
-        ) PURE;
-
-    // Controls the default number radix used
-    // in expressions and commands.
-    STDMETHOD(GetRadix)(
-        THIS_
-        __out PULONG Radix
-        ) PURE;
-    STDMETHOD(SetRadix)(
-        THIS_
-        __in ULONG Radix
-        ) PURE;
-
-    // Evaluates the given expression string and
-    // returns the resulting value.
-    // If DesiredType is DEBUG_VALUE_INVALID then
-    // the natural type is used.
-    // RemainderIndex, if provided, is set to the index
-    // of the first character in the input string that was
-    // not used when evaluating the expression.
-    STDMETHOD(Evaluate)(
-        THIS_
-        __in PCSTR Expression,
-        __in ULONG DesiredType,
-        __out PDEBUG_VALUE Value,
-        __out_opt PULONG RemainderIndex
-        ) PURE;
-    // Attempts to convert the input value to a value
-    // of the requested type in the output value.
-    // Conversions can fail if no conversion exists.
-    // Successful conversions may be lossy.
-    STDMETHOD(CoerceValue)(
-        THIS_
-        __in PDEBUG_VALUE In,
-        __in ULONG OutType,
-        __out PDEBUG_VALUE Out
-        ) PURE;
-    STDMETHOD(CoerceValues)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_VALUE In,
-        __in_ecount(Count) PULONG OutTypes,
-        __out_ecount(Count) PDEBUG_VALUE Out
-        ) PURE;
-
-    // Executes the given command string.
-    // If the string has multiple commands
-    // Execute will not return until all
-    // of them have been executed.  If this
-    // requires waiting for the debuggee to
-    // execute an internal wait will be done
-    // so Execute can take an arbitrary amount
-    // of time.
-    STDMETHOD(Execute)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR Command,
-        __in ULONG Flags
-        ) PURE;
-    // Executes the given command file by
-    // reading a line at a time and processing
-    // it with Execute.
-    STDMETHOD(ExecuteCommandFile)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR CommandFile,
-        __in ULONG Flags
-        ) PURE;
-
-    // Breakpoint interfaces are described
-    // elsewhere in this section.
-    STDMETHOD(GetNumberBreakpoints)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // It is possible for this retrieval function to
-    // fail even with an index within the number of
-    // existing breakpoints if the breakpoint is
-    // a private breakpoint.
-    STDMETHOD(GetBreakpointByIndex)(
-        THIS_
-        __in ULONG Index,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    STDMETHOD(GetBreakpointById)(
-        THIS_
-        __in ULONG Id,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    // If Ids is non-NULL the Count breakpoints
-    // referred to in the Ids array are returned,
-    // otherwise breakpoints from index Start to
-    // Start + Count  1 are returned.
-    STDMETHOD(GetBreakpointParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Ids,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
-        ) PURE;
-    // Breakpoints are created empty and disabled.
-    // When their parameters have been set they
-    // should be enabled by setting the ENABLE flag.
-    // If DesiredId is DEBUG_ANY_ID then the
-    // engine picks an unused ID.  If DesiredId
-    // is any other number the engine attempts
-    // to use the given ID for the breakpoint.
-    // If another breakpoint exists with that ID
-    // the call will fail.
-    STDMETHOD(AddBreakpoint)(
-        THIS_
-        __in ULONG Type,
-        __in ULONG DesiredId,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    // Breakpoint interface is invalid after this call.
-    STDMETHOD(RemoveBreakpoint)(
-        THIS_
-        __in PDEBUG_BREAKPOINT Bp
-        ) PURE;
-
-    // Control and use extension DLLs.
-    STDMETHOD(AddExtension)(
-        THIS_
-        __in PCSTR Path,
-        __in ULONG Flags,
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(RemoveExtension)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-    STDMETHOD(GetExtensionByPath)(
-        THIS_
-        __in PCSTR Path,
-        __out PULONG64 Handle
-        ) PURE;
-    // If Handle is zero the extension
-    // chain is walked searching for the
-    // function.
-    STDMETHOD(CallExtension)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCSTR Function,
-        __in_opt PCSTR Arguments
-        ) PURE;
-    // GetExtensionFunction works like
-    // GetProcAddress on extension DLLs
-    // to allow raw function-call-level
-    // interaction with extension DLLs.
-    // Such functions do not need to
-    // follow the standard extension prototype
-    // if they are not going to be called
-    // through the text extension interface.
-    // This function cannot be called remotely.
-    STDMETHOD(GetExtensionFunction)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCSTR FuncName,
-        __out FARPROC* Function
-        ) PURE;
-    // These methods return alternate
-    // extension interfaces in order to allow
-    // interface-style extension DLLs to mix in
-    // older extension calls.
-    // Structure sizes must be initialized before
-    // the call.
-    // These methods cannot be called remotely.
-    STDMETHOD(GetWindbgExtensionApis32)(
-        THIS_
-        __inout PWINDBG_EXTENSION_APIS32 Api
-        ) PURE;
-    STDMETHOD(GetWindbgExtensionApis64)(
-        THIS_
-        __inout PWINDBG_EXTENSION_APIS64 Api
-        ) PURE;
-
-    // The engine provides a simple mechanism
-    // to filter common events.  Arbitrarily complicated
-    // filtering can be done by registering event callbacks
-    // but simple event filtering only requires
-    // setting the options of one of the predefined
-    // event filters.
-    // Simple event filters are either for specific
-    // events and therefore have an enumerant or
-    // they are for an exception and are based on
-    // the exceptions code.  Exception filters
-    // are further divided into exceptions specially
-    // handled by the engine, which is a fixed set,
-    // and arbitrary exceptions.
-    // All three groups of filters are indexed together
-    // with the specific filters first, then the specific
-    // exception filters and finally the arbitrary
-    // exception filters.
-    // The first specific exception is the default
-    // exception.  If an exception event occurs for
-    // an exception without settings the default
-    // exception settings are used.
-    STDMETHOD(GetNumberEventFilters)(
-        THIS_
-        __out PULONG SpecificEvents,
-        __out PULONG SpecificExceptions,
-        __out PULONG ArbitraryExceptions
-        ) PURE;
-    // Some filters have descriptive text associated with them.
-    STDMETHOD(GetEventFilterText)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-    // All filters support executing a command when the
-    // event occurs.
-    STDMETHOD(GetEventFilterCommand)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetEventFilterCommand)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Command
-        ) PURE;
-    STDMETHOD(GetSpecificFilterParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
-        ) PURE;
-    STDMETHOD(SetSpecificFilterParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
-        ) PURE;
-    // Some specific filters have arguments to further
-    // qualify their operation.
-    STDMETHOD(GetSpecificFilterArgument)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ArgumentSize
-        ) PURE;
-    STDMETHOD(SetSpecificFilterArgument)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Argument
-        ) PURE;
-    // If Codes is non-NULL Start is ignored.
-    STDMETHOD(GetExceptionFilterParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Codes,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
-        ) PURE;
-    // The codes in the parameter data control the application
-    // of the parameter data.  If a code is not already in
-    // the set of filters it is added.  If the ExecutionOption
-    // for a code is REMOVE then the filter is removed.
-    // Specific exception filters cannot be removed.
-    STDMETHOD(SetExceptionFilterParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
-        ) PURE;
-    // Exception filters support an additional command for
-    // second-chance events.
-    STDMETHOD(GetExceptionFilterSecondCommand)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetExceptionFilterSecondCommand)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Command
-        ) PURE;
-
-    // Yields processing to the engine until
-    // an event occurs.  This method may
-    // only be called by the thread that started
-    // the debug session.
-    // When an event occurs the engine carries
-    // out all event processing such as calling
-    // callbacks.
-    // If the callbacks indicate that execution should
-    // break the wait will return, otherwise it
-    // goes back to waiting for a new event.
-    // If the timeout expires, S_FALSE is returned.
-    // The timeout is not currently supported for
-    // kernel debugging.
-    STDMETHOD(WaitForEvent)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG Timeout
-        ) PURE;
-
-    // Retrieves information about the last event that occurred.
-    // EventType is one of the event callback mask bits.
-    // ExtraInformation contains additional event-specific
-    // information.  Not all events have additional information.
-    STDMETHOD(GetLastEventInformation)(
-        THIS_
-        __out PULONG Type,
-        __out PULONG ProcessId,
-        __out PULONG ThreadId,
-        __out_bcount_opt(ExtraInformationSize) PVOID ExtraInformation,
-        __in ULONG ExtraInformationSize,
-        __out_opt PULONG ExtraInformationUsed,
-        __out_ecount_opt(DescriptionSize) PSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG DescriptionUsed
-        ) PURE;
-
-    // IDebugControl2.
-
-    STDMETHOD(GetCurrentTimeDate)(
-        THIS_
-        __out PULONG TimeDate
-        ) PURE;
-    // Retrieves the number of seconds since the
-    // machine started running.
-    STDMETHOD(GetCurrentSystemUpTime)(
-        THIS_
-        __out PULONG UpTime
-        ) PURE;
-
-    // If the current session is a dump session,
-    // retrieves any extended format information.
-    STDMETHOD(GetDumpFormatFlags)(
-        THIS_
-        __out PULONG FormatFlags
-        ) PURE;
-
-    // The debugger has been enhanced to allow
-    // arbitrary text replacements in addition
-    // to the simple $u0-$u9 text macros.
-    // Text replacement takes a given source
-    // text in commands and converts it to the
-    // given destination text.  Replacements
-    // are named by their source text so that
-    // only one replacement for a source text
-    // string can exist.
-    STDMETHOD(GetNumberTextReplacements)(
-        THIS_
-        __out PULONG NumRepl
-        ) PURE;
-    // If SrcText is non-NULL the replacement
-    // is looked up by source text, otherwise
-    // Index is used to get the Nth replacement.
-    STDMETHOD(GetTextReplacement)(
-        THIS_
-        __in_opt PCSTR SrcText,
-        __in ULONG Index,
-        __out_ecount_opt(SrcBufferSize) PSTR SrcBuffer,
-        __in ULONG SrcBufferSize,
-        __out_opt PULONG SrcSize,
-        __out_ecount_opt(DstBufferSize) PSTR DstBuffer,
-        __in ULONG DstBufferSize,
-        __out_opt PULONG DstSize
-        ) PURE;
-    // Setting the destination text to
-    // NULL removes the alias.
-    STDMETHOD(SetTextReplacement)(
-        THIS_
-        __in PCSTR SrcText,
-        __in_opt PCSTR DstText
-        ) PURE;
-    STDMETHOD(RemoveTextReplacements)(
-        THIS
-        ) PURE;
-    // Outputs the complete list of current
-    // replacements.
-    STDMETHOD(OutputTextReplacements)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags
-        ) PURE;
-
-    // IDebugControl3.
-
-    // Control options for assembly and disassembly.
-    STDMETHOD(GetAssemblyOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddAssemblyOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveAssemblyOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetAssemblyOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Control the expression syntax.
-    STDMETHOD(GetExpressionSyntax)(
-        THIS_
-        __out PULONG Flags
-        ) PURE;
-    STDMETHOD(SetExpressionSyntax)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Look up a syntax by its abbreviated
-    // name and set it.
-    STDMETHOD(SetExpressionSyntaxByName)(
-        THIS_
-        __in PCSTR AbbrevName
-        ) PURE;
-    STDMETHOD(GetNumberExpressionSyntaxes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetExpressionSyntaxNames)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(FullNameBufferSize) PSTR FullNameBuffer,
-        __in ULONG FullNameBufferSize,
-        __out_opt PULONG FullNameSize,
-        __out_ecount_opt(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
-        __in ULONG AbbrevNameBufferSize,
-        __out_opt PULONG AbbrevNameSize
-        ) PURE;
-
-    //
-    // Some debug sessions have only a single
-    // possible event, such as a snapshot dump
-    // file; some have dynamic events, such as
-    // a live debug session; and others may have
-    // multiple events, such as a dump file that
-    // contains snapshots from different points
-    // in time.  The following methods allow
-    // discovery and selection of the available
-    // events for a session.
-    // Sessions with one or more static events
-    // will be able to report all of the events
-    // when queried.  Sessions with dynamic events
-    // will only report a single event representing
-    // the current event.
-    // Switching events constitutes execution and
-    // changing the current event will alter the
-    // execution status to a running state, after
-    // which WaitForEvent must be used to process
-    // the selected event.
-    //
-
-    // GetNumberEvents returns S_OK if this is the
-    // complete set of events possible, such as for
-    // a static session; or S_FALSE if other events
-    // may be possible, such as for a dynamic session.
-    STDMETHOD(GetNumberEvents)(
-        THIS_
-        __out PULONG Events
-        ) PURE;
-    // Sessions may have descriptive information for
-    // the various events available.  The amount of
-    // information varies according to the specific
-    // session and data.
-    STDMETHOD(GetEventIndexDescription)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG Which,
-        __in_opt PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DescSize
-        ) PURE;
-    STDMETHOD(GetCurrentEventIndex)(
-        THIS_
-        __out PULONG Index
-        ) PURE;
-    // SetNextEventIndex works like seek in that
-    // it can set an absolute or relative index.
-    // SetNextEventIndex works similarly to SetExecutionStatus
-    // by putting the session into a running state, after
-    // which the caller must call WaitForEvent.  The
-    // current event index only changes when WaitForEvent
-    // is called.
-    STDMETHOD(SetNextEventIndex)(
-        THIS_
-        __in ULONG Relation,
-        __in ULONG Value,
-        __out PULONG NextIndex
-        ) PURE;
-};
-
-//
-// Log file flags.
-//
-
-#define DEBUG_LOG_DEFAULT 0x00000000
-#define DEBUG_LOG_APPEND  0x00000001
-#define DEBUG_LOG_UNICODE 0x00000002
-#define DEBUG_LOG_DML     0x00000004
-
-//
-// System version strings.
-//
-
-#define DEBUG_SYSVERSTR_SERVICE_PACK 0x00000000
-#define DEBUG_SYSVERSTR_BUILD        0x00000001
-
-//
-// GetManagedStatus flags and strings.
-//
-
-#define DEBUG_MANAGED_DISABLED   0x00000000
-#define DEBUG_MANAGED_ALLOWED    0x00000001
-#define DEBUG_MANAGED_DLL_LOADED 0x00000002
-
-#define DEBUG_MANSTR_NONE               0x00000000
-#define DEBUG_MANSTR_LOADED_SUPPORT_DLL 0x00000001
-#define DEBUG_MANSTR_LOAD_STATUS        0x00000002
-
-//
-// ResetManagedStatus flags.
-//
-
-// Reset state to default engine startup state with
-// no support loaded.
-#define DEBUG_MANRESET_DEFAULT  0x00000000
-// Force managed support DLL load attempt.
-#define DEBUG_MANRESET_LOAD_DLL 0x00000001
-
-#undef INTERFACE
-#define INTERFACE IDebugControl4
-DECLARE_INTERFACE_(IDebugControl4, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugControl.
-
-    // Checks for a user interrupt, such a Ctrl-C
-    // or stop button.
-    // This method is reentrant.
-    STDMETHOD(GetInterrupt)(
-        THIS
-        ) PURE;
-    // Registers a user interrupt.
-    // This method is reentrant.
-    STDMETHOD(SetInterrupt)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Interrupting a user-mode process requires
-    // access to some system resources that the
-    // process may hold itself, preventing the
-    // interrupt from occurring.  The engine
-    // will time-out pending interrupt requests
-    // and simulate an interrupt if necessary.
-    // These methods control the interrupt timeout.
-    STDMETHOD(GetInterruptTimeout)(
-        THIS_
-        __out PULONG Seconds
-        ) PURE;
-    STDMETHOD(SetInterruptTimeout)(
-        THIS_
-        __in ULONG Seconds
-        ) PURE;
-
-    STDMETHOD(GetLogFile)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FileSize,
-        __out PBOOL Append
-        ) PURE;
-    // Opens a log file which collects all
-    // output.  Output from every client except
-    // those that explicitly disable logging
-    // goes into the log.
-    // Opening a log file closes any log file
-    // already open.
-    STDMETHOD(OpenLogFile)(
-        THIS_
-        __in PCSTR File,
-        __in BOOL Append
-        ) PURE;
-    STDMETHOD(CloseLogFile)(
-        THIS
-        ) PURE;
-    // Controls what output is logged.
-    STDMETHOD(GetLogMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    STDMETHOD(SetLogMask)(
-        THIS_
-        __in ULONG Mask
-        ) PURE;
-
-    // Input requests input from all clients.
-    // The first input that is returned is used
-    // to satisfy the call.  Other returned
-    // input is discarded.
-    STDMETHOD(Input)(
-        THIS_
-        __out_ecount(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InputSize
-        ) PURE;
-    // This method is used by clients to return
-    // input when it is available.  It will
-    // return S_OK if the input is used to
-    // satisfy an Input call and S_FALSE if
-    // the input is ignored.
-    // This method is reentrant.
-    STDMETHOD(ReturnInput)(
-        THIS_
-        __in PCSTR Buffer
-        ) PURE;
-
-    // Sends output through clients
-    // output callbacks if the mask is allowed
-    // by the current output control mask and
-    // according to the output distribution
-    // settings.
-    STDMETHODV(Output)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputVaList)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Format,
-        __in va_list Args
-        ) PURE;
-    // The following methods allow direct control
-    // over the distribution of the given output
-    // for situations where something other than
-    // the default is desired.  These methods require
-    // extra work in the engine so they should
-    // only be used when necessary.
-    STDMETHODV(ControlledOutput)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(ControlledOutputVaList)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCSTR Format,
-        __in va_list Args
-        ) PURE;
-
-    // Displays the standard command-line prompt
-    // followed by the given output.  If Format
-    // is NULL no additional output is produced.
-    // Output is produced under the
-    // DEBUG_OUTPUT_PROMPT mask.
-    // This method only outputs the prompt; it
-    // does not get input.
-    STDMETHODV(OutputPrompt)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputPromptVaList)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCSTR Format,
-        __in va_list Args
-        ) PURE;
-    // Gets the text that would be displayed by OutputPrompt.
-    STDMETHOD(GetPromptText)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-    // Outputs information about the current
-    // debuggee state such as a register
-    // summary, disassembly at the current PC,
-    // closest symbol and others.
-    // Uses the line prefix.
-    STDMETHOD(OutputCurrentState)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags
-        ) PURE;
-
-    // Outputs the debugger and extension version
-    // information.  This method is reentrant.
-    // Uses the line prefix.
-    STDMETHOD(OutputVersionInformation)(
-        THIS_
-        __in ULONG OutputControl
-        ) PURE;
-
-    // In user-mode debugging sessions the
-    // engine will set an event when
-    // exceptions are continued.  This can
-    // be used to synchronize other processes
-    // with the debuggers handling of events.
-    // For example, this is used to support
-    // the e argument to ntsd.
-    STDMETHOD(GetNotifyEventHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(SetNotifyEventHandle)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-
-    STDMETHOD(Assemble)(
-        THIS_
-        __in ULONG64 Offset,
-        __in PCSTR Instr,
-        __out PULONG64 EndOffset
-        ) PURE;
-    STDMETHOD(Disassemble)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DisassemblySize,
-        __out PULONG64 EndOffset
-        ) PURE;
-    // Returns the value of the effective address
-    // computed for the last Disassemble, if there
-    // was one.
-    STDMETHOD(GetDisassembleEffectiveOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Uses the line prefix if necessary.
-    STDMETHOD(OutputDisassembly)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out PULONG64 EndOffset
-        ) PURE;
-    // Produces multiple lines of disassembly output.
-    // There will be PreviousLines of disassembly before
-    // the given offset if a valid disassembly exists.
-    // In all, there will be TotalLines of output produced.
-    // The first and last line offsets are returned
-    // specially and all lines offsets can be retrieved
-    // through LineOffsets.  LineOffsets will contain
-    // offsets for each line where disassembly started.
-    // When disassembly of a single instruction takes
-    // multiple lines the initial offset will be followed
-    // by DEBUG_INVALID_OFFSET.
-    // Uses the line prefix.
-    STDMETHOD(OutputDisassemblyLines)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG PreviousLines,
-        __in ULONG TotalLines,
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_opt PULONG OffsetLine,
-        __out_opt PULONG64 StartOffset,
-        __out_opt PULONG64 EndOffset,
-        __out_ecount_opt(TotalLines) PULONG64 LineOffsets
-        ) PURE;
-    // Returns the offset of the start of
-    // the instruction thats the given
-    // delta away from the instruction
-    // at the initial offset.
-    // This routine does not check for
-    // validity of the instruction or
-    // the memory containing it.
-    STDMETHOD(GetNearInstruction)(
-        THIS_
-        __in ULONG64 Offset,
-        __in LONG Delta,
-        __out PULONG64 NearOffset
-        ) PURE;
-
-    // Offsets can be passed in as zero to use the current
-    // thread state.
-    STDMETHOD(GetStackTrace)(
-        THIS_
-        __in ULONG64 FrameOffset,
-        __in ULONG64 StackOffset,
-        __in ULONG64 InstructionOffset,
-        __out_ecount(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __out_opt PULONG FramesFilled
-        ) PURE;
-    // Does a simple stack trace to determine
-    // what the current return address is.
-    STDMETHOD(GetReturnOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // If Frames is NULL OutputStackTrace will
-    // use GetStackTrace to get FramesSize frames
-    // and then output them.  The current register
-    // values for frame, stack and instruction offsets
-    // are used.
-    // Uses the line prefix.
-    STDMETHOD(OutputStackTrace)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_ecount_opt(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __in ULONG Flags
-        ) PURE;
-
-    // Returns information about the debuggee such
-    // as user vs. kernel, dump vs. live, etc.
-    STDMETHOD(GetDebuggeeType)(
-        THIS_
-        __out PULONG Class,
-        __out PULONG Qualifier
-        ) PURE;
-    // Returns the type of physical processors in
-    // the machine.
-    // Returns one of the IMAGE_FILE_MACHINE values.
-    STDMETHOD(GetActualProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    // Returns the type of processor used in the
-    // current processor context.
-    STDMETHOD(GetExecutingProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    // Query all the possible processor types that
-    // may be encountered during this debug session.
-    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetPossibleExecutingProcessorTypes)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Types
-        ) PURE;
-    // Get the number of actual processors in
-    // the machine.
-    STDMETHOD(GetNumberProcessors)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // PlatformId is one of the VER_PLATFORM values.
-    // Major and minor are as given in the NT
-    // kernel debugger protocol.
-    // ServicePackString and ServicePackNumber indicate the
-    // system service pack level.  ServicePackNumber is not
-    // available in some sessions where the service pack level
-    // is only expressed as a string.  The service pack information
-    // will be empty if the system does not have a service pack
-    // applied.
-    // The build string is string information identifying the
-    // particular build of the system.  The build string is
-    // empty if the system has no particular identifying
-    // information.
-    STDMETHOD(GetSystemVersion)(
-        THIS_
-        __out PULONG PlatformId,
-        __out PULONG Major,
-        __out PULONG Minor,
-        __out_ecount_opt(ServicePackStringSize) PSTR ServicePackString,
-        __in ULONG ServicePackStringSize,
-        __out_opt PULONG ServicePackStringUsed,
-        __out PULONG ServicePackNumber,
-        __out_ecount_opt(BuildStringSize) PSTR BuildString,
-        __in ULONG BuildStringSize,
-        __out_opt PULONG BuildStringUsed
-        ) PURE;
-    // Returns the page size for the currently executing
-    // processor context.  The page size may vary between
-    // processor types.
-    STDMETHOD(GetPageSize)(
-        THIS_
-        __out PULONG Size
-        ) PURE;
-    // Returns S_OK if the current processor context uses
-    // 64-bit addresses, otherwise S_FALSE.
-    STDMETHOD(IsPointer64Bit)(
-        THIS
-        ) PURE;
-    // Reads the bugcheck data area and returns the
-    // current contents.  This method only works
-    // in kernel debugging sessions.
-    STDMETHOD(ReadBugCheckData)(
-        THIS_
-        __out PULONG Code,
-        __out PULONG64 Arg1,
-        __out PULONG64 Arg2,
-        __out PULONG64 Arg3,
-        __out PULONG64 Arg4
-        ) PURE;
-
-    // Query all the processor types supported by
-    // the engine.  This is a complete list and is
-    // not related to the machine running the engine
-    // or the debuggee.
-    STDMETHOD(GetNumberSupportedProcessorTypes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetSupportedProcessorTypes)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Types
-        ) PURE;
-    // Returns a full, descriptive name and an
-    // abbreviated name for a processor type.
-    STDMETHOD(GetProcessorTypeNames)(
-        THIS_
-        __in ULONG Type,
-        __out_ecount_opt(FullNameBufferSize) PSTR FullNameBuffer,
-        __in ULONG FullNameBufferSize,
-        __out_opt PULONG FullNameSize,
-        __out_ecount_opt(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
-        __in ULONG AbbrevNameBufferSize,
-        __out_opt PULONG AbbrevNameSize
-        ) PURE;
-
-    // Gets and sets the type of processor to
-    // use when doing things like setting
-    // breakpoints, accessing registers,
-    // getting stack traces and so on.
-    STDMETHOD(GetEffectiveProcessorType)(
-        THIS_
-        __out PULONG Type
-        ) PURE;
-    STDMETHOD(SetEffectiveProcessorType)(
-        THIS_
-        __in ULONG Type
-        ) PURE;
-
-    // Returns information about whether and how
-    // the debuggee is running.  Status will
-    // be GO if the debuggee is running and
-    // BREAK if it isnt.
-    // If no debuggee exists the status is
-    // NO_DEBUGGEE.
-    // This method is reentrant.
-    STDMETHOD(GetExecutionStatus)(
-        THIS_
-        __out PULONG Status
-        ) PURE;
-    // Changes the execution status of the
-    // engine from stopped to running.
-    // Status must be one of the go or step
-    // status values.
-    STDMETHOD(SetExecutionStatus)(
-        THIS_
-        __in ULONG Status
-        ) PURE;
-
-    // Controls what code interpretation level the debugger
-    // runs at.  The debugger checks the code level when
-    // deciding whether to step by a source line or
-    // assembly instruction along with other related operations.
-    STDMETHOD(GetCodeLevel)(
-        THIS_
-        __out PULONG Level
-        ) PURE;
-    STDMETHOD(SetCodeLevel)(
-        THIS_
-        __in ULONG Level
-        ) PURE;
-
-    // Gets and sets engine control flags.
-    // These methods are reentrant.
-    STDMETHOD(GetEngineOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetEngineOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Gets and sets control values for
-    // handling system error events.
-    // If the system error level is less
-    // than or equal to the given levels
-    // the error may be displayed and
-    // the default break for the event
-    // may be set.
-    STDMETHOD(GetSystemErrorControl)(
-        THIS_
-        __out PULONG OutputLevel,
-        __out PULONG BreakLevel
-        ) PURE;
-    STDMETHOD(SetSystemErrorControl)(
-        THIS_
-        __in ULONG OutputLevel,
-        __in ULONG BreakLevel
-        ) PURE;
-
-    // The command processor supports simple
-    // string replacement macros in Evaluate and
-    // Execute.  There are currently ten macro
-    // slots available.  Slots 0-9 map to
-    // the command invocations $u0-$u9.
-    STDMETHOD(GetTextMacro)(
-        THIS_
-        __in ULONG Slot,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG MacroSize
-        ) PURE;
-    STDMETHOD(SetTextMacro)(
-        THIS_
-        __in ULONG Slot,
-        __in PCSTR Macro
-        ) PURE;
-
-    // Controls the default number radix used
-    // in expressions and commands.
-    STDMETHOD(GetRadix)(
-        THIS_
-        __out PULONG Radix
-        ) PURE;
-    STDMETHOD(SetRadix)(
-        THIS_
-        __in ULONG Radix
-        ) PURE;
-
-    // Evaluates the given expression string and
-    // returns the resulting value.
-    // If DesiredType is DEBUG_VALUE_INVALID then
-    // the natural type is used.
-    // RemainderIndex, if provided, is set to the index
-    // of the first character in the input string that was
-    // not used when evaluating the expression.
-    STDMETHOD(Evaluate)(
-        THIS_
-        __in PCSTR Expression,
-        __in ULONG DesiredType,
-        __out PDEBUG_VALUE Value,
-        __out_opt PULONG RemainderIndex
-        ) PURE;
-    // Attempts to convert the input value to a value
-    // of the requested type in the output value.
-    // Conversions can fail if no conversion exists.
-    // Successful conversions may be lossy.
-    STDMETHOD(CoerceValue)(
-        THIS_
-        __in PDEBUG_VALUE In,
-        __in ULONG OutType,
-        __out PDEBUG_VALUE Out
-        ) PURE;
-    STDMETHOD(CoerceValues)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_VALUE In,
-        __in_ecount(Count) PULONG OutTypes,
-        __out_ecount(Count) PDEBUG_VALUE Out
-        ) PURE;
-
-    // Executes the given command string.
-    // If the string has multiple commands
-    // Execute will not return until all
-    // of them have been executed.  If this
-    // requires waiting for the debuggee to
-    // execute an internal wait will be done
-    // so Execute can take an arbitrary amount
-    // of time.
-    STDMETHOD(Execute)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR Command,
-        __in ULONG Flags
-        ) PURE;
-    // Executes the given command file by
-    // reading a line at a time and processing
-    // it with Execute.
-    STDMETHOD(ExecuteCommandFile)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCSTR CommandFile,
-        __in ULONG Flags
-        ) PURE;
-
-    // Breakpoint interfaces are described
-    // elsewhere in this section.
-    STDMETHOD(GetNumberBreakpoints)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // It is possible for this retrieval function to
-    // fail even with an index within the number of
-    // existing breakpoints if the breakpoint is
-    // a private breakpoint.
-    STDMETHOD(GetBreakpointByIndex)(
-        THIS_
-        __in ULONG Index,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    STDMETHOD(GetBreakpointById)(
-        THIS_
-        __in ULONG Id,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    // If Ids is non-NULL the Count breakpoints
-    // referred to in the Ids array are returned,
-    // otherwise breakpoints from index Start to
-    // Start + Count  1 are returned.
-    STDMETHOD(GetBreakpointParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Ids,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
-        ) PURE;
-    // Breakpoints are created empty and disabled.
-    // When their parameters have been set they
-    // should be enabled by setting the ENABLE flag.
-    // If DesiredId is DEBUG_ANY_ID then the
-    // engine picks an unused ID.  If DesiredId
-    // is any other number the engine attempts
-    // to use the given ID for the breakpoint.
-    // If another breakpoint exists with that ID
-    // the call will fail.
-    STDMETHOD(AddBreakpoint)(
-        THIS_
-        __in ULONG Type,
-        __in ULONG DesiredId,
-        __out PDEBUG_BREAKPOINT* Bp
-        ) PURE;
-    // Breakpoint interface is invalid after this call.
-    STDMETHOD(RemoveBreakpoint)(
-        THIS_
-        __in PDEBUG_BREAKPOINT Bp
-        ) PURE;
-
-    // Control and use extension DLLs.
-    STDMETHOD(AddExtension)(
-        THIS_
-        __in PCSTR Path,
-        __in ULONG Flags,
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(RemoveExtension)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-    STDMETHOD(GetExtensionByPath)(
-        THIS_
-        __in PCSTR Path,
-        __out PULONG64 Handle
-        ) PURE;
-    // If Handle is zero the extension
-    // chain is walked searching for the
-    // function.
-    STDMETHOD(CallExtension)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCSTR Function,
-        __in_opt PCSTR Arguments
-        ) PURE;
-    // GetExtensionFunction works like
-    // GetProcAddress on extension DLLs
-    // to allow raw function-call-level
-    // interaction with extension DLLs.
-    // Such functions do not need to
-    // follow the standard extension prototype
-    // if they are not going to be called
-    // through the text extension interface.
-    // This function cannot be called remotely.
-    STDMETHOD(GetExtensionFunction)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCSTR FuncName,
-        __out FARPROC* Function
-        ) PURE;
-    // These methods return alternate
-    // extension interfaces in order to allow
-    // interface-style extension DLLs to mix in
-    // older extension calls.
-    // Structure sizes must be initialized before
-    // the call.
-    // These methods cannot be called remotely.
-    STDMETHOD(GetWindbgExtensionApis32)(
-        THIS_
-        __inout PWINDBG_EXTENSION_APIS32 Api
-        ) PURE;
-    STDMETHOD(GetWindbgExtensionApis64)(
-        THIS_
-        __inout PWINDBG_EXTENSION_APIS64 Api
-        ) PURE;
-
-    // The engine provides a simple mechanism
-    // to filter common events.  Arbitrarily complicated
-    // filtering can be done by registering event callbacks
-    // but simple event filtering only requires
-    // setting the options of one of the predefined
-    // event filters.
-    // Simple event filters are either for specific
-    // events and therefore have an enumerant or
-    // they are for an exception and are based on
-    // the exceptions code.  Exception filters
-    // are further divided into exceptions specially
-    // handled by the engine, which is a fixed set,
-    // and arbitrary exceptions.
-    // All three groups of filters are indexed together
-    // with the specific filters first, then the specific
-    // exception filters and finally the arbitrary
-    // exception filters.
-    // The first specific exception is the default
-    // exception.  If an exception event occurs for
-    // an exception without settings the default
-    // exception settings are used.
-    STDMETHOD(GetNumberEventFilters)(
-        THIS_
-        __out PULONG SpecificEvents,
-        __out PULONG SpecificExceptions,
-        __out PULONG ArbitraryExceptions
-        ) PURE;
-    // Some filters have descriptive text associated with them.
-    STDMETHOD(GetEventFilterText)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-    // All filters support executing a command when the
-    // event occurs.
-    STDMETHOD(GetEventFilterCommand)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetEventFilterCommand)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Command
-        ) PURE;
-    STDMETHOD(GetSpecificFilterParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
-        ) PURE;
-    STDMETHOD(SetSpecificFilterParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
-        ) PURE;
-    // Some specific filters have arguments to further
-    // qualify their operation.
-    STDMETHOD(GetSpecificFilterArgument)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ArgumentSize
-        ) PURE;
-    STDMETHOD(SetSpecificFilterArgument)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Argument
-        ) PURE;
-    // If Codes is non-NULL Start is ignored.
-    STDMETHOD(GetExceptionFilterParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Codes,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
-        ) PURE;
-    // The codes in the parameter data control the application
-    // of the parameter data.  If a code is not already in
-    // the set of filters it is added.  If the ExecutionOption
-    // for a code is REMOVE then the filter is removed.
-    // Specific exception filters cannot be removed.
-    STDMETHOD(SetExceptionFilterParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
-        ) PURE;
-    // Exception filters support an additional command for
-    // second-chance events.
-    STDMETHOD(GetExceptionFilterSecondCommand)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetExceptionFilterSecondCommand)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Command
-        ) PURE;
-
-    // Yields processing to the engine until
-    // an event occurs.  This method may
-    // only be called by the thread that started
-    // the debug session.
-    // When an event occurs the engine carries
-    // out all event processing such as calling
-    // callbacks.
-    // If the callbacks indicate that execution should
-    // break the wait will return, otherwise it
-    // goes back to waiting for a new event.
-    // If the timeout expires, S_FALSE is returned.
-    // The timeout is not currently supported for
-    // kernel debugging.
-    STDMETHOD(WaitForEvent)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG Timeout
-        ) PURE;
-
-    // Retrieves information about the last event that occurred.
-    // EventType is one of the event callback mask bits.
-    // ExtraInformation contains additional event-specific
-    // information.  Not all events have additional information.
-    STDMETHOD(GetLastEventInformation)(
-        THIS_
-        __out PULONG Type,
-        __out PULONG ProcessId,
-        __out PULONG ThreadId,
-        __out_bcount_opt(ExtraInformationSize) PVOID ExtraInformation,
-        __in ULONG ExtraInformationSize,
-        __out_opt PULONG ExtraInformationUsed,
-        __out_ecount_opt(DescriptionSize) PSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG DescriptionUsed
-        ) PURE;
-
-    // IDebugControl2.
-
-    STDMETHOD(GetCurrentTimeDate)(
-        THIS_
-        __out PULONG TimeDate
-        ) PURE;
-    // Retrieves the number of seconds since the
-    // machine started running.
-    STDMETHOD(GetCurrentSystemUpTime)(
-        THIS_
-        __out PULONG UpTime
-        ) PURE;
-
-    // If the current session is a dump session,
-    // retrieves any extended format information.
-    STDMETHOD(GetDumpFormatFlags)(
-        THIS_
-        __out PULONG FormatFlags
-        ) PURE;
-
-    // The debugger has been enhanced to allow
-    // arbitrary text replacements in addition
-    // to the simple $u0-$u9 text macros.
-    // Text replacement takes a given source
-    // text in commands and converts it to the
-    // given destination text.  Replacements
-    // are named by their source text so that
-    // only one replacement for a source text
-    // string can exist.
-    STDMETHOD(GetNumberTextReplacements)(
-        THIS_
-        __out PULONG NumRepl
-        ) PURE;
-    // If SrcText is non-NULL the replacement
-    // is looked up by source text, otherwise
-    // Index is used to get the Nth replacement.
-    STDMETHOD(GetTextReplacement)(
-        THIS_
-        __in_opt PCSTR SrcText,
-        __in ULONG Index,
-        __out_ecount_opt(SrcBufferSize) PSTR SrcBuffer,
-        __in ULONG SrcBufferSize,
-        __out_opt PULONG SrcSize,
-        __out_ecount_opt(DstBufferSize) PSTR DstBuffer,
-        __in ULONG DstBufferSize,
-        __out_opt PULONG DstSize
-        ) PURE;
-    // Setting the destination text to
-    // NULL removes the alias.
-    STDMETHOD(SetTextReplacement)(
-        THIS_
-        __in PCSTR SrcText,
-        __in_opt PCSTR DstText
-        ) PURE;
-    STDMETHOD(RemoveTextReplacements)(
-        THIS
-        ) PURE;
-    // Outputs the complete list of current
-    // replacements.
-    STDMETHOD(OutputTextReplacements)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags
-        ) PURE;
-
-    // IDebugControl3.
-
-    // Control options for assembly and disassembly.
-    STDMETHOD(GetAssemblyOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddAssemblyOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveAssemblyOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetAssemblyOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // Control the expression syntax.
-    STDMETHOD(GetExpressionSyntax)(
-        THIS_
-        __out PULONG Flags
-        ) PURE;
-    STDMETHOD(SetExpressionSyntax)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-    // Look up a syntax by its abbreviated
-    // name and set it.
-    STDMETHOD(SetExpressionSyntaxByName)(
-        THIS_
-        __in PCSTR AbbrevName
-        ) PURE;
-    STDMETHOD(GetNumberExpressionSyntaxes)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetExpressionSyntaxNames)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(FullNameBufferSize) PSTR FullNameBuffer,
-        __in ULONG FullNameBufferSize,
-        __out_opt PULONG FullNameSize,
-        __out_ecount_opt(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
-        __in ULONG AbbrevNameBufferSize,
-        __out_opt PULONG AbbrevNameSize
-        ) PURE;
-
-    //
-    // Some debug sessions have only a single
-    // possible event, such as a snapshot dump
-    // file; some have dynamic events, such as
-    // a live debug session; and others may have
-    // multiple events, such as a dump file that
-    // contains snapshots from different points
-    // in time.  The following methods allow
-    // discovery and selection of the available
-    // events for a session.
-    // Sessions with one or more static events
-    // will be able to report all of the events
-    // when queried.  Sessions with dynamic events
-    // will only report a single event representing
-    // the current event.
-    // Switching events constitutes execution and
-    // changing the current event will alter the
-    // execution status to a running state, after
-    // which WaitForEvent must be used to process
-    // the selected event.
-    //
-
-    // GetNumberEvents returns S_OK if this is the
-    // complete set of events possible, such as for
-    // a static session; or S_FALSE if other events
-    // may be possible, such as for a dynamic session.
-    STDMETHOD(GetNumberEvents)(
-        THIS_
-        __out PULONG Events
-        ) PURE;
-    // Sessions may have descriptive information for
-    // the various events available.  The amount of
-    // information varies according to the specific
-    // session and data.
-    STDMETHOD(GetEventIndexDescription)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG Which,
-        __in_opt PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DescSize
-        ) PURE;
-    STDMETHOD(GetCurrentEventIndex)(
-        THIS_
-        __out PULONG Index
-        ) PURE;
-    // SetNextEventIndex works like seek in that
-    // it can set an absolute or relative index.
-    // SetNextEventIndex works similarly to SetExecutionStatus
-    // by putting the session into a running state, after
-    // which the caller must call WaitForEvent.  The
-    // current event index only changes when WaitForEvent
-    // is called.
-    STDMETHOD(SetNextEventIndex)(
-        THIS_
-        __in ULONG Relation,
-        __in ULONG Value,
-        __out PULONG NextIndex
-        ) PURE;
-
-    // IDebugControl4.
-
-    STDMETHOD(GetLogFileWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FileSize,
-        __out PBOOL Append
-        ) PURE;
-    STDMETHOD(OpenLogFileWide)(
-        THIS_
-        __in PCWSTR File,
-        __in BOOL Append
-        ) PURE;
-
-    STDMETHOD(InputWide)(
-        THIS_
-        __out_ecount(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InputSize
-        ) PURE;
-    STDMETHOD(ReturnInputWide)(
-        THIS_
-        __in PCWSTR Buffer
-        ) PURE;
-
-    STDMETHODV(OutputWide)(
-        THIS_
-        __in ULONG Mask,
-        __in PCWSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputVaListWide)(
-        THIS_
-        __in ULONG Mask,
-        __in PCWSTR Format,
-        __in va_list Args
-        ) PURE;
-    STDMETHODV(ControlledOutputWide)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCWSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(ControlledOutputVaListWide)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Mask,
-        __in PCWSTR Format,
-        __in va_list Args
-        ) PURE;
-
-    STDMETHODV(OutputPromptWide)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCWSTR Format,
-        ...
-        ) PURE;
-    STDMETHOD(OutputPromptVaListWide)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_opt PCWSTR Format,
-        __in va_list Args
-        ) PURE;
-    STDMETHOD(GetPromptTextWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-
-    STDMETHOD(AssembleWide)(
-        THIS_
-        __in ULONG64 Offset,
-        __in PCWSTR Instr,
-        __out PULONG64 EndOffset
-        ) PURE;
-    STDMETHOD(DisassembleWide)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DisassemblySize,
-        __out PULONG64 EndOffset
-        ) PURE;
-
-    STDMETHOD(GetProcessorTypeNamesWide)(
-        THIS_
-        __in ULONG Type,
-        __out_ecount_opt(FullNameBufferSize) PWSTR FullNameBuffer,
-        __in ULONG FullNameBufferSize,
-        __out_opt PULONG FullNameSize,
-        __out_ecount_opt(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
-        __in ULONG AbbrevNameBufferSize,
-        __out_opt PULONG AbbrevNameSize
-        ) PURE;
-
-    STDMETHOD(GetTextMacroWide)(
-        THIS_
-        __in ULONG Slot,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG MacroSize
-        ) PURE;
-    STDMETHOD(SetTextMacroWide)(
-        THIS_
-        __in ULONG Slot,
-        __in PCWSTR Macro
-        ) PURE;
-
-    STDMETHOD(EvaluateWide)(
-        THIS_
-        __in PCWSTR Expression,
-        __in ULONG DesiredType,
-        __out PDEBUG_VALUE Value,
-        __out_opt PULONG RemainderIndex
-        ) PURE;
-
-    STDMETHOD(ExecuteWide)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCWSTR Command,
-        __in ULONG Flags
-        ) PURE;
-    STDMETHOD(ExecuteCommandFileWide)(
-        THIS_
-        __in ULONG OutputControl,
-        __in PCWSTR CommandFile,
-        __in ULONG Flags
-        ) PURE;
-
-    STDMETHOD(GetBreakpointByIndex2)(
-        THIS_
-        __in ULONG Index,
-        __out PDEBUG_BREAKPOINT2* Bp
-        ) PURE;
-    STDMETHOD(GetBreakpointById2)(
-        THIS_
-        __in ULONG Id,
-        __out PDEBUG_BREAKPOINT2* Bp
-        ) PURE;
-    STDMETHOD(AddBreakpoint2)(
-        THIS_
-        __in ULONG Type,
-        __in ULONG DesiredId,
-        __out PDEBUG_BREAKPOINT2* Bp
-        ) PURE;
-    STDMETHOD(RemoveBreakpoint2)(
-        THIS_
-        __in PDEBUG_BREAKPOINT2 Bp
-        ) PURE;
-
-    STDMETHOD(AddExtensionWide)(
-        THIS_
-        __in PCWSTR Path,
-        __in ULONG Flags,
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(GetExtensionByPathWide)(
-        THIS_
-        __in PCWSTR Path,
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(CallExtensionWide)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCWSTR Function,
-        __in_opt PCWSTR Arguments
-        ) PURE;
-    STDMETHOD(GetExtensionFunctionWide)(
-        THIS_
-        __in ULONG64 Handle,
-        __in PCWSTR FuncName,
-        __out FARPROC* Function
-        ) PURE;
-
-    STDMETHOD(GetEventFilterTextWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TextSize
-        ) PURE;
-    STDMETHOD(GetEventFilterCommandWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetEventFilterCommandWide)(
-        THIS_
-        __in ULONG Index,
-        __in PCWSTR Command
-        ) PURE;
-    STDMETHOD(GetSpecificFilterArgumentWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ArgumentSize
-        ) PURE;
-    STDMETHOD(SetSpecificFilterArgumentWide)(
-        THIS_
-        __in ULONG Index,
-        __in PCWSTR Argument
-        ) PURE;
-    STDMETHOD(GetExceptionFilterSecondCommandWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG CommandSize
-        ) PURE;
-    STDMETHOD(SetExceptionFilterSecondCommandWide)(
-        THIS_
-        __in ULONG Index,
-        __in PCWSTR Command
-        ) PURE;
-
-    STDMETHOD(GetLastEventInformationWide)(
-        THIS_
-        __out PULONG Type,
-        __out PULONG ProcessId,
-        __out PULONG ThreadId,
-        __out_bcount_opt(ExtraInformationSize) PVOID ExtraInformation,
-        __in ULONG ExtraInformationSize,
-        __out_opt PULONG ExtraInformationUsed,
-        __out_ecount_opt(DescriptionSize) PWSTR Description,
-        __in ULONG DescriptionSize,
-        __out_opt PULONG DescriptionUsed
-        ) PURE;
-
-    STDMETHOD(GetTextReplacementWide)(
-        THIS_
-        __in_opt PCWSTR SrcText,
-        __in ULONG Index,
-        __out_ecount_opt(SrcBufferSize) PWSTR SrcBuffer,
-        __in ULONG SrcBufferSize,
-        __out_opt PULONG SrcSize,
-        __out_ecount_opt(DstBufferSize) PWSTR DstBuffer,
-        __in ULONG DstBufferSize,
-        __out_opt PULONG DstSize
-        ) PURE;
-    STDMETHOD(SetTextReplacementWide)(
-        THIS_
-        __in PCWSTR SrcText,
-        __in_opt PCWSTR DstText
-        ) PURE;
-
-    STDMETHOD(SetExpressionSyntaxByNameWide)(
-        THIS_
-        __in PCWSTR AbbrevName
-        ) PURE;
-    STDMETHOD(GetExpressionSyntaxNamesWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(FullNameBufferSize) PWSTR FullNameBuffer,
-        __in ULONG FullNameBufferSize,
-        __out_opt PULONG FullNameSize,
-        __out_ecount_opt(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
-        __in ULONG AbbrevNameBufferSize,
-        __out_opt PULONG AbbrevNameSize
-        ) PURE;
-
-    STDMETHOD(GetEventIndexDescriptionWide)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG Which,
-        __in_opt PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DescSize
-        ) PURE;
-
-    STDMETHOD(GetLogFile2)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FileSize,
-        __out PULONG Flags
-        ) PURE;
-    STDMETHOD(OpenLogFile2)(
-        THIS_
-        __in PCSTR File,
-        __in ULONG Flags
-        ) PURE;
-    STDMETHOD(GetLogFile2Wide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FileSize,
-        __out PULONG Flags
-        ) PURE;
-    STDMETHOD(OpenLogFile2Wide)(
-        THIS_
-        __in PCWSTR File,
-        __in ULONG Flags
-        ) PURE;
-
-    // GetSystemVersion always returns the kd
-    // major/minor version numbers, which are
-    // different than the Win32 version numbers.
-    // GetSystemVersionValues can be used
-    // to determine the Win32 version values.
-    STDMETHOD(GetSystemVersionValues)(
-        THIS_
-        __out PULONG PlatformId,
-        __out PULONG Win32Major,
-        __out PULONG Win32Minor,
-        __out_opt PULONG KdMajor,
-        __out_opt PULONG KdMinor
-        ) PURE;
-    // Strings are selected with DEBUG_SYSVERSTR_*.
-    STDMETHOD(GetSystemVersionString)(
-        THIS_
-        __in ULONG Which,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-    STDMETHOD(GetSystemVersionStringWide)(
-        THIS_
-        __in ULONG Which,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-
-    // Stack tracing with a full initial context
-    // and full context return for each frame.
-    // The FrameContextsSize parameter is the total
-    // byte size of FrameContexts.  FrameContextsEntrySize
-    // gives the byte size of each entry in
-    // FrameContexts.
-    STDMETHOD(GetContextStackTrace)(
-        THIS_
-        __in_bcount_opt(StartContextSize) PVOID StartContext,
-        __in ULONG StartContextSize,
-        __out_ecount_opt(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __out_bcount_opt(FrameContextsSize) PVOID FrameContexts,
-        __in ULONG FrameContextsSize,
-        __in ULONG FrameContextsEntrySize,
-        __out_opt PULONG FramesFilled
-        ) PURE;
-    STDMETHOD(OutputContextStackTrace)(
-        THIS_
-        __in ULONG OutputControl,
-        __in_ecount(FramesSize) PDEBUG_STACK_FRAME Frames,
-        __in ULONG FramesSize,
-        __in_bcount(FrameContextsSize) PVOID FrameContexts,
-        __in ULONG FrameContextsSize,
-        __in ULONG FrameContextsEntrySize,
-        __in ULONG Flags
-        ) PURE;
-
-    // Some targets, such as user-mode minidump files,
-    // have separate "event of interest" information
-    // stored within them.  This method allows
-    // access to that information.
-    STDMETHOD(GetStoredEventInformation)(
-        THIS_
-        __out PULONG Type,
-        __out PULONG ProcessId,
-        __out PULONG ThreadId,
-        __out_bcount_opt(ContextSize) PVOID Context,
-        __in ULONG ContextSize,
-        __out_opt PULONG ContextUsed,
-        __out_bcount_opt(ExtraInformationSize) PVOID ExtraInformation,
-        __in ULONG ExtraInformationSize,
-        __out_opt PULONG ExtraInformationUsed
-        ) PURE;
-
-    // Managed debugging support relies on debugging
-    // functionality provided by the Common Language Runtime.
-    // This method provides feedback on the engine's
-    // use of the runtime debugging APIs.
-    STDMETHOD(GetManagedStatus)(
-        THIS_
-        __out_opt PULONG Flags,
-        __in ULONG WhichString,
-        __out_ecount_opt(StringSize) PSTR String,
-        __in ULONG StringSize,
-        __out_opt PULONG StringNeeded
-        ) PURE;
-    STDMETHOD(GetManagedStatusWide)(
-        THIS_
-        __out_opt PULONG Flags,
-        __in ULONG WhichString,
-        __out_ecount_opt(StringSize) PWSTR String,
-        __in ULONG StringSize,
-        __out_opt PULONG StringNeeded
-        ) PURE;
-    // Clears and reinitializes the engine's
-    // managed code debugging support.
-    STDMETHOD(ResetManagedStatus)(
-        THIS_
-        __in ULONG Flags
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugDataSpaces.
-//
-//----------------------------------------------------------------------------
-
-// Data space indices for callbacks and other methods.
-#define DEBUG_DATA_SPACE_VIRTUAL       0
-#define DEBUG_DATA_SPACE_PHYSICAL      1
-#define DEBUG_DATA_SPACE_CONTROL       2
-#define DEBUG_DATA_SPACE_IO            3
-#define DEBUG_DATA_SPACE_MSR           4
-#define DEBUG_DATA_SPACE_BUS_DATA      5
-#define DEBUG_DATA_SPACE_DEBUGGER_DATA 6
-// Count of data spaces.
-#define DEBUG_DATA_SPACE_COUNT         7
-
-// Indices for ReadDebuggerData interface
-#define DEBUG_DATA_KernBase                              24
-#define DEBUG_DATA_BreakpointWithStatusAddr              32
-#define DEBUG_DATA_SavedContextAddr                      40
-#define DEBUG_DATA_KiCallUserModeAddr                    56
-#define DEBUG_DATA_KeUserCallbackDispatcherAddr          64
-#define DEBUG_DATA_PsLoadedModuleListAddr                72
-#define DEBUG_DATA_PsActiveProcessHeadAddr               80
-#define DEBUG_DATA_PspCidTableAddr                       88
-#define DEBUG_DATA_ExpSystemResourcesListAddr            96
-#define DEBUG_DATA_ExpPagedPoolDescriptorAddr           104
-#define DEBUG_DATA_ExpNumberOfPagedPoolsAddr            112
-#define DEBUG_DATA_KeTimeIncrementAddr                  120
-#define DEBUG_DATA_KeBugCheckCallbackListHeadAddr       128
-#define DEBUG_DATA_KiBugcheckDataAddr                   136
-#define DEBUG_DATA_IopErrorLogListHeadAddr              144
-#define DEBUG_DATA_ObpRootDirectoryObjectAddr           152
-#define DEBUG_DATA_ObpTypeObjectTypeAddr                160
-#define DEBUG_DATA_MmSystemCacheStartAddr               168
-#define DEBUG_DATA_MmSystemCacheEndAddr                 176
-#define DEBUG_DATA_MmSystemCacheWsAddr                  184
-#define DEBUG_DATA_MmPfnDatabaseAddr                    192
-#define DEBUG_DATA_MmSystemPtesStartAddr                200
-#define DEBUG_DATA_MmSystemPtesEndAddr                  208
-#define DEBUG_DATA_MmSubsectionBaseAddr                 216
-#define DEBUG_DATA_MmNumberOfPagingFilesAddr            224
-#define DEBUG_DATA_MmLowestPhysicalPageAddr             232
-#define DEBUG_DATA_MmHighestPhysicalPageAddr            240
-#define DEBUG_DATA_MmNumberOfPhysicalPagesAddr          248
-#define DEBUG_DATA_MmMaximumNonPagedPoolInBytesAddr     256
-#define DEBUG_DATA_MmNonPagedSystemStartAddr            264
-#define DEBUG_DATA_MmNonPagedPoolStartAddr              272
-#define DEBUG_DATA_MmNonPagedPoolEndAddr                280
-#define DEBUG_DATA_MmPagedPoolStartAddr                 288
-#define DEBUG_DATA_MmPagedPoolEndAddr                   296
-#define DEBUG_DATA_MmPagedPoolInformationAddr           304
-#define DEBUG_DATA_MmPageSize                           312
-#define DEBUG_DATA_MmSizeOfPagedPoolInBytesAddr         320
-#define DEBUG_DATA_MmTotalCommitLimitAddr               328
-#define DEBUG_DATA_MmTotalCommittedPagesAddr            336
-#define DEBUG_DATA_MmSharedCommitAddr                   344
-#define DEBUG_DATA_MmDriverCommitAddr                   352
-#define DEBUG_DATA_MmProcessCommitAddr                  360
-#define DEBUG_DATA_MmPagedPoolCommitAddr                368
-#define DEBUG_DATA_MmExtendedCommitAddr                 376
-#define DEBUG_DATA_MmZeroedPageListHeadAddr             384
-#define DEBUG_DATA_MmFreePageListHeadAddr               392
-#define DEBUG_DATA_MmStandbyPageListHeadAddr            400
-#define DEBUG_DATA_MmModifiedPageListHeadAddr           408
-#define DEBUG_DATA_MmModifiedNoWritePageListHeadAddr    416
-#define DEBUG_DATA_MmAvailablePagesAddr                 424
-#define DEBUG_DATA_MmResidentAvailablePagesAddr         432
-#define DEBUG_DATA_PoolTrackTableAddr                   440
-#define DEBUG_DATA_NonPagedPoolDescriptorAddr           448
-#define DEBUG_DATA_MmHighestUserAddressAddr             456
-#define DEBUG_DATA_MmSystemRangeStartAddr               464
-#define DEBUG_DATA_MmUserProbeAddressAddr               472
-#define DEBUG_DATA_KdPrintCircularBufferAddr            480
-#define DEBUG_DATA_KdPrintCircularBufferEndAddr         488
-#define DEBUG_DATA_KdPrintWritePointerAddr              496
-#define DEBUG_DATA_KdPrintRolloverCountAddr             504
-#define DEBUG_DATA_MmLoadedUserImageListAddr            512
-#define DEBUG_DATA_NtBuildLabAddr                       520
-#define DEBUG_DATA_KiNormalSystemCall                   528
-#define DEBUG_DATA_KiProcessorBlockAddr                 536
-#define DEBUG_DATA_MmUnloadedDriversAddr                544
-#define DEBUG_DATA_MmLastUnloadedDriverAddr             552
-#define DEBUG_DATA_MmTriageActionTakenAddr              560
-#define DEBUG_DATA_MmSpecialPoolTagAddr                 568
-#define DEBUG_DATA_KernelVerifierAddr                   576
-#define DEBUG_DATA_MmVerifierDataAddr                   584
-#define DEBUG_DATA_MmAllocatedNonPagedPoolAddr          592
-#define DEBUG_DATA_MmPeakCommitmentAddr                 600
-#define DEBUG_DATA_MmTotalCommitLimitMaximumAddr        608
-#define DEBUG_DATA_CmNtCSDVersionAddr                   616
-#define DEBUG_DATA_MmPhysicalMemoryBlockAddr            624
-#define DEBUG_DATA_MmSessionBase                        632
-#define DEBUG_DATA_MmSessionSize                        640
-#define DEBUG_DATA_MmSystemParentTablePage              648
-#define DEBUG_DATA_MmVirtualTranslationBase             656
-#define DEBUG_DATA_OffsetKThreadNextProcessor           664
-#define DEBUG_DATA_OffsetKThreadTeb                     666
-#define DEBUG_DATA_OffsetKThreadKernelStack             668
-#define DEBUG_DATA_OffsetKThreadInitialStack            670
-#define DEBUG_DATA_OffsetKThreadApcProcess              672
-#define DEBUG_DATA_OffsetKThreadState                   674
-#define DEBUG_DATA_OffsetKThreadBStore                  676
-#define DEBUG_DATA_OffsetKThreadBStoreLimit             678
-#define DEBUG_DATA_SizeEProcess                         680
-#define DEBUG_DATA_OffsetEprocessPeb                    682
-#define DEBUG_DATA_OffsetEprocessParentCID              684
-#define DEBUG_DATA_OffsetEprocessDirectoryTableBase     686
-#define DEBUG_DATA_SizePrcb                             688
-#define DEBUG_DATA_OffsetPrcbDpcRoutine                 690
-#define DEBUG_DATA_OffsetPrcbCurrentThread              692
-#define DEBUG_DATA_OffsetPrcbMhz                        694
-#define DEBUG_DATA_OffsetPrcbCpuType                    696
-#define DEBUG_DATA_OffsetPrcbVendorString               698
-#define DEBUG_DATA_OffsetPrcbProcessorState             700
-#define DEBUG_DATA_OffsetPrcbNumber                     702
-#define DEBUG_DATA_SizeEThread                          704
-#define DEBUG_DATA_KdPrintCircularBufferPtrAddr         712
-#define DEBUG_DATA_KdPrintBufferSizeAddr             720
-#define DEBUG_DATA_MmBadPagesDetected             800
-
-#define DEBUG_DATA_PaeEnabled                        100000
-#define DEBUG_DATA_SharedUserData                    100008
-#define DEBUG_DATA_ProductType                       100016
-#define DEBUG_DATA_SuiteMask                         100024
-#define DEBUG_DATA_DumpWriterStatus                  100032
-#define DEBUG_DATA_DumpFormatVersion                 100040
-#define DEBUG_DATA_DumpWriterVersion                 100048
-#define DEBUG_DATA_DumpPowerState                    100056
-#define DEBUG_DATA_DumpMmStorage                     100064
-
-//
-// Processor information structures.
-//
-
-typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_ALPHA
-{
-    ULONG Type;
-    ULONG Revision;
-} DEBUG_PROCESSOR_IDENTIFICATION_ALPHA, *PDEBUG_PROCESSOR_IDENTIFICATION_ALPHA;
-
-typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_AMD64
-{
-    ULONG Family;
-    ULONG Model;
-    ULONG Stepping;
-    CHAR  VendorString[16];
-} DEBUG_PROCESSOR_IDENTIFICATION_AMD64, *PDEBUG_PROCESSOR_IDENTIFICATION_AMD64;
-
-typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_IA64
-{
-    ULONG Model;
-    ULONG Revision;
-    ULONG Family;
-    ULONG ArchRev;
-    CHAR  VendorString[16];
-} DEBUG_PROCESSOR_IDENTIFICATION_IA64, *PDEBUG_PROCESSOR_IDENTIFICATION_IA64;
-
-typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_X86
-{
-    ULONG Family;
-    ULONG Model;
-    ULONG Stepping;
-    CHAR  VendorString[16];
-} DEBUG_PROCESSOR_IDENTIFICATION_X86, *PDEBUG_PROCESSOR_IDENTIFICATION_X86;
-
-typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_ARM
-{
-    ULONG Type;
-    ULONG Revision;
-} DEBUG_PROCESSOR_IDENTIFICATION_ARM, *PDEBUG_PROCESSOR_IDENTIFICATION_ARM;
-
-typedef union _DEBUG_PROCESSOR_IDENTIFICATION_ALL
-{
-    DEBUG_PROCESSOR_IDENTIFICATION_ALPHA Alpha;
-    DEBUG_PROCESSOR_IDENTIFICATION_AMD64 Amd64;
-    DEBUG_PROCESSOR_IDENTIFICATION_IA64  Ia64;
-    DEBUG_PROCESSOR_IDENTIFICATION_X86   X86;
-    DEBUG_PROCESSOR_IDENTIFICATION_ARM   Arm;
-} DEBUG_PROCESSOR_IDENTIFICATION_ALL, *PDEBUG_PROCESSOR_IDENTIFICATION_ALL;
-
-// Indices for ReadProcessorSystemData.
-#define DEBUG_DATA_KPCR_OFFSET                          0
-#define DEBUG_DATA_KPRCB_OFFSET                         1
-#define DEBUG_DATA_KTHREAD_OFFSET                       2
-#define DEBUG_DATA_BASE_TRANSLATION_VIRTUAL_OFFSET      3
-#define DEBUG_DATA_PROCESSOR_IDENTIFICATION             4
-#define DEBUG_DATA_PROCESSOR_SPEED                      5
-
-#undef INTERFACE
-#define INTERFACE IDebugDataSpaces
-DECLARE_INTERFACE_(IDebugDataSpaces, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugDataSpaces.
-    STDMETHOD(ReadVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    // SearchVirtual searches the given virtual
-    // address range for the given pattern.  PatternSize
-    // gives the byte length of the pattern and PatternGranularity
-    // controls the granularity of comparisons during
-    // the search.
-    // For example, a DWORD-granular search would
-    // use a pattern granularity of four to search by DWORD
-    // increments.
-    STDMETHOD(SearchVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Length,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __in ULONG PatternGranularity,
-        __out PULONG64 MatchOffset
-        ) PURE;
-    // These methods are identical to Read/WriteVirtual
-    // except that they avoid the kernel virtual memory
-    // cache entirely and are therefore useful for reading
-    // virtual memory which is inherently volatile, such
-    // as memory-mapped device areas, without contaminating
-    // or invalidating the cache.
-    // In user-mode they are the same as Read/WriteVirtual.
-    STDMETHOD(ReadVirtualUncached)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteVirtualUncached)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    // The following two methods are convenience
-    // methods for accessing pointer values.
-    // They automatically convert between native pointers
-    // and canonical 64-bit values as necessary.
-    // These routines stop at the first failure.
-    STDMETHOD(ReadPointersVirtual)(
-        THIS_
-        __in ULONG Count,
-        __in ULONG64 Offset,
-        __out_ecount(Count) PULONG64 Ptrs
-        ) PURE;
-    STDMETHOD(WritePointersVirtual)(
-        THIS_
-        __in ULONG Count,
-        __in ULONG64 Offset,
-        __in_ecount(Count) PULONG64 Ptrs
-        ) PURE;
-    // All non-virtual data spaces are only
-    // available when kernel debugging.
-    STDMETHOD(ReadPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WritePhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadControl)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteControl)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadIo)(
-        THIS_
-        __in ULONG InterfaceType,
-        __in ULONG BusNumber,
-        __in ULONG AddressSpace,
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteIo)(
-        THIS_
-        __in ULONG InterfaceType,
-        __in ULONG BusNumber,
-        __in ULONG AddressSpace,
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadMsr)(
-        THIS_
-        __in ULONG Msr,
-        __out PULONG64 Value
-        ) PURE;
-    STDMETHOD(WriteMsr)(
-        THIS_
-        __in ULONG Msr,
-        __in ULONG64 Value
-        ) PURE;
-    STDMETHOD(ReadBusData)(
-        THIS_
-        __in ULONG BusDataType,
-        __in ULONG BusNumber,
-        __in ULONG SlotNumber,
-        __in ULONG Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteBusData)(
-        THIS_
-        __in ULONG BusDataType,
-        __in ULONG BusNumber,
-        __in ULONG SlotNumber,
-        __in ULONG Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(CheckLowMemory)(
-        THIS
-        ) PURE;
-    STDMETHOD(ReadDebuggerData)(
-        THIS_
-        __in ULONG Index,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-    STDMETHOD(ReadProcessorSystemData)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG Index,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-};
-
-//
-// Handle data types and structures.
-//
-
-#define DEBUG_HANDLE_DATA_TYPE_BASIC                 0
-#define DEBUG_HANDLE_DATA_TYPE_TYPE_NAME             1
-#define DEBUG_HANDLE_DATA_TYPE_OBJECT_NAME           2
-#define DEBUG_HANDLE_DATA_TYPE_HANDLE_COUNT          3
-#define DEBUG_HANDLE_DATA_TYPE_TYPE_NAME_WIDE        4
-#define DEBUG_HANDLE_DATA_TYPE_OBJECT_NAME_WIDE      5
-#define DEBUG_HANDLE_DATA_TYPE_MINI_THREAD_1         6
-#define DEBUG_HANDLE_DATA_TYPE_MINI_MUTANT_1         7
-#define DEBUG_HANDLE_DATA_TYPE_MINI_MUTANT_2         8
-#define DEBUG_HANDLE_DATA_TYPE_PER_HANDLE_OPERATIONS 9
-#define DEBUG_HANDLE_DATA_TYPE_ALL_HANDLE_OPERATIONS 10
-#define DEBUG_HANDLE_DATA_TYPE_MINI_PROCESS_1        11
-#define DEBUG_HANDLE_DATA_TYPE_MINI_PROCESS_2        12
-
-typedef struct _DEBUG_HANDLE_DATA_BASIC
-{
-    ULONG TypeNameSize;
-    ULONG ObjectNameSize;
-    ULONG Attributes;
-    ULONG GrantedAccess;
-    ULONG HandleCount;
-    ULONG PointerCount;
-} DEBUG_HANDLE_DATA_BASIC, *PDEBUG_HANDLE_DATA_BASIC;
-
-#undef INTERFACE
-#define INTERFACE IDebugDataSpaces2
-DECLARE_INTERFACE_(IDebugDataSpaces2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugDataSpaces.
-    STDMETHOD(ReadVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    // SearchVirtual searches the given virtual
-    // address range for the given pattern.  PatternSize
-    // gives the byte length of the pattern and PatternGranularity
-    // controls the granularity of comparisons during
-    // the search.
-    // For example, a DWORD-granular search would
-    // use a pattern granularity of four to search by DWORD
-    // increments.
-    STDMETHOD(SearchVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Length,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __in ULONG PatternGranularity,
-        __out PULONG64 MatchOffset
-        ) PURE;
-    // These methods are identical to Read/WriteVirtual
-    // except that they avoid the kernel virtual memory
-    // cache entirely and are therefore useful for reading
-    // virtual memory which is inherently volatile, such
-    // as memory-mapped device areas, without contaminating
-    // or invalidating the cache.
-    // In user-mode they are the same as Read/WriteVirtual.
-    STDMETHOD(ReadVirtualUncached)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteVirtualUncached)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    // The following two methods are convenience
-    // methods for accessing pointer values.
-    // They automatically convert between native pointers
-    // and canonical 64-bit values as necessary.
-    // These routines stop at the first failure.
-    STDMETHOD(ReadPointersVirtual)(
-        THIS_
-        __in ULONG Count,
-        __in ULONG64 Offset,
-        __out_ecount(Count) PULONG64 Ptrs
-        ) PURE;
-    STDMETHOD(WritePointersVirtual)(
-        THIS_
-        __in ULONG Count,
-        __in ULONG64 Offset,
-        __in_ecount(Count) PULONG64 Ptrs
-        ) PURE;
-    // All non-virtual data spaces are only
-    // available when kernel debugging.
-    STDMETHOD(ReadPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WritePhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadControl)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteControl)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadIo)(
-        THIS_
-        __in ULONG InterfaceType,
-        __in ULONG BusNumber,
-        __in ULONG AddressSpace,
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteIo)(
-        THIS_
-        __in ULONG InterfaceType,
-        __in ULONG BusNumber,
-        __in ULONG AddressSpace,
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadMsr)(
-        THIS_
-        __in ULONG Msr,
-        __out PULONG64 Value
-        ) PURE;
-    STDMETHOD(WriteMsr)(
-        THIS_
-        __in ULONG Msr,
-        __in ULONG64 Value
-        ) PURE;
-    STDMETHOD(ReadBusData)(
-        THIS_
-        __in ULONG BusDataType,
-        __in ULONG BusNumber,
-        __in ULONG SlotNumber,
-        __in ULONG Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteBusData)(
-        THIS_
-        __in ULONG BusDataType,
-        __in ULONG BusNumber,
-        __in ULONG SlotNumber,
-        __in ULONG Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(CheckLowMemory)(
-        THIS
-        ) PURE;
-    STDMETHOD(ReadDebuggerData)(
-        THIS_
-        __in ULONG Index,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-    STDMETHOD(ReadProcessorSystemData)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG Index,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-
-    // IDebugDataSpaces2.
-
-    STDMETHOD(VirtualToPhysical)(
-        THIS_
-        __in ULONG64 Virtual,
-        __out PULONG64 Physical
-        ) PURE;
-    // Returns the physical addresses for the
-    // N levels of the systems paging structures.
-    // Level zero is the starting base physical
-    // address for virtual translations.
-    // Levels one-(N-1) will point to the appropriate
-    // paging descriptor for the virtual address at
-    // the given level of the paging hierarchy.  The
-    // exact number of levels depends on many factors.
-    // The last level will be the fully translated
-    // physical address, matching what VirtualToPhysical
-    // returns.  If the address can only be partially
-    // translated S_FALSE is returned.
-    STDMETHOD(GetVirtualTranslationPhysicalOffsets)(
-        THIS_
-        __in ULONG64 Virtual,
-        __out_ecount_opt(OffsetsSize) PULONG64 Offsets,
-        __in ULONG OffsetsSize,
-        __out_opt PULONG Levels
-        ) PURE;
-
-    // System handle data is accessible in certain
-    // debug sessions.  The particular data available
-    // varies from session to session and platform
-    // to platform.
-    STDMETHOD(ReadHandleData)(
-        THIS_
-        __in ULONG64 Handle,
-        __in ULONG DataType,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-
-    // Fills memory with the given pattern.
-    // The fill stops at the first non-writable byte.
-    STDMETHOD(FillVirtual)(
-        THIS_
-        __in ULONG64 Start,
-        __in ULONG Size,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __out_opt PULONG Filled
-        ) PURE;
-    STDMETHOD(FillPhysical)(
-        THIS_
-        __in ULONG64 Start,
-        __in ULONG Size,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __out_opt PULONG Filled
-        ) PURE;
-
-    // Queries virtual memory mapping information given
-    // an address similarly to the Win32 API VirtualQuery.
-    // MEMORY_BASIC_INFORMATION64 is defined in crash.h.
-    // This method currently only works for user-mode sessions.
-    STDMETHOD(QueryVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PMEMORY_BASIC_INFORMATION64 Info
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugDataSpaces3
-DECLARE_INTERFACE_(IDebugDataSpaces3, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugDataSpaces.
-    STDMETHOD(ReadVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    // SearchVirtual searches the given virtual
-    // address range for the given pattern.  PatternSize
-    // gives the byte length of the pattern and PatternGranularity
-    // controls the granularity of comparisons during
-    // the search.
-    // For example, a DWORD-granular search would
-    // use a pattern granularity of four to search by DWORD
-    // increments.
-    STDMETHOD(SearchVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Length,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __in ULONG PatternGranularity,
-        __out PULONG64 MatchOffset
-        ) PURE;
-    // These methods are identical to Read/WriteVirtual
-    // except that they avoid the kernel virtual memory
-    // cache entirely and are therefore useful for reading
-    // virtual memory which is inherently volatile, such
-    // as memory-mapped device areas, without contaminating
-    // or invalidating the cache.
-    // In user-mode they are the same as Read/WriteVirtual.
-    STDMETHOD(ReadVirtualUncached)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteVirtualUncached)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    // The following two methods are convenience
-    // methods for accessing pointer values.
-    // They automatically convert between native pointers
-    // and canonical 64-bit values as necessary.
-    // These routines stop at the first failure.
-    STDMETHOD(ReadPointersVirtual)(
-        THIS_
-        __in ULONG Count,
-        __in ULONG64 Offset,
-        __out_ecount(Count) PULONG64 Ptrs
-        ) PURE;
-    STDMETHOD(WritePointersVirtual)(
-        THIS_
-        __in ULONG Count,
-        __in ULONG64 Offset,
-        __in_ecount(Count) PULONG64 Ptrs
-        ) PURE;
-    // All non-virtual data spaces are only
-    // available when kernel debugging.
-    STDMETHOD(ReadPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WritePhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadControl)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteControl)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadIo)(
-        THIS_
-        __in ULONG InterfaceType,
-        __in ULONG BusNumber,
-        __in ULONG AddressSpace,
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteIo)(
-        THIS_
-        __in ULONG InterfaceType,
-        __in ULONG BusNumber,
-        __in ULONG AddressSpace,
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadMsr)(
-        THIS_
-        __in ULONG Msr,
-        __out PULONG64 Value
-        ) PURE;
-    STDMETHOD(WriteMsr)(
-        THIS_
-        __in ULONG Msr,
-        __in ULONG64 Value
-        ) PURE;
-    STDMETHOD(ReadBusData)(
-        THIS_
-        __in ULONG BusDataType,
-        __in ULONG BusNumber,
-        __in ULONG SlotNumber,
-        __in ULONG Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteBusData)(
-        THIS_
-        __in ULONG BusDataType,
-        __in ULONG BusNumber,
-        __in ULONG SlotNumber,
-        __in ULONG Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(CheckLowMemory)(
-        THIS
-        ) PURE;
-    STDMETHOD(ReadDebuggerData)(
-        THIS_
-        __in ULONG Index,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-    STDMETHOD(ReadProcessorSystemData)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG Index,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-
-    // IDebugDataSpaces2.
-
-    STDMETHOD(VirtualToPhysical)(
-        THIS_
-        __in ULONG64 Virtual,
-        __out PULONG64 Physical
-        ) PURE;
-    // Returns the physical addresses for the
-    // N levels of the systems paging structures.
-    // Level zero is the starting base physical
-    // address for virtual translations.
-    // Levels one-(N-1) will point to the appropriate
-    // paging descriptor for the virtual address at
-    // the given level of the paging hierarchy.  The
-    // exact number of levels depends on many factors.
-    // The last level will be the fully translated
-    // physical address, matching what VirtualToPhysical
-    // returns.  If the address can only be partially
-    // translated S_FALSE is returned.
-    STDMETHOD(GetVirtualTranslationPhysicalOffsets)(
-        THIS_
-        __in ULONG64 Virtual,
-        __out_ecount_opt(OffsetsSize) PULONG64 Offsets,
-        __in ULONG OffsetsSize,
-        __out_opt PULONG Levels
-        ) PURE;
-
-    // System handle data is accessible in certain
-    // debug sessions.  The particular data available
-    // varies from session to session and platform
-    // to platform.
-    STDMETHOD(ReadHandleData)(
-        THIS_
-        __in ULONG64 Handle,
-        __in ULONG DataType,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-
-    // Fills memory with the given pattern.
-    // The fill stops at the first non-writable byte.
-    STDMETHOD(FillVirtual)(
-        THIS_
-        __in ULONG64 Start,
-        __in ULONG Size,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __out_opt PULONG Filled
-        ) PURE;
-    STDMETHOD(FillPhysical)(
-        THIS_
-        __in ULONG64 Start,
-        __in ULONG Size,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __out_opt PULONG Filled
-        ) PURE;
-
-    // Queries virtual memory mapping information given
-    // an address similarly to the Win32 API VirtualQuery.
-    // MEMORY_BASIC_INFORMATION64 is defined in crash.h.
-    // This method currently only works for user-mode sessions.
-    STDMETHOD(QueryVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PMEMORY_BASIC_INFORMATION64 Info
-        ) PURE;
-
-    // IDebugDataSpaces3.
-
-    // Convenience method for reading an image
-    // header from virtual memory.  Given the
-    // image base, this method determines where
-    // the NT headers are, validates the necessary
-    // markers and converts the headers into
-    // 64-bit form for consistency.
-    // A caller can check whether the headers were
-    // originally 32-bit by checking the optional
-    // header magic value.
-    // This method will not read ROM headers.
-    STDMETHOD(ReadImageNtHeaders)(
-        THIS_
-        __in ULONG64 ImageBase,
-        __out PIMAGE_NT_HEADERS64 Headers
-        ) PURE;
-
-    // Some debug sessions have arbitrary additional
-    // data available.  For example, additional dump
-    // information files may contain extra information
-    // gathered at the same time as the primary dump.
-    // Such information is tagged with a unique identifier
-    // and can only be retrieved via the tag.
-    // Tagged data cannot be partially available; the
-    // tagged block is either fully present or completely
-    // absent.
-    STDMETHOD(ReadTagged)(
-        THIS_
-        __in LPGUID Tag,
-        __in ULONG Offset,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TotalSize
-        ) PURE;
-    STDMETHOD(StartEnumTagged)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(GetNextTagged)(
-        THIS_
-        __in ULONG64 Handle,
-        __out LPGUID Tag,
-        __out PULONG Size
-        ) PURE;
-    STDMETHOD(EndEnumTagged)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-};
-
-#define DEBUG_OFFSINFO_VIRTUAL_SOURCE 0x00000001
-
-#define DEBUG_VSOURCE_INVALID      0x00000000
-#define DEBUG_VSOURCE_DEBUGGEE     0x00000001
-#define DEBUG_VSOURCE_MAPPED_IMAGE 0x00000002
-
-#define DEBUG_VSEARCH_DEFAULT       0x00000000
-#define DEBUG_VSEARCH_WRITABLE_ONLY 0x00000001
-
-#define DEBUG_PHYSICAL_DEFAULT        0x00000000
-#define DEBUG_PHYSICAL_CACHED         0x00000001
-#define DEBUG_PHYSICAL_UNCACHED       0x00000002
-#define DEBUG_PHYSICAL_WRITE_COMBINED 0x00000003
-
-#undef INTERFACE
-#define INTERFACE IDebugDataSpaces4
-DECLARE_INTERFACE_(IDebugDataSpaces4, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugDataSpaces.
-
-    STDMETHOD(ReadVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    // SearchVirtual searches the given virtual
-    // address range for the given pattern.  PatternSize
-    // gives the byte length of the pattern and PatternGranularity
-    // controls the granularity of comparisons during
-    // the search.
-    // For example, a DWORD-granular search would
-    // use a pattern granularity of four to search by DWORD
-    // increments.
-    STDMETHOD(SearchVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Length,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __in ULONG PatternGranularity,
-        __out PULONG64 MatchOffset
-        ) PURE;
-    // These methods are identical to Read/WriteVirtual
-    // except that they avoid the kernel virtual memory
-    // cache entirely and are therefore useful for reading
-    // virtual memory which is inherently volatile, such
-    // as memory-mapped device areas, without contaminating
-    // or invalidating the cache.
-    // In user-mode they are the same as Read/WriteVirtual.
-    STDMETHOD(ReadVirtualUncached)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteVirtualUncached)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    // The following two methods are convenience
-    // methods for accessing pointer values.
-    // They automatically convert between native pointers
-    // and canonical 64-bit values as necessary.
-    // These routines stop at the first failure.
-    STDMETHOD(ReadPointersVirtual)(
-        THIS_
-        __in ULONG Count,
-        __in ULONG64 Offset,
-        __out_ecount(Count) PULONG64 Ptrs
-        ) PURE;
-    STDMETHOD(WritePointersVirtual)(
-        THIS_
-        __in ULONG Count,
-        __in ULONG64 Offset,
-        __in_ecount(Count) PULONG64 Ptrs
-        ) PURE;
-    // All non-virtual data spaces are only
-    // available when kernel debugging.
-    STDMETHOD(ReadPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WritePhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadControl)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteControl)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadIo)(
-        THIS_
-        __in ULONG InterfaceType,
-        __in ULONG BusNumber,
-        __in ULONG AddressSpace,
-        __in ULONG64 Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteIo)(
-        THIS_
-        __in ULONG InterfaceType,
-        __in ULONG BusNumber,
-        __in ULONG AddressSpace,
-        __in ULONG64 Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(ReadMsr)(
-        THIS_
-        __in ULONG Msr,
-        __out PULONG64 Value
-        ) PURE;
-    STDMETHOD(WriteMsr)(
-        THIS_
-        __in ULONG Msr,
-        __in ULONG64 Value
-        ) PURE;
-    STDMETHOD(ReadBusData)(
-        THIS_
-        __in ULONG BusDataType,
-        __in ULONG BusNumber,
-        __in ULONG SlotNumber,
-        __in ULONG Offset,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteBusData)(
-        THIS_
-        __in ULONG BusDataType,
-        __in ULONG BusNumber,
-        __in ULONG SlotNumber,
-        __in ULONG Offset,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(CheckLowMemory)(
-        THIS
-        ) PURE;
-    STDMETHOD(ReadDebuggerData)(
-        THIS_
-        __in ULONG Index,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-    STDMETHOD(ReadProcessorSystemData)(
-        THIS_
-        __in ULONG Processor,
-        __in ULONG Index,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-
-    // IDebugDataSpaces2.
-
-    STDMETHOD(VirtualToPhysical)(
-        THIS_
-        __in ULONG64 Virtual,
-        __out PULONG64 Physical
-        ) PURE;
-    // Returns the physical addresses for the
-    // N levels of the systems paging structures.
-    // Level zero is the starting base physical
-    // address for virtual translations.
-    // Levels one-(N-1) will point to the appropriate
-    // paging descriptor for the virtual address at
-    // the given level of the paging hierarchy.  The
-    // exact number of levels depends on many factors.
-    // The last level will be the fully translated
-    // physical address, matching what VirtualToPhysical
-    // returns.  If the address can only be partially
-    // translated S_FALSE is returned.
-    STDMETHOD(GetVirtualTranslationPhysicalOffsets)(
-        THIS_
-        __in ULONG64 Virtual,
-        __out_ecount_opt(OffsetsSize) PULONG64 Offsets,
-        __in ULONG OffsetsSize,
-        __out_opt PULONG Levels
-        ) PURE;
-
-    // System handle data is accessible in certain
-    // debug sessions.  The particular data available
-    // varies from session to session and platform
-    // to platform.
-    STDMETHOD(ReadHandleData)(
-        THIS_
-        __in ULONG64 Handle,
-        __in ULONG DataType,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG DataSize
-        ) PURE;
-
-    // Fills memory with the given pattern.
-    // The fill stops at the first non-writable byte.
-    STDMETHOD(FillVirtual)(
-        THIS_
-        __in ULONG64 Start,
-        __in ULONG Size,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __out_opt PULONG Filled
-        ) PURE;
-    STDMETHOD(FillPhysical)(
-        THIS_
-        __in ULONG64 Start,
-        __in ULONG Size,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __out_opt PULONG Filled
-        ) PURE;
-
-    // Queries virtual memory mapping information given
-    // an address similarly to the Win32 API VirtualQuery.
-    // MEMORY_BASIC_INFORMATION64 is defined in crash.h.
-    // This method currently only works for user-mode sessions.
-    STDMETHOD(QueryVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PMEMORY_BASIC_INFORMATION64 Info
-        ) PURE;
-
-    // IDebugDataSpaces3.
-
-    // Convenience method for reading an image
-    // header from virtual memory.  Given the
-    // image base, this method determines where
-    // the NT headers are, validates the necessary
-    // markers and converts the headers into
-    // 64-bit form for consistency.
-    // A caller can check whether the headers were
-    // originally 32-bit by checking the optional
-    // header magic value.
-    // This method will not read ROM headers.
-    STDMETHOD(ReadImageNtHeaders)(
-        THIS_
-        __in ULONG64 ImageBase,
-        __out PIMAGE_NT_HEADERS64 Headers
-        ) PURE;
-
-    // Some debug sessions have arbitrary additional
-    // data available.  For example, additional dump
-    // information files may contain extra information
-    // gathered at the same time as the primary dump.
-    // Such information is tagged with a unique identifier
-    // and can only be retrieved via the tag.
-    // Tagged data cannot be partially available; the
-    // tagged block is either fully present or completely
-    // absent.
-    STDMETHOD(ReadTagged)(
-        THIS_
-        __in LPGUID Tag,
-        __in ULONG Offset,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG TotalSize
-        ) PURE;
-    STDMETHOD(StartEnumTagged)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(GetNextTagged)(
-        THIS_
-        __in ULONG64 Handle,
-        __out LPGUID Tag,
-        __out PULONG Size
-        ) PURE;
-    STDMETHOD(EndEnumTagged)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-
-    // IDebugDataSpaces4.
-
-    // General information about an address in the given data space.
-    // Queries are from DEBUG_OFFSINFO_*.
-    STDMETHOD(GetOffsetInformation)(
-        THIS_
-        __in ULONG Space,
-        __in ULONG Which,
-        __in ULONG64 Offset,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG InfoSize
-        ) PURE;
-
-    // Given a particular address, return the
-    // next address which has a different validity.
-    // For example, in debug sessions such as a live
-    // user-mode session where virtual address validity
-    // changes from page to page this will return the
-    // page after the given page.  In sessions such as
-    // a user-mode dump file where validity can change
-    // from byte to byte this will return the start of
-    // the next region that has different validity.
-    STDMETHOD(GetNextDifferentlyValidOffsetVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG64 NextOffset
-        ) PURE;
-
-    // Given a particular range of virtual addresses,
-    // find the first region which is valid memory.
-    STDMETHOD(GetValidRegionVirtual)(
-        THIS_
-        __in ULONG64 Base,
-        __in ULONG Size,
-        __out PULONG64 ValidBase,
-        __out PULONG ValidSize
-        ) PURE;
-
-    STDMETHOD(SearchVirtual2)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Length,
-        __in ULONG Flags,
-        __in_bcount(PatternSize) PVOID Pattern,
-        __in ULONG PatternSize,
-        __in ULONG PatternGranularity,
-        __out PULONG64 MatchOffset
-        ) PURE;
-
-    // Attempts to read a multi-byte string
-    // starting at the given virtual address.
-    // The possible string length, including terminator,
-    // is capped at the given max size.
-    // If a return buffer is given it will always
-    // be terminated.
-    STDMETHOD(ReadMultiByteStringVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG MaxBytes,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringBytes
-        ) PURE;
-    // Reads a multi-byte string and converts
-    // it to Unicode using the given code page.
-    STDMETHOD(ReadMultiByteStringVirtualWide)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG MaxBytes,
-        __in ULONG CodePage,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringBytes
-        ) PURE;
-    STDMETHOD(ReadUnicodeStringVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG MaxBytes,
-        __in ULONG CodePage,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringBytes
-        ) PURE;
-    STDMETHOD(ReadUnicodeStringVirtualWide)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG MaxBytes,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringBytes
-        ) PURE;
-
-    STDMETHOD(ReadPhysical2)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WritePhysical2)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugEventCallbacks.
-//
-//----------------------------------------------------------------------------
-
-// Interest mask bits.
-#define DEBUG_EVENT_BREAKPOINT              0x00000001
-#define DEBUG_EVENT_EXCEPTION               0x00000002
-#define DEBUG_EVENT_CREATE_THREAD           0x00000004
-#define DEBUG_EVENT_EXIT_THREAD             0x00000008
-#define DEBUG_EVENT_CREATE_PROCESS          0x00000010
-#define DEBUG_EVENT_EXIT_PROCESS            0x00000020
-#define DEBUG_EVENT_LOAD_MODULE             0x00000040
-#define DEBUG_EVENT_UNLOAD_MODULE           0x00000080
-#define DEBUG_EVENT_SYSTEM_ERROR            0x00000100
-#define DEBUG_EVENT_SESSION_STATUS          0x00000200
-#define DEBUG_EVENT_CHANGE_DEBUGGEE_STATE   0x00000400
-#define DEBUG_EVENT_CHANGE_ENGINE_STATE     0x00000800
-#define DEBUG_EVENT_CHANGE_SYMBOL_STATE     0x00001000
-
-// SessionStatus flags.
-// A debuggee has been discovered for the session.
-#define DEBUG_SESSION_ACTIVE                       0x00000000
-// The session has been ended by EndSession.
-#define DEBUG_SESSION_END_SESSION_ACTIVE_TERMINATE 0x00000001
-#define DEBUG_SESSION_END_SESSION_ACTIVE_DETACH    0x00000002
-#define DEBUG_SESSION_END_SESSION_PASSIVE          0x00000003
-// The debuggee has run to completion.  User-mode only.
-#define DEBUG_SESSION_END                          0x00000004
-// The target machine has rebooted.  Kernel-mode only.
-#define DEBUG_SESSION_REBOOT                       0x00000005
-// The target machine has hibernated.  Kernel-mode only.
-#define DEBUG_SESSION_HIBERNATE                    0x00000006
-// The engine was unable to continue the session.
-#define DEBUG_SESSION_FAILURE                      0x00000007
-
-// ChangeDebuggeeState flags.
-// The debuggees state has changed generally, such
-// as when the debuggee has been executing.
-// Argument is zero.
-#define DEBUG_CDS_ALL       0xffffffff
-// Registers have changed.  If only a single register
-// changed, argument is the index of the register.
-// Otherwise it is DEBUG_ANY_ID.
-#define DEBUG_CDS_REGISTERS 0x00000001
-// Data spaces have changed.  If only a single
-// space was affected, argument is the data
-// space.  Otherwise it is DEBUG_ANY_ID.
-#define DEBUG_CDS_DATA      0x00000002
-
-// ChangeEngineState flags.
-// The engine state has changed generally.
-// Argument is zero.
-#define DEBUG_CES_ALL                 0xffffffff
-// Current thread changed.  This may imply a change
-// of system and process also.  Argument is the ID of the new
-// current thread or DEBUG_ANY_ID if no thread is current.
-#define DEBUG_CES_CURRENT_THREAD      0x00000001
-// Effective processor changed.  Argument is the
-// new processor type.
-#define DEBUG_CES_EFFECTIVE_PROCESSOR 0x00000002
-// Breakpoints changed.  If only a single breakpoint
-// changed, argument is the ID of the breakpoint.
-// Otherwise it is DEBUG_ANY_ID.
-#define DEBUG_CES_BREAKPOINTS         0x00000004
-// Code interpretation level changed.  Argument is
-// the new level.
-#define DEBUG_CES_CODE_LEVEL          0x00000008
-// Execution status changed.  Argument is the new
-// execution status.
-#define DEBUG_CES_EXECUTION_STATUS    0x00000010
-// Engine options have changed.  Argument is the new
-// options value.
-#define DEBUG_CES_ENGINE_OPTIONS      0x00000020
-// Log file information has changed.  Argument
-// is TRUE if a log file was opened and FALSE if
-// a log file was closed.
-#define DEBUG_CES_LOG_FILE            0x00000040
-// Default number radix has changed.  Argument
-// is the new radix.
-#define DEBUG_CES_RADIX               0x00000080
-// Event filters changed.  If only a single filter
-// changed the argument is the filter's index,
-// otherwise it is DEBUG_ANY_ID.
-#define DEBUG_CES_EVENT_FILTERS       0x00000100
-// Process options have changed.  Argument is the new
-// options value.
-#define DEBUG_CES_PROCESS_OPTIONS     0x00000200
-// Extensions have been added or removed.
-#define DEBUG_CES_EXTENSIONS          0x00000400
-// Systems have been added or removed.  The argument
-// is the system ID.  Systems, unlike processes and
-// threads, may be created at any time and not
-// just during WaitForEvent.
-#define DEBUG_CES_SYSTEMS             0x00000800
-// Assembly/disassembly options have changed.  Argument
-// is the new options value.
-#define DEBUG_CES_ASSEMBLY_OPTIONS    0x00001000
-// Expression syntax has changed.  Argument
-// is the new syntax value.
-#define DEBUG_CES_EXPRESSION_SYNTAX   0x00002000
-// Text replacements have changed.
-#define DEBUG_CES_TEXT_REPLACEMENTS   0x00004000
-
-// ChangeSymbolState flags.
-// Symbol state has changed generally, such
-// as after reload operations.  Argument is zero.
-#define DEBUG_CSS_ALL            0xffffffff
-// Modules have been loaded.  If only a
-// single module changed, argument is the
-// base address of the module.  Otherwise
-// it is zero.
-#define DEBUG_CSS_LOADS          0x00000001
-// Modules have been unloaded.  If only a
-// single module changed, argument is the
-// base address of the module.  Otherwise
-// it is zero.
-#define DEBUG_CSS_UNLOADS        0x00000002
-// Current symbol scope changed.
-#define DEBUG_CSS_SCOPE          0x00000004
-// Paths have changed.
-#define DEBUG_CSS_PATHS          0x00000008
-// Symbol options have changed.  Argument is the new
-// options value.
-#define DEBUG_CSS_SYMBOL_OPTIONS 0x00000010
-// Type options have changed.  Argument is the new
-// options value.
-#define DEBUG_CSS_TYPE_OPTIONS   0x00000020
-
-#undef INTERFACE
-#define INTERFACE IDebugEventCallbacks
-DECLARE_INTERFACE_(IDebugEventCallbacks, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugEventCallbacks.
-
-    // The engine calls GetInterestMask once when
-    // the event callbacks are set for a client.
-    STDMETHOD(GetInterestMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-
-    // A breakpoint event is generated when
-    // a breakpoint exception is received and
-    // it can be mapped to an existing breakpoint.
-    // The callback method is given a reference
-    // to the breakpoint and should release it when
-    // it is done with it.
-    STDMETHOD(Breakpoint)(
-        THIS_
-        __in PDEBUG_BREAKPOINT Bp
-        ) PURE;
-
-    // Exceptions include breaks which cannot
-    // be mapped to an existing breakpoint
-    // instance.
-    STDMETHOD(Exception)(
-        THIS_
-        __in PEXCEPTION_RECORD64 Exception,
-        __in ULONG FirstChance
-        ) PURE;
-
-    // Any of these values can be zero if they
-    // cannot be provided by the engine.
-    // Currently the kernel does not return thread
-    // or process change events.
-    STDMETHOD(CreateThread)(
-        THIS_
-        __in ULONG64 Handle,
-        __in ULONG64 DataOffset,
-        __in ULONG64 StartOffset
-        ) PURE;
-    STDMETHOD(ExitThread)(
-        THIS_
-        __in ULONG ExitCode
-        ) PURE;
-
-    // Any of these values can be zero if they
-    // cannot be provided by the engine.
-    STDMETHOD(CreateProcess)(
-        THIS_
-        __in ULONG64 ImageFileHandle,
-        __in ULONG64 Handle,
-        __in ULONG64 BaseOffset,
-        __in ULONG ModuleSize,
-        __in_opt PCSTR ModuleName,
-        __in_opt PCSTR ImageName,
-        __in ULONG CheckSum,
-        __in ULONG TimeDateStamp,
-        __in ULONG64 InitialThreadHandle,
-        __in ULONG64 ThreadDataOffset,
-        __in ULONG64 StartOffset
-        ) PURE;
-    STDMETHOD(ExitProcess)(
-        THIS_
-        __in ULONG ExitCode
-        ) PURE;
-
-    // Any of these values may be zero.
-    STDMETHOD(LoadModule)(
-        THIS_
-        __in ULONG64 ImageFileHandle,
-        __in ULONG64 BaseOffset,
-        __in ULONG ModuleSize,
-        __in_opt PCSTR ModuleName,
-        __in_opt PCSTR ImageName,
-        __in ULONG CheckSum,
-        __in ULONG TimeDateStamp
-        ) PURE;
-    STDMETHOD(UnloadModule)(
-        THIS_
-        __in_opt PCSTR ImageBaseName,
-        __in ULONG64 BaseOffset
-        ) PURE;
-
-    STDMETHOD(SystemError)(
-        THIS_
-        __in ULONG Error,
-        __in ULONG Level
-        ) PURE;
-
-    // Session status is synchronous like the other
-    // wait callbacks but it is called as the state
-    // of the session is changing rather than at
-    // specific events so its return value does not
-    // influence waiting.  Implementations should just
-    // return DEBUG_STATUS_NO_CHANGE.
-    // Also, because some of the status
-    // notifications are very early or very
-    // late in the session lifetime there may not be
-    // current processes or threads when the notification
-    // is generated.
-    STDMETHOD(SessionStatus)(
-        THIS_
-        __in ULONG Status
-        ) PURE;
-
-    // The following callbacks are informational
-    // callbacks notifying the provider about
-    // changes in debug state.  The return value
-    // of these callbacks is ignored.  Implementations
-    // can not call back into the engine.
-
-    // Debuggee state, such as registers or data spaces,
-    // has changed.
-    STDMETHOD(ChangeDebuggeeState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        ) PURE;
-    // Engine state has changed.
-    STDMETHOD(ChangeEngineState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        ) PURE;
-    // Symbol state has changed.
-    STDMETHOD(ChangeSymbolState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugEventCallbacksWide
-DECLARE_INTERFACE_(IDebugEventCallbacksWide, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugEventCallbacksWide.
-
-    // The engine calls GetInterestMask once when
-    // the event callbacks are set for a client.
-    STDMETHOD(GetInterestMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-
-    // A breakpoint event is generated when
-    // a breakpoint exception is received and
-    // it can be mapped to an existing breakpoint.
-    // The callback method is given a reference
-    // to the breakpoint and should release it when
-    // it is done with it.
-    STDMETHOD(Breakpoint)(
-        THIS_
-        __in PDEBUG_BREAKPOINT2 Bp
-        ) PURE;
-
-    // Exceptions include breaks which cannot
-    // be mapped to an existing breakpoint
-    // instance.
-    STDMETHOD(Exception)(
-        THIS_
-        __in PEXCEPTION_RECORD64 Exception,
-        __in ULONG FirstChance
-        ) PURE;
-
-    // Any of these values can be zero if they
-    // cannot be provided by the engine.
-    // Currently the kernel does not return thread
-    // or process change events.
-    STDMETHOD(CreateThread)(
-        THIS_
-        __in ULONG64 Handle,
-        __in ULONG64 DataOffset,
-        __in ULONG64 StartOffset
-        ) PURE;
-    STDMETHOD(ExitThread)(
-        THIS_
-        __in ULONG ExitCode
-        ) PURE;
-
-    // Any of these values can be zero if they
-    // cannot be provided by the engine.
-    STDMETHOD(CreateProcess)(
-        THIS_
-        __in ULONG64 ImageFileHandle,
-        __in ULONG64 Handle,
-        __in ULONG64 BaseOffset,
-        __in ULONG ModuleSize,
-        __in_opt PCWSTR ModuleName,
-        __in_opt PCWSTR ImageName,
-        __in ULONG CheckSum,
-        __in ULONG TimeDateStamp,
-        __in ULONG64 InitialThreadHandle,
-        __in ULONG64 ThreadDataOffset,
-        __in ULONG64 StartOffset
-        ) PURE;
-    STDMETHOD(ExitProcess)(
-        THIS_
-        __in ULONG ExitCode
-        ) PURE;
-
-    // Any of these values may be zero.
-    STDMETHOD(LoadModule)(
-        THIS_
-        __in ULONG64 ImageFileHandle,
-        __in ULONG64 BaseOffset,
-        __in ULONG ModuleSize,
-        __in_opt PCWSTR ModuleName,
-        __in_opt PCWSTR ImageName,
-        __in ULONG CheckSum,
-        __in ULONG TimeDateStamp
-        ) PURE;
-    STDMETHOD(UnloadModule)(
-        THIS_
-        __in_opt PCWSTR ImageBaseName,
-        __in ULONG64 BaseOffset
-        ) PURE;
-
-    STDMETHOD(SystemError)(
-        THIS_
-        __in ULONG Error,
-        __in ULONG Level
-        ) PURE;
-
-    // Session status is synchronous like the other
-    // wait callbacks but it is called as the state
-    // of the session is changing rather than at
-    // specific events so its return value does not
-    // influence waiting.  Implementations should just
-    // return DEBUG_STATUS_NO_CHANGE.
-    // Also, because some of the status
-    // notifications are very early or very
-    // late in the session lifetime there may not be
-    // current processes or threads when the notification
-    // is generated.
-    STDMETHOD(SessionStatus)(
-        THIS_
-        __in ULONG Status
-        ) PURE;
-
-    // The following callbacks are informational
-    // callbacks notifying the provider about
-    // changes in debug state.  The return value
-    // of these callbacks is ignored.  Implementations
-    // can not call back into the engine.
-
-    // Debuggee state, such as registers or data spaces,
-    // has changed.
-    STDMETHOD(ChangeDebuggeeState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        ) PURE;
-    // Engine state has changed.
-    STDMETHOD(ChangeEngineState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        ) PURE;
-    // Symbol state has changed.
-    STDMETHOD(ChangeSymbolState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugInputCallbacks.
-//
-//----------------------------------------------------------------------------
-
-#undef INTERFACE
-#define INTERFACE IDebugInputCallbacks
-DECLARE_INTERFACE_(IDebugInputCallbacks, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugInputCallbacks.
-
-    // A call to the StartInput method is a request for
-    // a line of input from any client.  The returned input
-    // should always be zero-terminated.  The buffer size
-    // provided is only a guideline.  A client can return
-    // more if necessary and the engine will truncate it
-    // before returning from IDebugControl::Input.
-    // The return value is ignored.
-    STDMETHOD(StartInput)(
-        THIS_
-        __in ULONG BufferSize
-        ) PURE;
-    // The return value is ignored.
-    STDMETHOD(EndInput)(
-        THIS
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugOutputCallbacks.
-//
-//----------------------------------------------------------------------------
-
-#undef INTERFACE
-#define INTERFACE IDebugOutputCallbacks
-DECLARE_INTERFACE_(IDebugOutputCallbacks, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugOutputCallbacks.
-
-    // This method is only called if the supplied mask
-    // is allowed by the clients output control.
-    // The return value is ignored.
-    STDMETHOD(Output)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Text
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugOutputCallbacksWide
-DECLARE_INTERFACE_(IDebugOutputCallbacksWide, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugOutputCallbacksWide.
-
-    // This method is only called if the supplied mask
-    // is allowed by the clients output control.
-    // The return value is ignored.
-    STDMETHOD(Output)(
-        THIS_
-        __in ULONG Mask,
-        __in PCWSTR Text
-        ) PURE;
-};
-
-//
-// IDebugOutputCallbacks2 interest mask flags.
-//
-
-// Indicates that the callback wants notifications
-// of all explicit flushes.
-#define DEBUG_OUTCBI_EXPLICIT_FLUSH 0x00000001
-// Indicates that the callback wants
-// content in text form.
-#define DEBUG_OUTCBI_TEXT           0x00000002
-// Indicates that the callback wants
-// content in markup form.
-#define DEBUG_OUTCBI_DML            0x00000004
-
-#define DEBUG_OUTCBI_ANY_FORMAT     0x00000006
-
-//
-// Different kinds of output callback notifications
-// that can be sent to Output2.
-//
-
-// Plain text content, flags are below, argument is mask.
-#define DEBUG_OUTCB_TEXT           0
-// Debugger markup content, flags are below, argument is mask.
-#define DEBUG_OUTCB_DML            1
-// Notification of an explicit output flush, flags and argument are zero.
-#define DEBUG_OUTCB_EXPLICIT_FLUSH 2
-
-//
-// Flags for various Output2 callbacks.
-//
-
-// The content string was followed by an
-// explicit flush.  This flag will be used
-// instead of a separate DEBUG_OUTCB_EXPLICIT_FLUSH
-// callback when a flush has text to flush,
-// thus avoiding two callbacks.
-#define DEBUG_OUTCBF_COMBINED_EXPLICIT_FLUSH    0x00000001
-
-// The markup content string has embedded tags.
-#define DEBUG_OUTCBF_DML_HAS_TAGS               0x00000002
-// The markup content has encoded special characters like ", &, < and >.
-#define DEBUG_OUTCBF_DML_HAS_SPECIAL_CHARACTERS 0x00000004
-
-#undef INTERFACE
-#define INTERFACE IDebugOutputCallbacks2
-DECLARE_INTERFACE_(IDebugOutputCallbacks2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugOutputCallbacks.
-
-    // This method is not used.
-    STDMETHOD(Output)(
-        THIS_
-        __in ULONG Mask,
-        __in PCSTR Text
-        ) PURE;
-
-    // IDebugOutputCallbacks2.
-
-    // The engine calls GetInterestMask once when
-    // the callbacks are set for a client.
-    STDMETHOD(GetInterestMask)(
-        THIS_
-        __out PULONG Mask
-        ) PURE;
-    
-    STDMETHOD(Output2)(
-        THIS_
-        __in ULONG Which,
-        __in ULONG Flags,
-        __in ULONG64 Arg,
-        __in_opt PCWSTR Text
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugRegisters.
-//
-//----------------------------------------------------------------------------
-
-#define DEBUG_REGISTERS_DEFAULT 0x00000000
-#define DEBUG_REGISTERS_INT32   0x00000001
-#define DEBUG_REGISTERS_INT64   0x00000002
-#define DEBUG_REGISTERS_FLOAT   0x00000004
-#define DEBUG_REGISTERS_ALL     0x00000007
-
-#define DEBUG_REGISTER_SUB_REGISTER 0x00000001
-
-typedef struct _DEBUG_REGISTER_DESCRIPTION
-{
-    // DEBUG_VALUE type.
-    ULONG Type;
-    ULONG Flags;
-
-    // If this is a subregister the full
-    // registers description index is
-    // given in SubregMaster.  The length, mask
-    // and shift describe how the subregisters
-    // bits fit into the full register.
-    ULONG SubregMaster;
-    ULONG SubregLength;
-    ULONG64 SubregMask;
-    ULONG SubregShift;
-
-    ULONG Reserved0;
-} DEBUG_REGISTER_DESCRIPTION, *PDEBUG_REGISTER_DESCRIPTION;
-
-#undef INTERFACE
-#define INTERFACE IDebugRegisters
-DECLARE_INTERFACE_(IDebugRegisters, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugRegisters.
-    STDMETHOD(GetNumberRegisters)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetDescription)(
-        THIS_
-        __in ULONG Register,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PDEBUG_REGISTER_DESCRIPTION Desc
-        ) PURE;
-    STDMETHOD(GetIndexByName)(
-        THIS_
-        __in PCSTR Name,
-        __out PULONG Index
-        ) PURE;
-
-    STDMETHOD(GetValue)(
-        THIS_
-        __in ULONG Register,
-        __out PDEBUG_VALUE Value
-        ) PURE;
-    // SetValue makes a best effort at coercing
-    // the given value into the given registers
-    // value type.  If the given value is larger
-    // than the register can hold the least
-    // significant bits will be dropped.  Float
-    // to int and int to float will be done
-    // if necessary.  Subregister bits will be
-    // inserted into the master register.
-    STDMETHOD(SetValue)(
-        THIS_
-        __in ULONG Register,
-        __in PDEBUG_VALUE Value
-        ) PURE;
-    // Gets Count register values.  If Indices is
-    // non-NULL it must contain Count register
-    // indices which control the registers affected.
-    // If Indices is NULL the registers from Start
-    // to Start + Count  1 are retrieved.
-    STDMETHOD(GetValues)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Indices,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_VALUE Values
-        ) PURE;
-    STDMETHOD(SetValues)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Indices,
-        __in ULONG Start,
-        __in_ecount(Count) PDEBUG_VALUE Values
-        ) PURE;
-
-    // Outputs a group of registers in a well-formatted
-    // way thats specific to the platforms register set.
-    // Uses the line prefix.
-    STDMETHOD(OutputRegisters)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags
-        ) PURE;
-
-    // Abstracted pieces of processor information.
-    // The mapping of these values to architectural
-    // registers is architecture-specific and their
-    // interpretation and existence may vary.  They
-    // are intended to be directly compatible with
-    // calls which take this information, such as
-    // stack walking.
-    STDMETHOD(GetInstructionOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetStackOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetFrameOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-};
-
-//
-// The engine maintains several separate
-// pieces of context information.  There is
-// the current debuggee context, a possible
-// override context, such as from .cxr,
-// a context for the current scope frame and so on.
-//
-
-// Get register information from the debuggee.
-#define DEBUG_REGSRC_DEBUGGEE 0x00000000
-// Get register information from an explicit
-// override context, such as one set by .cxr.
-// If there is no override context the request will fail.
-#define DEBUG_REGSRC_EXPLICIT 0x00000001
-// Get register information from the current scope
-// frame.  Note that stack unwinding does not guarantee
-// accurate updating of the register context,
-// so scope frame register context may not be accurate
-// in all cases.
-#define DEBUG_REGSRC_FRAME    0x00000002
-
-#undef INTERFACE
-#define INTERFACE IDebugRegisters2
-DECLARE_INTERFACE_(IDebugRegisters2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugRegisters.
-
-    STDMETHOD(GetNumberRegisters)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetDescription)(
-        THIS_
-        __in ULONG Register,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PDEBUG_REGISTER_DESCRIPTION Desc
-        ) PURE;
-    STDMETHOD(GetIndexByName)(
-        THIS_
-        __in PCSTR Name,
-        __out PULONG Index
-        ) PURE;
-
-    STDMETHOD(GetValue)(
-        THIS_
-        __in ULONG Register,
-        __out PDEBUG_VALUE Value
-        ) PURE;
-    // SetValue makes a best effort at coercing
-    // the given value into the given registers
-    // value type.  If the given value is larger
-    // than the register can hold the least
-    // significant bits will be dropped.  Float
-    // to int and int to float will be done
-    // if necessary.  Subregister bits will be
-    // inserted into the master register.
-    STDMETHOD(SetValue)(
-        THIS_
-        __in ULONG Register,
-        __in PDEBUG_VALUE Value
-        ) PURE;
-    // Gets Count register values.  If Indices is
-    // non-NULL it must contain Count register
-    // indices which control the registers affected.
-    // If Indices is NULL the registers from Start
-    // to Start + Count  1 are retrieved.
-    STDMETHOD(GetValues)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Indices,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_VALUE Values
-        ) PURE;
-    STDMETHOD(SetValues)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Indices,
-        __in ULONG Start,
-        __in_ecount(Count) PDEBUG_VALUE Values
-        ) PURE;
-
-    // Outputs a group of registers in a well-formatted
-    // way thats specific to the platforms register set.
-    // Uses the line prefix.
-    STDMETHOD(OutputRegisters)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags
-        ) PURE;
-
-    // Abstracted pieces of processor information.
-    // The mapping of these values to architectural
-    // registers is architecture-specific and their
-    // interpretation and existence may vary.  They
-    // are intended to be directly compatible with
-    // calls which take this information, such as
-    // stack walking.
-    STDMETHOD(GetInstructionOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetStackOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetFrameOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-
-    // IDebugRegisters2.
-
-    STDMETHOD(GetDescriptionWide)(
-        THIS_
-        __in ULONG Register,
-        __out_ecount_opt(NameBufferSize) PWSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PDEBUG_REGISTER_DESCRIPTION Desc
-        ) PURE;
-    STDMETHOD(GetIndexByNameWide)(
-        THIS_
-        __in PCWSTR Name,
-        __out PULONG Index
-        ) PURE;
-
-    // Pseudo-registers are synthetic values derived
-    // by the engine that are presented in a manner
-    // similar to regular registers.  They are simple
-    // value holders, similar to actual registers.
-    // Pseudo-registers are defined for concepts,
-    // such as current-instruction-pointer or
-    // current-thread-data.  As such they have
-    // types appropriate for their data.
-    STDMETHOD(GetNumberPseudoRegisters)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetPseudoDescription)(
-        THIS_
-        __in ULONG Register,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 TypeModule,
-        __out_opt PULONG TypeId
-        ) PURE;
-    STDMETHOD(GetPseudoDescriptionWide)(
-        THIS_
-        __in ULONG Register,
-        __out_ecount_opt(NameBufferSize) PWSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 TypeModule,
-        __out_opt PULONG TypeId
-        ) PURE;
-    STDMETHOD(GetPseudoIndexByName)(
-        THIS_
-        __in PCSTR Name,
-        __out PULONG Index
-        ) PURE;
-    STDMETHOD(GetPseudoIndexByNameWide)(
-        THIS_
-        __in PCWSTR Name,
-        __out PULONG Index
-        ) PURE;
-    // Some pseudo-register values are affected
-    // by the register source, others are not.
-    STDMETHOD(GetPseudoValues)(
-        THIS_
-        __in ULONG Source,
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Indices,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_VALUE Values
-        ) PURE;
-    // Many pseudo-registers are read-only and cannot be set.
-    STDMETHOD(SetPseudoValues)(
-        THIS_
-        __in ULONG Source,
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Indices,
-        __in ULONG Start,
-        __in_ecount(Count) PDEBUG_VALUE Values
-        ) PURE;
-
-    // These expanded methods allow selection
-    // of the source of register information.
-    STDMETHOD(GetValues2)(
-        THIS_
-        __in ULONG Source,
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Indices,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_VALUE Values
-        ) PURE;
-    STDMETHOD(SetValues2)(
-        THIS_
-        __in ULONG Source,
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG Indices,
-        __in ULONG Start,
-        __in_ecount(Count) PDEBUG_VALUE Values
-        ) PURE;
-    STDMETHOD(OutputRegisters2)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Source,
-        __in ULONG Flags
-        ) PURE;
-    STDMETHOD(GetInstructionOffset2)(
-        THIS_
-        __in ULONG Source,
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetStackOffset2)(
-        THIS_
-        __in ULONG Source,
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetFrameOffset2)(
-        THIS_
-        __in ULONG Source,
-        __out PULONG64 Offset
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugSymbolGroup
-//
-//----------------------------------------------------------------------------
-
-// OutputSymbols flags.
-// Default output contains
-//   <Name>**NAME**<Offset>**OFF**<Value>**VALUE**<Type>**TYPE**
-// per symbol.
-#define DEBUG_OUTPUT_SYMBOLS_DEFAULT    0x00000000
-#define DEBUG_OUTPUT_SYMBOLS_NO_NAMES   0x00000001
-#define DEBUG_OUTPUT_SYMBOLS_NO_OFFSETS 0x00000002
-#define DEBUG_OUTPUT_SYMBOLS_NO_VALUES  0x00000004
-#define DEBUG_OUTPUT_SYMBOLS_NO_TYPES   0x00000010
-
-#define DEBUG_OUTPUT_NAME_END           "**NAME**"
-#define DEBUG_OUTPUT_OFFSET_END         "**OFF**"
-#define DEBUG_OUTPUT_VALUE_END          "**VALUE**"
-#define DEBUG_OUTPUT_TYPE_END           "**TYPE**"
-
-#define DEBUG_OUTPUT_NAME_END_WIDE      L"**NAME**"
-#define DEBUG_OUTPUT_OFFSET_END_WIDE    L"**OFF**"
-#define DEBUG_OUTPUT_VALUE_END_WIDE     L"**VALUE**"
-#define DEBUG_OUTPUT_TYPE_END_WIDE      L"**TYPE**"
-
-#ifdef UNICODE
-#define DEBUG_OUTPUT_NAME_END_T DEBUG_OUTPUT_NAME_END_WIDE
-#define DEBUG_OUTPUT_OFFSET_END_T DEBUG_OUTPUT_OFFSET_END_WIDE
-#define DEBUG_OUTPUT_VALUE_END_T DEBUG_OUTPUT_VALUE_END_WIDE
-#define DEBUG_OUTPUT_TYPE_END_T DEBUG_OUTPUT_TYPE_END_WIDE
-#else
-#define DEBUG_OUTPUT_NAME_END_T DEBUG_OUTPUT_NAME_END
-#define DEBUG_OUTPUT_OFFSET_END_T DEBUG_OUTPUT_OFFSET_END
-#define DEBUG_OUTPUT_VALUE_END_T DEBUG_OUTPUT_VALUE_END
-#define DEBUG_OUTPUT_TYPE_END_T DEBUG_OUTPUT_TYPE_END
-#endif
-
-// DEBUG_SYMBOL_PARAMETERS flags.
-// Cumulative expansion level, takes four bits.
-#define DEBUG_SYMBOL_EXPANSION_LEVEL_MASK 0x0000000f
-// Symbols subelements follow.
-#define DEBUG_SYMBOL_EXPANDED             0x00000010
-// Symbols value is read-only.
-#define DEBUG_SYMBOL_READ_ONLY            0x00000020
-// Symbol subelements are array elements.
-#define DEBUG_SYMBOL_IS_ARRAY             0x00000040
-// Symbol is a float value.
-#define DEBUG_SYMBOL_IS_FLOAT             0x00000080
-// Symbol is a scope argument.
-#define DEBUG_SYMBOL_IS_ARGUMENT          0x00000100
-// Symbol is a scope argument.
-#define DEBUG_SYMBOL_IS_LOCAL             0x00000200
-
-typedef struct _DEBUG_SYMBOL_PARAMETERS
-{
-    ULONG64 Module;
-    ULONG TypeId;
-    // ParentSymbol may be DEBUG_ANY_ID when unknown.
-    ULONG ParentSymbol;
-    // A subelement of a symbol can be a field, such
-    // as in structs, unions or classes; or an array
-    // element count for arrays.
-    ULONG SubElements;
-    ULONG Flags;
-    ULONG64 Reserved;
-} DEBUG_SYMBOL_PARAMETERS, *PDEBUG_SYMBOL_PARAMETERS;
-
-#undef INTERFACE
-#define INTERFACE IDebugSymbolGroup
-DECLARE_INTERFACE_(IDebugSymbolGroup, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugSymbolGroup.
-    STDMETHOD(GetNumberSymbols)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // On input Index indicates the desired insertion
-    // index.  On output Index contains the actual index.
-    // Use DEBUG_ANY_ID to append a symbol to the end.
-    STDMETHOD(AddSymbol)(
-        THIS_
-        __in PCSTR Name,
-        __inout PULONG Index
-        ) PURE;
-    STDMETHOD(RemoveSymbolByName)(
-        THIS_
-        __in PCSTR Name
-        ) PURE;
-    STDMETHOD(RemoveSymbolByIndex)(
-        THIS_
-        __in ULONG Index
-        ) PURE;
-    STDMETHOD(GetSymbolName)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    STDMETHOD(GetSymbolParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PDEBUG_SYMBOL_PARAMETERS Params
-        ) PURE;
-    STDMETHOD(ExpandSymbol)(
-        THIS_
-        __in ULONG Index,
-        __in BOOL Expand
-        ) PURE;
-    // Uses the line prefix.
-    STDMETHOD(OutputSymbols)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags,
-        __in ULONG Start,
-        __in ULONG Count
-        ) PURE;
-    STDMETHOD(WriteSymbol)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Value
-        ) PURE;
-    STDMETHOD(OutputAsType)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Type
-        ) PURE;
-};
-
-#define DEBUG_SYMENT_IS_CODE      0x00000001
-#define DEBUG_SYMENT_IS_DATA      0x00000002
-#define DEBUG_SYMENT_IS_PARAMETER 0x00000004
-#define DEBUG_SYMENT_IS_LOCAL     0x00000008
-#define DEBUG_SYMENT_IS_MANAGED   0x00000010
-#define DEBUG_SYMENT_IS_SYNTHETIC 0x00000020
-
-typedef struct _DEBUG_SYMBOL_ENTRY
-{
-    ULONG64 ModuleBase;
-    ULONG64 Offset;
-    ULONG64 Id;
-    ULONG64 Arg64;
-    ULONG Size;
-    ULONG Flags;
-    ULONG TypeId;
-    ULONG NameSize;
-    ULONG Token;
-    ULONG Tag;
-    ULONG Arg32;
-    ULONG Reserved;
-} DEBUG_SYMBOL_ENTRY, *PDEBUG_SYMBOL_ENTRY;
-
-#undef INTERFACE
-#define INTERFACE IDebugSymbolGroup2
-DECLARE_INTERFACE_(IDebugSymbolGroup2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugSymbolGroup.
-
-    STDMETHOD(GetNumberSymbols)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // On input Index indicates the desired insertion
-    // index.  On output Index contains the actual index.
-    // Use DEBUG_ANY_ID to append a symbol to the end.
-    STDMETHOD(AddSymbol)(
-        THIS_
-        __in PCSTR Name,
-        __inout PULONG Index
-        ) PURE;
-    STDMETHOD(RemoveSymbolByName)(
-        THIS_
-        __in PCSTR Name
-        ) PURE;
-    STDMETHOD(RemoveSymbolByIndex)(
-        THIS_
-        __in ULONG Index
-        ) PURE;
-    STDMETHOD(GetSymbolName)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    STDMETHOD(GetSymbolParameters)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PDEBUG_SYMBOL_PARAMETERS Params
-        ) PURE;
-    STDMETHOD(ExpandSymbol)(
-        THIS_
-        __in ULONG Index,
-        __in BOOL Expand
-        ) PURE;
-    // Uses the line prefix.
-    STDMETHOD(OutputSymbols)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags,
-        __in ULONG Start,
-        __in ULONG Count
-        ) PURE;
-    STDMETHOD(WriteSymbol)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Value
-        ) PURE;
-    STDMETHOD(OutputAsType)(
-        THIS_
-        __in ULONG Index,
-        __in PCSTR Type
-        ) PURE;
-
-    // IDebugSymbolGroup2.
-
-    STDMETHOD(AddSymbolWide)(
-        THIS_
-        __in PCWSTR Name,
-        __inout PULONG Index
-        ) PURE;
-    STDMETHOD(RemoveSymbolByNameWide)(
-        THIS_
-        __in PCWSTR Name
-        ) PURE;
-    STDMETHOD(GetSymbolNameWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    STDMETHOD(WriteSymbolWide)(
-        THIS_
-        __in ULONG Index,
-        __in PCWSTR Value
-        ) PURE;
-    STDMETHOD(OutputAsTypeWide)(
-        THIS_
-        __in ULONG Index,
-        __in PCWSTR Type
-        ) PURE;
-
-    STDMETHOD(GetSymbolTypeName)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    STDMETHOD(GetSymbolTypeNameWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    STDMETHOD(GetSymbolSize)(
-        THIS_
-        __in ULONG Index,
-        __out PULONG Size
-        ) PURE;
-    // If the symbol has an absolute address
-    // this method will retrieve it.
-    STDMETHOD(GetSymbolOffset)(
-        THIS_
-        __in ULONG Index,
-        __out PULONG64 Offset
-        ) PURE;
-    // If the symbol is enregistered this
-    // method will return the register index.
-    STDMETHOD(GetSymbolRegister)(
-        THIS_
-        __in ULONG Index,
-        __out PULONG Register
-        ) PURE;
-    STDMETHOD(GetSymbolValueText)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    STDMETHOD(GetSymbolValueTextWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    STDMETHOD(GetSymbolEntryInformation)(
-        THIS_
-        __in ULONG Index,
-        __out PDEBUG_SYMBOL_ENTRY Entry
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugSymbols.
-//
-//----------------------------------------------------------------------------
-
-//
-// Information about a module.
-//
-
-// Flags.
-#define DEBUG_MODULE_LOADED            0x00000000
-#define DEBUG_MODULE_UNLOADED          0x00000001
-#define DEBUG_MODULE_USER_MODE         0x00000002
-#define DEBUG_MODULE_EXPLICIT          0x00000008
-#define DEBUG_MODULE_SECONDARY         0x00000010
-#define DEBUG_MODULE_SYNTHETIC         0x00000020
-#define DEBUG_MODULE_SYM_BAD_CHECKSUM  0x00010000
-
-// Symbol types.
-#define DEBUG_SYMTYPE_NONE     0
-#define DEBUG_SYMTYPE_COFF     1
-#define DEBUG_SYMTYPE_CODEVIEW 2
-#define DEBUG_SYMTYPE_PDB      3
-#define DEBUG_SYMTYPE_EXPORT   4
-#define DEBUG_SYMTYPE_DEFERRED 5
-#define DEBUG_SYMTYPE_SYM      6
-#define DEBUG_SYMTYPE_DIA      7
-
-typedef struct _DEBUG_MODULE_PARAMETERS
-{
-    ULONG64 Base;
-    ULONG Size;
-    ULONG TimeDateStamp;
-    ULONG Checksum;
-    ULONG Flags;
-    ULONG SymbolType;
-    ULONG ImageNameSize;
-    ULONG ModuleNameSize;
-    ULONG LoadedImageNameSize;
-    ULONG SymbolFileNameSize;
-    ULONG MappedImageNameSize;
-    ULONG64 Reserved[2];
-} DEBUG_MODULE_PARAMETERS, *PDEBUG_MODULE_PARAMETERS;
-
-// Scope arguments are function arguments
-// and thus only change when the scope
-// crosses functions.
-#define DEBUG_SCOPE_GROUP_ARGUMENTS 0x00000001
-// Scope locals are locals declared in a particular
-// scope and are only defined within that scope.
-#define DEBUG_SCOPE_GROUP_LOCALS    0x00000002
-// All symbols in the scope.
-#define DEBUG_SCOPE_GROUP_ALL       0x00000003
-
-// Typed data output control flags.
-#define DEBUG_OUTTYPE_DEFAULT              0x00000000
-#define DEBUG_OUTTYPE_NO_INDENT            0x00000001
-#define DEBUG_OUTTYPE_NO_OFFSET            0x00000002
-#define DEBUG_OUTTYPE_VERBOSE              0x00000004
-#define DEBUG_OUTTYPE_COMPACT_OUTPUT       0x00000008
-#define DEBUG_OUTTYPE_RECURSION_LEVEL(Max) (((Max) & 0xf) << 4)
-#define DEBUG_OUTTYPE_ADDRESS_OF_FIELD     0x00010000
-#define DEBUG_OUTTYPE_ADDRESS_AT_END       0x00020000
-#define DEBUG_OUTTYPE_BLOCK_RECURSE        0x00200000
-
-// FindSourceFile flags.
-#define DEBUG_FIND_SOURCE_DEFAULT      0x00000000
-// Returns fully-qualified paths only.  If this
-// is not set the path returned may be relative.
-#define DEBUG_FIND_SOURCE_FULL_PATH    0x00000001
-// Scans all the path elements for a match and
-// returns the one that has the most similarity
-// between the given file and the matching element.
-#define DEBUG_FIND_SOURCE_BEST_MATCH   0x00000002
-// Do not search source server paths.
-#define DEBUG_FIND_SOURCE_NO_SRCSRV    0x00000004
-// Restrict FindSourceFileAndToken to token lookup only.
-#define DEBUG_FIND_SOURCE_TOKEN_LOOKUP 0x00000008
-
-// A special value marking an offset that should not
-// be treated as a valid offset.  This is only used
-// in special situations where it is unlikely that
-// this value would be a valid offset.
-#define DEBUG_INVALID_OFFSET ((ULONG64)-1)
-
-#undef INTERFACE
-#define INTERFACE IDebugSymbols
-DECLARE_INTERFACE_(IDebugSymbols, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugSymbols.
-
-    // Controls the symbol options used during
-    // symbol operations.
-    // Uses the same flags as dbghelps SymSetOptions.
-    STDMETHOD(GetSymbolOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddSymbolOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveSymbolOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetSymbolOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    STDMETHOD(GetNameByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-    // A symbol name may not be unique, particularly
-    // when overloaded functions exist which all
-    // have the same name.  If GetOffsetByName
-    // finds multiple matches for the name it
-    // can return any one of them.  In that
-    // case it will return S_FALSE to indicate
-    // that ambiguity was arbitrarily resolved.
-    // A caller can then use SearchSymbols to
-    // find all of the matches if it wishes to
-    // perform different disambiguation.
-    STDMETHOD(GetOffsetByName)(
-        THIS_
-        __in PCSTR Symbol,
-        __out PULONG64 Offset
-        ) PURE;
-    // GetNearNameByOffset returns symbols
-    // located near the symbol closest to
-    // to the offset, such as the previous
-    // or next symbol.  If Delta is zero it
-    // operates identically to GetNameByOffset.
-    // If Delta is nonzero and such a symbol
-    // does not exist an error is returned.
-    // The next symbol, if one exists, will
-    // always have a higher offset than the
-    // input offset so the displacement is
-    // always negative.  The situation is
-    // reversed for the previous symbol.
-    STDMETHOD(GetNearNameByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __in LONG Delta,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-
-    STDMETHOD(GetLineByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_opt PULONG Line,
-        __out_ecount_opt(FileBufferSize) PSTR FileBuffer,
-        __in ULONG FileBufferSize,
-        __out_opt PULONG FileSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-    STDMETHOD(GetOffsetByLine)(
-        THIS_
-        __in ULONG Line,
-        __in PCSTR File,
-        __out PULONG64 Offset
-        ) PURE;
-
-    // Enumerates the engines list of modules
-    // loaded for the current process.  This may
-    // or may not match the system module list
-    // for the process.  Reload can be used to
-    // synchronize the engines list with the system
-    // if necessary.
-    // Some sessions also track recently unloaded
-    // code modules for help in analyzing failures
-    // where an attempt is made to call unloaded code.
-    // These modules are indexed after the loaded
-    // modules.
-    STDMETHOD(GetNumberModules)(
-        THIS_
-        __out PULONG Loaded,
-        __out PULONG Unloaded
-        ) PURE;
-    STDMETHOD(GetModuleByIndex)(
-        THIS_
-        __in ULONG Index,
-        __out PULONG64 Base
-        ) PURE;
-    // The module name may not be unique.
-    // This method returns the first match.
-    STDMETHOD(GetModuleByModuleName)(
-        THIS_
-        __in PCSTR Name,
-        __in ULONG StartIndex,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-    // Offset can be any offset within
-    // the module extent.  Extents may
-    // not be unique when including unloaded
-    // drivers.  This method returns the
-    // first match.
-    STDMETHOD(GetModuleByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG StartIndex,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-    // If Index is DEBUG_ANY_ID the base address
-    // is used to look up the module instead.
-    STDMETHOD(GetModuleNames)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG64 Base,
-        __out_ecount_opt(ImageNameBufferSize) PSTR ImageNameBuffer,
-        __in ULONG ImageNameBufferSize,
-        __out_opt PULONG ImageNameSize,
-        __out_ecount_opt(ModuleNameBufferSize) PSTR ModuleNameBuffer,
-        __in ULONG ModuleNameBufferSize,
-        __out_opt PULONG ModuleNameSize,
-        __out_ecount_opt(LoadedImageNameBufferSize) PSTR LoadedImageNameBuffer,
-        __in ULONG LoadedImageNameBufferSize,
-        __out_opt PULONG LoadedImageNameSize
-        ) PURE;
-    STDMETHOD(GetModuleParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG64 Bases,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_MODULE_PARAMETERS Params
-        ) PURE;
-    // Looks up the module from a <Module>!<Symbol>
-    // string.
-    STDMETHOD(GetSymbolModule)(
-        THIS_
-        __in PCSTR Symbol,
-        __out PULONG64 Base
-        ) PURE;
-
-    // Returns the string name of a type.
-    STDMETHOD(GetTypeName)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    // Returns the ID for a type name.
-    STDMETHOD(GetTypeId)(
-        THIS_
-        __in ULONG64 Module,
-        __in PCSTR Name,
-        __out PULONG TypeId
-        ) PURE;
-    STDMETHOD(GetTypeSize)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out PULONG Size
-        ) PURE;
-    // Given a type which can contain members
-    // this method returns the offset of a
-    // particular member within the type.
-    // TypeId should give the container type ID
-    // and Field gives the dot-separated path
-    // to the field of interest.
-    STDMETHOD(GetFieldOffset)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in PCSTR Field,
-        __out PULONG Offset
-        ) PURE;
-
-    STDMETHOD(GetSymbolTypeId)(
-        THIS_
-        __in PCSTR Symbol,
-        __out PULONG TypeId,
-        __out_opt PULONG64 Module
-        ) PURE;
-    // As with GetOffsetByName a symbol's
-    // name may be ambiguous.  GetOffsetTypeId
-    // returns the type for the symbol closest
-    // to the given offset and can be used
-    // to avoid ambiguity.
-    STDMETHOD(GetOffsetTypeId)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG TypeId,
-        __out_opt PULONG64 Module
-        ) PURE;
-
-    // Helpers for virtual and physical data
-    // which combine creation of a location with
-    // the actual operation.
-    STDMETHOD(ReadTypedDataVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteTypedDataVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(OutputTypedDataVirtual)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG Flags
-        ) PURE;
-    STDMETHOD(ReadTypedDataPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteTypedDataPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(OutputTypedDataPhysical)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG Flags
-        ) PURE;
-
-    // Function arguments and scope block symbols
-    // can be retrieved relative to currently
-    // executing code.  A caller can provide just
-    // a code offset for scoping purposes and look
-    // up names or the caller can provide a full frame
-    // and look up actual values.  The values for
-    // scoped symbols are best-guess and may or may not
-    // be accurate depending on program optimizations,
-    // the machine architecture, the current point
-    // in the programs execution and so on.
-    // A caller can also provide a complete register
-    // context for setting a scope to a previous
-    // machine state such as a context saved for
-    // an exception.  Usually this isnt necessary
-    // and the current register context is used.
-    STDMETHOD(GetScope)(
-        THIS_
-        __out_opt PULONG64 InstructionOffset,
-        __out_opt PDEBUG_STACK_FRAME ScopeFrame,
-        __out_bcount_opt(ScopeContextSize) PVOID ScopeContext,
-        __in ULONG ScopeContextSize
-        ) PURE;
-    // If ScopeFrame or ScopeContext is non-NULL then
-    // InstructionOffset is ignored.
-    // If ScopeContext is NULL the current
-    // register context is used.
-    // If the scope identified by the given
-    // information is the same as before
-    // SetScope returns S_OK.  If the scope
-    // information changes, such as when the
-    // scope moves between functions or scope
-    // blocks, SetScope returns S_FALSE.
-    STDMETHOD(SetScope)(
-        THIS_
-        __in ULONG64 InstructionOffset,
-        __in_opt PDEBUG_STACK_FRAME ScopeFrame,
-        __in_bcount_opt(ScopeContextSize) PVOID ScopeContext,
-        __in ULONG ScopeContextSize
-        ) PURE;
-    // ResetScope clears the scope information
-    // for situations where scoped symbols
-    // mask global symbols or when resetting
-    // from explicit information to the current
-    // information.
-    STDMETHOD(ResetScope)(
-        THIS
-        ) PURE;
-    // A scope symbol is tied to its particular
-    // scope and only is meaningful within the scope.
-    // The returned group can be updated by passing it back
-    // into the method for lower-cost
-    // incremental updates when stepping.
-    STDMETHOD(GetScopeSymbolGroup)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PDEBUG_SYMBOL_GROUP Update,
-        __out PDEBUG_SYMBOL_GROUP* Symbols
-        ) PURE;
-
-    // Create a new symbol group.
-    STDMETHOD(CreateSymbolGroup)(
-        THIS_
-        __out PDEBUG_SYMBOL_GROUP* Group
-        ) PURE;
-
-    // StartSymbolMatch matches symbol names
-    // against the given pattern using simple
-    // regular expressions.  The search results
-    // are iterated through using GetNextSymbolMatch.
-    // When the caller is done examining results
-    // the match should be freed via EndSymbolMatch.
-    // If the match pattern contains a module name
-    // the search is restricted to a single module.
-    // Pattern matching is only done on symbol names,
-    // not module names.
-    // All active symbol match handles are invalidated
-    // when the set of loaded symbols changes.
-    STDMETHOD(StartSymbolMatch)(
-        THIS_
-        __in PCSTR Pattern,
-        __out PULONG64 Handle
-        ) PURE;
-    // If Buffer is NULL the match does not
-    // advance.
-    STDMETHOD(GetNextSymbolMatch)(
-        THIS_
-        __in ULONG64 Handle,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG MatchSize,
-        __out_opt PULONG64 Offset
-        ) PURE;
-    STDMETHOD(EndSymbolMatch)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-
-    STDMETHOD(Reload)(
-        THIS_
-        __in PCSTR Module
-        ) PURE;
-
-    STDMETHOD(GetSymbolPath)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    STDMETHOD(SetSymbolPath)(
-        THIS_
-        __in PCSTR Path
-        ) PURE;
-    STDMETHOD(AppendSymbolPath)(
-        THIS_
-        __in PCSTR Addition
-        ) PURE;
-
-    // Manipulate the path for executable images.
-    // Some dump files need to load executable images
-    // in order to resolve dump information.  This
-    // path controls where the engine looks for
-    // images.
-    STDMETHOD(GetImagePath)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    STDMETHOD(SetImagePath)(
-        THIS_
-        __in PCSTR Path
-        ) PURE;
-    STDMETHOD(AppendImagePath)(
-        THIS_
-        __in PCSTR Addition
-        ) PURE;
-
-    // Path routines for source file location
-    // methods.
-    STDMETHOD(GetSourcePath)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    // Gets the nth part of the source path.
-    STDMETHOD(GetSourcePathElement)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ElementSize
-        ) PURE;
-    STDMETHOD(SetSourcePath)(
-        THIS_
-        __in PCSTR Path
-        ) PURE;
-    STDMETHOD(AppendSourcePath)(
-        THIS_
-        __in PCSTR Addition
-        ) PURE;
-    // Uses the given file path and the source path
-    // information to try and locate an existing file.
-    // The given file path is merged with elements
-    // of the source path and checked for existence.
-    // If a match is found the element used is returned.
-    // A starting element can be specified to restrict
-    // the search to a subset of the path elements;
-    // this can be useful when checking for multiple
-    // matches along the source path.
-    // The returned element can be 1, indicating
-    // the file was found directly and not on the path.
-    STDMETHOD(FindSourceFile)(
-        THIS_
-        __in ULONG StartElement,
-        __in PCSTR File,
-        __in ULONG Flags,
-        __out_opt PULONG FoundElement,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FoundSize
-        ) PURE;
-    // Retrieves all the line offset information
-    // for a particular source file.  Buffer is
-    // first intialized to DEBUG_INVALID_OFFSET for
-    // every entry.  Then for each piece of line
-    // symbol information Buffer[Line] set to
-    // Lines offset.  This produces a per-line
-    // map of the offsets for the lines of the
-    // given file.  Line numbers are decremented
-    // for the map so Buffer[0] contains the offset
-    // for line number 1.
-    // If there is no line information at all for
-    // the given file the method fails rather
-    // than returning a map of invalid offsets.
-    STDMETHOD(GetSourceFileLineOffsets)(
-        THIS_
-        __in PCSTR File,
-        __out_ecount_opt(BufferLines) PULONG64 Buffer,
-        __in ULONG BufferLines,
-        __out_opt PULONG FileLines
-        ) PURE;
-};
-
-//
-// GetModuleNameString strings.
-//
-
-#define DEBUG_MODNAME_IMAGE        0x00000000
-#define DEBUG_MODNAME_MODULE       0x00000001
-#define DEBUG_MODNAME_LOADED_IMAGE 0x00000002
-#define DEBUG_MODNAME_SYMBOL_FILE  0x00000003
-#define DEBUG_MODNAME_MAPPED_IMAGE 0x00000004
-
-//
-// Type options, used with Get/SetTypeOptions.
-//
-
-// Display PUSHORT and USHORT arrays in Unicode.
-#define DEBUG_TYPEOPTS_UNICODE_DISPLAY    0x00000001
-// Display LONG types in default base instead of decimal.
-#define DEBUG_TYPEOPTS_LONGSTATUS_DISPLAY 0x00000002
-// Display integer types in default base instead of decimal.
-#define DEBUG_TYPEOPTS_FORCERADIX_OUTPUT  0x00000004
-// Search for the type/symbol with largest size when
-// multiple type/symbol match for a given name
-#define DEBUG_TYPEOPTS_MATCH_MAXSIZE      0x00000008
-
-#undef INTERFACE
-#define INTERFACE IDebugSymbols2
-DECLARE_INTERFACE_(IDebugSymbols2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugSymbols.
-
-    // Controls the symbol options used during
-    // symbol operations.
-    // Uses the same flags as dbghelps SymSetOptions.
-    STDMETHOD(GetSymbolOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddSymbolOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveSymbolOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetSymbolOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    STDMETHOD(GetNameByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-    // A symbol name may not be unique, particularly
-    // when overloaded functions exist which all
-    // have the same name.  If GetOffsetByName
-    // finds multiple matches for the name it
-    // can return any one of them.  In that
-    // case it will return S_FALSE to indicate
-    // that ambiguity was arbitrarily resolved.
-    // A caller can then use SearchSymbols to
-    // find all of the matches if it wishes to
-    // perform different disambiguation.
-    STDMETHOD(GetOffsetByName)(
-        THIS_
-        __in PCSTR Symbol,
-        __out PULONG64 Offset
-        ) PURE;
-    // GetNearNameByOffset returns symbols
-    // located near the symbol closest to
-    // to the offset, such as the previous
-    // or next symbol.  If Delta is zero it
-    // operates identically to GetNameByOffset.
-    // If Delta is nonzero and such a symbol
-    // does not exist an error is returned.
-    // The next symbol, if one exists, will
-    // always have a higher offset than the
-    // input offset so the displacement is
-    // always negative.  The situation is
-    // reversed for the previous symbol.
-    STDMETHOD(GetNearNameByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __in LONG Delta,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-
-    STDMETHOD(GetLineByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_opt PULONG Line,
-        __out_ecount_opt(FileBufferSize) PSTR FileBuffer,
-        __in ULONG FileBufferSize,
-        __out_opt PULONG FileSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-    STDMETHOD(GetOffsetByLine)(
-        THIS_
-        __in ULONG Line,
-        __in PCSTR File,
-        __out PULONG64 Offset
-        ) PURE;
-
-    // Enumerates the engines list of modules
-    // loaded for the current process.  This may
-    // or may not match the system module list
-    // for the process.  Reload can be used to
-    // synchronize the engines list with the system
-    // if necessary.
-    // Some sessions also track recently unloaded
-    // code modules for help in analyzing failures
-    // where an attempt is made to call unloaded code.
-    // These modules are indexed after the loaded
-    // modules.
-    STDMETHOD(GetNumberModules)(
-        THIS_
-        __out PULONG Loaded,
-        __out PULONG Unloaded
-        ) PURE;
-    STDMETHOD(GetModuleByIndex)(
-        THIS_
-        __in ULONG Index,
-        __out PULONG64 Base
-        ) PURE;
-    // The module name may not be unique.
-    // This method returns the first match.
-    STDMETHOD(GetModuleByModuleName)(
-        THIS_
-        __in PCSTR Name,
-        __in ULONG StartIndex,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-    // Offset can be any offset within
-    // the module extent.  Extents may
-    // not be unique when including unloaded
-    // drivers.  This method returns the
-    // first match.
-    STDMETHOD(GetModuleByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG StartIndex,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-    // If Index is DEBUG_ANY_ID the base address
-    // is used to look up the module instead.
-    STDMETHOD(GetModuleNames)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG64 Base,
-        __out_ecount_opt(ImageNameBufferSize) PSTR ImageNameBuffer,
-        __in ULONG ImageNameBufferSize,
-        __out_opt PULONG ImageNameSize,
-        __out_ecount_opt(ModuleNameBufferSize) PSTR ModuleNameBuffer,
-        __in ULONG ModuleNameBufferSize,
-        __out_opt PULONG ModuleNameSize,
-        __out_ecount_opt(LoadedImageNameBufferSize) PSTR LoadedImageNameBuffer,
-        __in ULONG LoadedImageNameBufferSize,
-        __out_opt PULONG LoadedImageNameSize
-        ) PURE;
-    STDMETHOD(GetModuleParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG64 Bases,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_MODULE_PARAMETERS Params
-        ) PURE;
-    // Looks up the module from a <Module>!<Symbol>
-    // string.
-    STDMETHOD(GetSymbolModule)(
-        THIS_
-        __in PCSTR Symbol,
-        __out PULONG64 Base
-        ) PURE;
-
-    // Returns the string name of a type.
-    STDMETHOD(GetTypeName)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    // Returns the ID for a type name.
-    STDMETHOD(GetTypeId)(
-        THIS_
-        __in ULONG64 Module,
-        __in PCSTR Name,
-        __out PULONG TypeId
-        ) PURE;
-    STDMETHOD(GetTypeSize)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out PULONG Size
-        ) PURE;
-    // Given a type which can contain members
-    // this method returns the offset of a
-    // particular member within the type.
-    // TypeId should give the container type ID
-    // and Field gives the dot-separated path
-    // to the field of interest.
-    STDMETHOD(GetFieldOffset)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in PCSTR Field,
-        __out PULONG Offset
-        ) PURE;
-
-    STDMETHOD(GetSymbolTypeId)(
-        THIS_
-        __in PCSTR Symbol,
-        __out PULONG TypeId,
-        __out_opt PULONG64 Module
-        ) PURE;
-    // As with GetOffsetByName a symbol's
-    // name may be ambiguous.  GetOffsetTypeId
-    // returns the type for the symbol closest
-    // to the given offset and can be used
-    // to avoid ambiguity.
-    STDMETHOD(GetOffsetTypeId)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG TypeId,
-        __out_opt PULONG64 Module
-        ) PURE;
-
-    // Helpers for virtual and physical data
-    // which combine creation of a location with
-    // the actual operation.
-    STDMETHOD(ReadTypedDataVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteTypedDataVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(OutputTypedDataVirtual)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG Flags
-        ) PURE;
-    STDMETHOD(ReadTypedDataPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteTypedDataPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(OutputTypedDataPhysical)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG Flags
-        ) PURE;
-
-    // Function arguments and scope block symbols
-    // can be retrieved relative to currently
-    // executing code.  A caller can provide just
-    // a code offset for scoping purposes and look
-    // up names or the caller can provide a full frame
-    // and look up actual values.  The values for
-    // scoped symbols are best-guess and may or may not
-    // be accurate depending on program optimizations,
-    // the machine architecture, the current point
-    // in the programs execution and so on.
-    // A caller can also provide a complete register
-    // context for setting a scope to a previous
-    // machine state such as a context saved for
-    // an exception.  Usually this isnt necessary
-    // and the current register context is used.
-    STDMETHOD(GetScope)(
-        THIS_
-        __out_opt PULONG64 InstructionOffset,
-        __out_opt PDEBUG_STACK_FRAME ScopeFrame,
-        __out_bcount_opt(ScopeContextSize) PVOID ScopeContext,
-        __in ULONG ScopeContextSize
-        ) PURE;
-    // If ScopeFrame or ScopeContext is non-NULL then
-    // InstructionOffset is ignored.
-    // If ScopeContext is NULL the current
-    // register context is used.
-    // If the scope identified by the given
-    // information is the same as before
-    // SetScope returns S_OK.  If the scope
-    // information changes, such as when the
-    // scope moves between functions or scope
-    // blocks, SetScope returns S_FALSE.
-    STDMETHOD(SetScope)(
-        THIS_
-        __in ULONG64 InstructionOffset,
-        __in_opt PDEBUG_STACK_FRAME ScopeFrame,
-        __in_bcount_opt(ScopeContextSize) PVOID ScopeContext,
-        __in ULONG ScopeContextSize
-        ) PURE;
-    // ResetScope clears the scope information
-    // for situations where scoped symbols
-    // mask global symbols or when resetting
-    // from explicit information to the current
-    // information.
-    STDMETHOD(ResetScope)(
-        THIS
-        ) PURE;
-    // A scope symbol is tied to its particular
-    // scope and only is meaningful within the scope.
-    // The returned group can be updated by passing it back
-    // into the method for lower-cost
-    // incremental updates when stepping.
-    STDMETHOD(GetScopeSymbolGroup)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PDEBUG_SYMBOL_GROUP Update,
-        __out PDEBUG_SYMBOL_GROUP* Symbols
-        ) PURE;
-
-    // Create a new symbol group.
-    STDMETHOD(CreateSymbolGroup)(
-        THIS_
-        __out PDEBUG_SYMBOL_GROUP* Group
-        ) PURE;
-
-    // StartSymbolMatch matches symbol names
-    // against the given pattern using simple
-    // regular expressions.  The search results
-    // are iterated through using GetNextSymbolMatch.
-    // When the caller is done examining results
-    // the match should be freed via EndSymbolMatch.
-    // If the match pattern contains a module name
-    // the search is restricted to a single module.
-    // Pattern matching is only done on symbol names,
-    // not module names.
-    // All active symbol match handles are invalidated
-    // when the set of loaded symbols changes.
-    STDMETHOD(StartSymbolMatch)(
-        THIS_
-        __in PCSTR Pattern,
-        __out PULONG64 Handle
-        ) PURE;
-    // If Buffer is NULL the match does not
-    // advance.
-    STDMETHOD(GetNextSymbolMatch)(
-        THIS_
-        __in ULONG64 Handle,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG MatchSize,
-        __out_opt PULONG64 Offset
-        ) PURE;
-    STDMETHOD(EndSymbolMatch)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-
-    STDMETHOD(Reload)(
-        THIS_
-        __in PCSTR Module
-        ) PURE;
-
-    STDMETHOD(GetSymbolPath)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    STDMETHOD(SetSymbolPath)(
-        THIS_
-        __in PCSTR Path
-        ) PURE;
-    STDMETHOD(AppendSymbolPath)(
-        THIS_
-        __in PCSTR Addition
-        ) PURE;
-
-    // Manipulate the path for executable images.
-    // Some dump files need to load executable images
-    // in order to resolve dump information.  This
-    // path controls where the engine looks for
-    // images.
-    STDMETHOD(GetImagePath)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    STDMETHOD(SetImagePath)(
-        THIS_
-        __in PCSTR Path
-        ) PURE;
-    STDMETHOD(AppendImagePath)(
-        THIS_
-        __in PCSTR Addition
-        ) PURE;
-
-    // Path routines for source file location
-    // methods.
-    STDMETHOD(GetSourcePath)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    // Gets the nth part of the source path.
-    STDMETHOD(GetSourcePathElement)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ElementSize
-        ) PURE;
-    STDMETHOD(SetSourcePath)(
-        THIS_
-        __in PCSTR Path
-        ) PURE;
-    STDMETHOD(AppendSourcePath)(
-        THIS_
-        __in PCSTR Addition
-        ) PURE;
-    // Uses the given file path and the source path
-    // information to try and locate an existing file.
-    // The given file path is merged with elements
-    // of the source path and checked for existence.
-    // If a match is found the element used is returned.
-    // A starting element can be specified to restrict
-    // the search to a subset of the path elements;
-    // this can be useful when checking for multiple
-    // matches along the source path.
-    // The returned element can be 1, indicating
-    // the file was found directly and not on the path.
-    STDMETHOD(FindSourceFile)(
-        THIS_
-        __in ULONG StartElement,
-        __in PCSTR File,
-        __in ULONG Flags,
-        __out_opt PULONG FoundElement,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FoundSize
-        ) PURE;
-    // Retrieves all the line offset information
-    // for a particular source file.  Buffer is
-    // first intialized to DEBUG_INVALID_OFFSET for
-    // every entry.  Then for each piece of line
-    // symbol information Buffer[Line] set to
-    // Lines offset.  This produces a per-line
-    // map of the offsets for the lines of the
-    // given file.  Line numbers are decremented
-    // for the map so Buffer[0] contains the offset
-    // for line number 1.
-    // If there is no line information at all for
-    // the given file the method fails rather
-    // than returning a map of invalid offsets.
-    STDMETHOD(GetSourceFileLineOffsets)(
-        THIS_
-        __in PCSTR File,
-        __out_ecount_opt(BufferLines) PULONG64 Buffer,
-        __in ULONG BufferLines,
-        __out_opt PULONG FileLines
-        ) PURE;
-
-    // IDebugSymbols2.
-
-    // If Index is DEBUG_ANY_ID the base address
-    // is used to look up the module instead.
-    // Item is specified as in VerQueryValue.
-    // Module version information is only
-    // available for loaded modules and may
-    // not be available in all debug sessions.
-    STDMETHOD(GetModuleVersionInformation)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG64 Base,
-        __in PCSTR Item,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG VerInfoSize
-        ) PURE;
-    // Retrieves any available module name string
-    // such as module name or symbol file name.
-    // If Index is DEBUG_ANY_ID the base address
-    // is used to look up the module instead.
-    // If symbols are deferred an error will
-    // be returned.
-    // E_NOINTERFACE may be returned, indicating
-    // no information exists.
-    STDMETHOD(GetModuleNameString)(
-        THIS_
-        __in ULONG Which,
-        __in ULONG Index,
-        __in ULONG64 Base,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    // Returns the string name of a constant type.
-    STDMETHOD(GetConstantName)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG64 Value,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    // Gets name of a field in a struct
-    // FieldNumber is 0 based index of field in a struct
-    STDMETHOD(GetFieldName)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG FieldIndex,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    // Control options for typed values.
-    STDMETHOD(GetTypeOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddTypeOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveTypeOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetTypeOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-};
-
-//
-// GetModuleBy* flags.
-//
-
-// Scan all modules, loaded and unloaded.
-#define DEBUG_GETMOD_DEFAULT             0x00000000
-// Do not scan loaded modules.
-#define DEBUG_GETMOD_NO_LOADED_MODULES   0x00000001
-// Do not scan unloaded modules.
-#define DEBUG_GETMOD_NO_UNLOADED_MODULES 0x00000002
-
-//
-// AddSyntheticModule flags.
-//
-
-#define DEBUG_ADDSYNTHMOD_DEFAULT 0x00000000
-
-//
-// AddSyntheticSymbol flags.
-//
-
-#define DEBUG_ADDSYNTHSYM_DEFAULT 0x00000000
-
-//
-// OutputSymbolByOffset flags.
-//
-
-// Use the current debugger settings for symbol output.
-#define DEBUG_OUTSYM_DEFAULT            0x00000000
-// Always display the offset in addition to any symbol hit.
-#define DEBUG_OUTSYM_FORCE_OFFSET       0x00000001
-// Display source line information if found.
-#define DEBUG_OUTSYM_SOURCE_LINE        0x00000002
-// Output symbol hits that don't exactly match.
-#define DEBUG_OUTSYM_ALLOW_DISPLACEMENT 0x00000004
-
-//
-// GetFunctionEntryByOffset flags.
-//
-
-#define DEBUG_GETFNENT_DEFAULT        0x00000000
-// The engine provides artificial entries for well-known
-// cases.  This flag limits the entry search to only
-// the raw entries and disables artificial entry lookup.
-#define DEBUG_GETFNENT_RAW_ENTRY_ONLY 0x00000001
-
-typedef struct _DEBUG_MODULE_AND_ID
-{
-    ULONG64 ModuleBase;
-    ULONG64 Id;
-} DEBUG_MODULE_AND_ID, *PDEBUG_MODULE_AND_ID;
-
-#define DEBUG_SOURCE_IS_STATEMENT 0x00000001
-
-//
-// GetSourceEntriesByLine flags.
-//
-
-#define DEBUG_GSEL_DEFAULT         0x00000000
-// Do not allow any extra symbols to load during the search.
-#define DEBUG_GSEL_NO_SYMBOL_LOADS 0x00000001
-// Allow source hits with lower line numbers.
-#define DEBUG_GSEL_ALLOW_LOWER     0x00000002
-// Allow source hits with higher line numbers.
-#define DEBUG_GSEL_ALLOW_HIGHER    0x00000004
-// Only return the nearest hits.
-#define DEBUG_GSEL_NEAREST_ONLY    0x00000008
-
-typedef struct _DEBUG_SYMBOL_SOURCE_ENTRY
-{
-    ULONG64 ModuleBase;
-    ULONG64 Offset;
-    ULONG64 FileNameId;
-    ULONG64 EngineInternal;
-    ULONG Size;
-    ULONG Flags;
-    ULONG FileNameSize;
-    // Line numbers are one-based.
-    // May be DEBUG_ANY_ID if unknown.
-    ULONG StartLine;
-    ULONG EndLine;
-    // Column numbers are one-based byte indices.
-    // May be DEBUG_ANY_ID if unknown.
-    ULONG StartColumn;
-    ULONG EndColumn;
-    ULONG Reserved;
-} DEBUG_SYMBOL_SOURCE_ENTRY, *PDEBUG_SYMBOL_SOURCE_ENTRY;
-
-#undef INTERFACE
-#define INTERFACE IDebugSymbols3
-DECLARE_INTERFACE_(IDebugSymbols3, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugSymbols.
-
-    // Controls the symbol options used during
-    // symbol operations.
-    // Uses the same flags as dbghelps SymSetOptions.
-    STDMETHOD(GetSymbolOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddSymbolOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveSymbolOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetSymbolOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    STDMETHOD(GetNameByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-    // A symbol name may not be unique, particularly
-    // when overloaded functions exist which all
-    // have the same name.  If GetOffsetByName
-    // finds multiple matches for the name it
-    // can return any one of them.  In that
-    // case it will return S_FALSE to indicate
-    // that ambiguity was arbitrarily resolved.
-    // A caller can then use SearchSymbols to
-    // find all of the matches if it wishes to
-    // perform different disambiguation.
-    STDMETHOD(GetOffsetByName)(
-        THIS_
-        __in PCSTR Symbol,
-        __out PULONG64 Offset
-        ) PURE;
-    // GetNearNameByOffset returns symbols
-    // located near the symbol closest to
-    // to the offset, such as the previous
-    // or next symbol.  If Delta is zero it
-    // operates identically to GetNameByOffset.
-    // If Delta is nonzero and such a symbol
-    // does not exist an error is returned.
-    // The next symbol, if one exists, will
-    // always have a higher offset than the
-    // input offset so the displacement is
-    // always negative.  The situation is
-    // reversed for the previous symbol.
-    STDMETHOD(GetNearNameByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __in LONG Delta,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-
-    STDMETHOD(GetLineByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_opt PULONG Line,
-        __out_ecount_opt(FileBufferSize) PSTR FileBuffer,
-        __in ULONG FileBufferSize,
-        __out_opt PULONG FileSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-    STDMETHOD(GetOffsetByLine)(
-        THIS_
-        __in ULONG Line,
-        __in PCSTR File,
-        __out PULONG64 Offset
-        ) PURE;
-
-    // Enumerates the engines list of modules
-    // loaded for the current process.  This may
-    // or may not match the system module list
-    // for the process.  Reload can be used to
-    // synchronize the engines list with the system
-    // if necessary.
-    // Some sessions also track recently unloaded
-    // code modules for help in analyzing failures
-    // where an attempt is made to call unloaded code.
-    // These modules are indexed after the loaded
-    // modules.
-    STDMETHOD(GetNumberModules)(
-        THIS_
-        __out PULONG Loaded,
-        __out PULONG Unloaded
-        ) PURE;
-    STDMETHOD(GetModuleByIndex)(
-        THIS_
-        __in ULONG Index,
-        __out PULONG64 Base
-        ) PURE;
-    // The module name may not be unique.
-    // This method returns the first match.
-    STDMETHOD(GetModuleByModuleName)(
-        THIS_
-        __in PCSTR Name,
-        __in ULONG StartIndex,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-    // Offset can be any offset within
-    // the module extent.  Extents may
-    // not be unique when including unloaded
-    // drivers.  This method returns the
-    // first match.
-    STDMETHOD(GetModuleByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG StartIndex,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-    // If Index is DEBUG_ANY_ID the base address
-    // is used to look up the module instead.
-    STDMETHOD(GetModuleNames)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG64 Base,
-        __out_ecount_opt(ImageNameBufferSize) PSTR ImageNameBuffer,
-        __in ULONG ImageNameBufferSize,
-        __out_opt PULONG ImageNameSize,
-        __out_ecount_opt(ModuleNameBufferSize) PSTR ModuleNameBuffer,
-        __in ULONG ModuleNameBufferSize,
-        __out_opt PULONG ModuleNameSize,
-        __out_ecount_opt(LoadedImageNameBufferSize) PSTR LoadedImageNameBuffer,
-        __in ULONG LoadedImageNameBufferSize,
-        __out_opt PULONG LoadedImageNameSize
-        ) PURE;
-    STDMETHOD(GetModuleParameters)(
-        THIS_
-        __in ULONG Count,
-        __in_ecount_opt(Count) PULONG64 Bases,
-        __in ULONG Start,
-        __out_ecount(Count) PDEBUG_MODULE_PARAMETERS Params
-        ) PURE;
-    // Looks up the module from a <Module>!<Symbol>
-    // string.
-    STDMETHOD(GetSymbolModule)(
-        THIS_
-        __in PCSTR Symbol,
-        __out PULONG64 Base
-        ) PURE;
-
-    // Returns the string name of a type.
-    STDMETHOD(GetTypeName)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    // Returns the ID for a type name.
-    STDMETHOD(GetTypeId)(
-        THIS_
-        __in ULONG64 Module,
-        __in PCSTR Name,
-        __out PULONG TypeId
-        ) PURE;
-    STDMETHOD(GetTypeSize)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out PULONG Size
-        ) PURE;
-    // Given a type which can contain members
-    // this method returns the offset of a
-    // particular member within the type.
-    // TypeId should give the container type ID
-    // and Field gives the dot-separated path
-    // to the field of interest.
-    STDMETHOD(GetFieldOffset)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in PCSTR Field,
-        __out PULONG Offset
-        ) PURE;
-
-    STDMETHOD(GetSymbolTypeId)(
-        THIS_
-        __in PCSTR Symbol,
-        __out PULONG TypeId,
-        __out_opt PULONG64 Module
-        ) PURE;
-    // As with GetOffsetByName a symbol's
-    // name may be ambiguous.  GetOffsetTypeId
-    // returns the type for the symbol closest
-    // to the given offset and can be used
-    // to avoid ambiguity.
-    STDMETHOD(GetOffsetTypeId)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG TypeId,
-        __out_opt PULONG64 Module
-        ) PURE;
-
-    // Helpers for virtual and physical data
-    // which combine creation of a location with
-    // the actual operation.
-    STDMETHOD(ReadTypedDataVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteTypedDataVirtual)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(OutputTypedDataVirtual)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG Flags
-        ) PURE;
-    STDMETHOD(ReadTypedDataPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesRead
-        ) PURE;
-    STDMETHOD(WriteTypedDataPhysical)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in_bcount(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BytesWritten
-        ) PURE;
-    STDMETHOD(OutputTypedDataPhysical)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 Offset,
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG Flags
-        ) PURE;
-
-    // Function arguments and scope block symbols
-    // can be retrieved relative to currently
-    // executing code.  A caller can provide just
-    // a code offset for scoping purposes and look
-    // up names or the caller can provide a full frame
-    // and look up actual values.  The values for
-    // scoped symbols are best-guess and may or may not
-    // be accurate depending on program optimizations,
-    // the machine architecture, the current point
-    // in the programs execution and so on.
-    // A caller can also provide a complete register
-    // context for setting a scope to a previous
-    // machine state such as a context saved for
-    // an exception.  Usually this isnt necessary
-    // and the current register context is used.
-    STDMETHOD(GetScope)(
-        THIS_
-        __out_opt PULONG64 InstructionOffset,
-        __out_opt PDEBUG_STACK_FRAME ScopeFrame,
-        __out_bcount_opt(ScopeContextSize) PVOID ScopeContext,
-        __in ULONG ScopeContextSize
-        ) PURE;
-    // If ScopeFrame or ScopeContext is non-NULL then
-    // InstructionOffset is ignored.
-    // If ScopeContext is NULL the current
-    // register context is used.
-    // If the scope identified by the given
-    // information is the same as before
-    // SetScope returns S_OK.  If the scope
-    // information changes, such as when the
-    // scope moves between functions or scope
-    // blocks, SetScope returns S_FALSE.
-    STDMETHOD(SetScope)(
-        THIS_
-        __in ULONG64 InstructionOffset,
-        __in_opt PDEBUG_STACK_FRAME ScopeFrame,
-        __in_bcount_opt(ScopeContextSize) PVOID ScopeContext,
-        __in ULONG ScopeContextSize
-        ) PURE;
-    // ResetScope clears the scope information
-    // for situations where scoped symbols
-    // mask global symbols or when resetting
-    // from explicit information to the current
-    // information.
-    STDMETHOD(ResetScope)(
-        THIS
-        ) PURE;
-    // A scope symbol is tied to its particular
-    // scope and only is meaningful within the scope.
-    // The returned group can be updated by passing it back
-    // into the method for lower-cost
-    // incremental updates when stepping.
-    STDMETHOD(GetScopeSymbolGroup)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PDEBUG_SYMBOL_GROUP Update,
-        __out PDEBUG_SYMBOL_GROUP* Symbols
-        ) PURE;
-
-    // Create a new symbol group.
-    STDMETHOD(CreateSymbolGroup)(
-        THIS_
-        __out PDEBUG_SYMBOL_GROUP* Group
-        ) PURE;
-
-    // StartSymbolMatch matches symbol names
-    // against the given pattern using simple
-    // regular expressions.  The search results
-    // are iterated through using GetNextSymbolMatch.
-    // When the caller is done examining results
-    // the match should be freed via EndSymbolMatch.
-    // If the match pattern contains a module name
-    // the search is restricted to a single module.
-    // Pattern matching is only done on symbol names,
-    // not module names.
-    // All active symbol match handles are invalidated
-    // when the set of loaded symbols changes.
-    STDMETHOD(StartSymbolMatch)(
-        THIS_
-        __in PCSTR Pattern,
-        __out PULONG64 Handle
-        ) PURE;
-    // If Buffer is NULL the match does not
-    // advance.
-    STDMETHOD(GetNextSymbolMatch)(
-        THIS_
-        __in ULONG64 Handle,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG MatchSize,
-        __out_opt PULONG64 Offset
-        ) PURE;
-    STDMETHOD(EndSymbolMatch)(
-        THIS_
-        __in ULONG64 Handle
-        ) PURE;
-
-    STDMETHOD(Reload)(
-        THIS_
-        __in PCSTR Module
-        ) PURE;
-
-    STDMETHOD(GetSymbolPath)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    STDMETHOD(SetSymbolPath)(
-        THIS_
-        __in PCSTR Path
-        ) PURE;
-    STDMETHOD(AppendSymbolPath)(
-        THIS_
-        __in PCSTR Addition
-        ) PURE;
-
-    // Manipulate the path for executable images.
-    // Some dump files need to load executable images
-    // in order to resolve dump information.  This
-    // path controls where the engine looks for
-    // images.
-    STDMETHOD(GetImagePath)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    STDMETHOD(SetImagePath)(
-        THIS_
-        __in PCSTR Path
-        ) PURE;
-    STDMETHOD(AppendImagePath)(
-        THIS_
-        __in PCSTR Addition
-        ) PURE;
-
-    // Path routines for source file location
-    // methods.
-    STDMETHOD(GetSourcePath)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    // Gets the nth part of the source path.
-    STDMETHOD(GetSourcePathElement)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ElementSize
-        ) PURE;
-    STDMETHOD(SetSourcePath)(
-        THIS_
-        __in PCSTR Path
-        ) PURE;
-    STDMETHOD(AppendSourcePath)(
-        THIS_
-        __in PCSTR Addition
-        ) PURE;
-    // Uses the given file path and the source path
-    // information to try and locate an existing file.
-    // The given file path is merged with elements
-    // of the source path and checked for existence.
-    // If a match is found the element used is returned.
-    // A starting element can be specified to restrict
-    // the search to a subset of the path elements;
-    // this can be useful when checking for multiple
-    // matches along the source path.
-    // The returned element can be 1, indicating
-    // the file was found directly and not on the path.
-    STDMETHOD(FindSourceFile)(
-        THIS_
-        __in ULONG StartElement,
-        __in PCSTR File,
-        __in ULONG Flags,
-        __out_opt PULONG FoundElement,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FoundSize
-        ) PURE;
-    // Retrieves all the line offset information
-    // for a particular source file.  Buffer is
-    // first intialized to DEBUG_INVALID_OFFSET for
-    // every entry.  Then for each piece of line
-    // symbol information Buffer[Line] set to
-    // Lines offset.  This produces a per-line
-    // map of the offsets for the lines of the
-    // given file.  Line numbers are decremented
-    // for the map so Buffer[0] contains the offset
-    // for line number 1.
-    // If there is no line information at all for
-    // the given file the method fails rather
-    // than returning a map of invalid offsets.
-    STDMETHOD(GetSourceFileLineOffsets)(
-        THIS_
-        __in PCSTR File,
-        __out_ecount_opt(BufferLines) PULONG64 Buffer,
-        __in ULONG BufferLines,
-        __out_opt PULONG FileLines
-        ) PURE;
-
-    // IDebugSymbols2.
-
-    // If Index is DEBUG_ANY_ID the base address
-    // is used to look up the module instead.
-    // Item is specified as in VerQueryValue.
-    // Module version information is only
-    // available for loaded modules and may
-    // not be available in all debug sessions.
-    STDMETHOD(GetModuleVersionInformation)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG64 Base,
-        __in PCSTR Item,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG VerInfoSize
-        ) PURE;
-    // Retrieves any available module name string
-    // such as module name or symbol file name.
-    // If Index is DEBUG_ANY_ID the base address
-    // is used to look up the module instead.
-    // If symbols are deferred an error will
-    // be returned.
-    // E_NOINTERFACE may be returned, indicating
-    // no information exists.
-    STDMETHOD(GetModuleNameString)(
-        THIS_
-        __in ULONG Which,
-        __in ULONG Index,
-        __in ULONG64 Base,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    // Returns the string name of a constant type.
-    STDMETHOD(GetConstantName)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG64 Value,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    // Gets name of a field in a struct
-    // FieldNumber is 0 based index of field in a struct
-    STDMETHOD(GetFieldName)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG FieldIndex,
-        __out_ecount_opt(NameBufferSize) PSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    // Control options for typed values.
-    STDMETHOD(GetTypeOptions)(
-        THIS_
-        __out PULONG Options
-        ) PURE;
-    STDMETHOD(AddTypeOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(RemoveTypeOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-    STDMETHOD(SetTypeOptions)(
-        THIS_
-        __in ULONG Options
-        ) PURE;
-
-    // IDebugSymbols3.
-
-    STDMETHOD(GetNameByOffsetWide)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_ecount_opt(NameBufferSize) PWSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-    STDMETHOD(GetOffsetByNameWide)(
-        THIS_
-        __in PCWSTR Symbol,
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetNearNameByOffsetWide)(
-        THIS_
-        __in ULONG64 Offset,
-        __in LONG Delta,
-        __out_ecount_opt(NameBufferSize) PWSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-
-    STDMETHOD(GetLineByOffsetWide)(
-        THIS_
-        __in ULONG64 Offset,
-        __out_opt PULONG Line,
-        __out_ecount_opt(FileBufferSize) PWSTR FileBuffer,
-        __in ULONG FileBufferSize,
-        __out_opt PULONG FileSize,
-        __out_opt PULONG64 Displacement
-        ) PURE;
-    STDMETHOD(GetOffsetByLineWide)(
-        THIS_
-        __in ULONG Line,
-        __in PCWSTR File,
-        __out PULONG64 Offset
-        ) PURE;
-
-    STDMETHOD(GetModuleByModuleNameWide)(
-        THIS_
-        __in PCWSTR Name,
-        __in ULONG StartIndex,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-    STDMETHOD(GetSymbolModuleWide)(
-        THIS_
-        __in PCWSTR Symbol,
-        __out PULONG64 Base
-        ) PURE;
-
-    STDMETHOD(GetTypeNameWide)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __out_ecount_opt(NameBufferSize) PWSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-    // Returns the ID for a type name.
-    STDMETHOD(GetTypeIdWide)(
-        THIS_
-        __in ULONG64 Module,
-        __in PCWSTR Name,
-        __out PULONG TypeId
-        ) PURE;
-    STDMETHOD(GetFieldOffsetWide)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in PCWSTR Field,
-        __out PULONG Offset
-        ) PURE;
-
-    STDMETHOD(GetSymbolTypeIdWide)(
-        THIS_
-        __in PCWSTR Symbol,
-        __out PULONG TypeId,
-        __out_opt PULONG64 Module
-        ) PURE;
-
-    STDMETHOD(GetScopeSymbolGroup2)(
-        THIS_
-        __in ULONG Flags,
-        __in_opt PDEBUG_SYMBOL_GROUP2 Update,
-        __out PDEBUG_SYMBOL_GROUP2* Symbols
-        ) PURE;
-
-    STDMETHOD(CreateSymbolGroup2)(
-        THIS_
-        __out PDEBUG_SYMBOL_GROUP2* Group
-        ) PURE;
-
-    STDMETHOD(StartSymbolMatchWide)(
-        THIS_
-        __in PCWSTR Pattern,
-        __out PULONG64 Handle
-        ) PURE;
-    STDMETHOD(GetNextSymbolMatchWide)(
-        THIS_
-        __in ULONG64 Handle,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG MatchSize,
-        __out_opt PULONG64 Offset
-        ) PURE;
-
-    STDMETHOD(ReloadWide)(
-        THIS_
-        __in PCWSTR Module
-        ) PURE;
-
-    STDMETHOD(GetSymbolPathWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    STDMETHOD(SetSymbolPathWide)(
-        THIS_
-        __in PCWSTR Path
-        ) PURE;
-    STDMETHOD(AppendSymbolPathWide)(
-        THIS_
-        __in PCWSTR Addition
-        ) PURE;
-
-    STDMETHOD(GetImagePathWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    STDMETHOD(SetImagePathWide)(
-        THIS_
-        __in PCWSTR Path
-        ) PURE;
-    STDMETHOD(AppendImagePathWide)(
-        THIS_
-        __in PCWSTR Addition
-        ) PURE;
-
-    STDMETHOD(GetSourcePathWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG PathSize
-        ) PURE;
-    STDMETHOD(GetSourcePathElementWide)(
-        THIS_
-        __in ULONG Index,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ElementSize
-        ) PURE;
-    STDMETHOD(SetSourcePathWide)(
-        THIS_
-        __in PCWSTR Path
-        ) PURE;
-    STDMETHOD(AppendSourcePathWide)(
-        THIS_
-        __in PCWSTR Addition
-        ) PURE;
-    STDMETHOD(FindSourceFileWide)(
-        THIS_
-        __in ULONG StartElement,
-        __in PCWSTR File,
-        __in ULONG Flags,
-        __out_opt PULONG FoundElement,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG FoundSize
-        ) PURE;
-    STDMETHOD(GetSourceFileLineOffsetsWide)(
-        THIS_
-        __in PCWSTR File,
-        __out_ecount_opt(BufferLines) PULONG64 Buffer,
-        __in ULONG BufferLines,
-        __out_opt PULONG FileLines
-        ) PURE;
-
-    STDMETHOD(GetModuleVersionInformationWide)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG64 Base,
-        __in PCWSTR Item,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG VerInfoSize
-        ) PURE;
-    STDMETHOD(GetModuleNameStringWide)(
-        THIS_
-        __in ULONG Which,
-        __in ULONG Index,
-        __in ULONG64 Base,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    STDMETHOD(GetConstantNameWide)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG64 Value,
-        __out_ecount_opt(NameBufferSize) PWSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    STDMETHOD(GetFieldNameWide)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG TypeId,
-        __in ULONG FieldIndex,
-        __out_ecount_opt(NameBufferSize) PWSTR NameBuffer,
-        __in ULONG NameBufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    // Returns S_OK if the engine is using managed
-    // debugging support when retriving information
-    // for the given module.  This can be expensive
-    // to check.
-    STDMETHOD(IsManagedModule)(
-        THIS_
-        __in ULONG Index,
-        __in ULONG64 Base
-        ) PURE;
-
-    // The module name may not be unique.
-    // This method returns the first match.
-    STDMETHOD(GetModuleByModuleName2)(
-        THIS_
-        __in PCSTR Name,
-        __in ULONG StartIndex,
-        __in ULONG Flags,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-    STDMETHOD(GetModuleByModuleName2Wide)(
-        THIS_
-        __in PCWSTR Name,
-        __in ULONG StartIndex,
-        __in ULONG Flags,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-    // Offset can be any offset within
-    // the module extent.  Extents may
-    // not be unique when including unloaded
-    // drivers.  This method returns the
-    // first match.
-    STDMETHOD(GetModuleByOffset2)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG StartIndex,
-        __in ULONG Flags,
-        __out_opt PULONG Index,
-        __out_opt PULONG64 Base
-        ) PURE;
-
-    // A caller can create artificial loaded modules in
-    // the engine's module list if desired.
-    // These modules only serve as names for
-    // a region of addresses.  They cannot have
-    // real symbols loaded for them; if that
-    // is desired Reload can be used with explicit
-    // parameters to create a true module entry.
-    // The region must not be in use by any other
-    // module.
-    // A general reload will discard any synthetic modules.
-    STDMETHOD(AddSyntheticModule)(
-        THIS_
-        __in ULONG64 Base,
-        __in ULONG Size,
-        __in PCSTR ImagePath,
-        __in PCSTR ModuleName,
-        __in ULONG Flags
-        ) PURE;
-    STDMETHOD(AddSyntheticModuleWide)(
-        THIS_
-        __in ULONG64 Base,
-        __in ULONG Size,
-        __in PCWSTR ImagePath,
-        __in PCWSTR ModuleName,
-        __in ULONG Flags
-        ) PURE;
-    STDMETHOD(RemoveSyntheticModule)(
-        THIS_
-        __in ULONG64 Base
-        ) PURE;
-
-    // Modify the current frame used for scoping.
-    // This is equivalent to the '.frame' command.
-    STDMETHOD(GetCurrentScopeFrameIndex)(
-        THIS_
-        __out PULONG Index
-        ) PURE;
-    STDMETHOD(SetScopeFrameByIndex)(
-        THIS_
-        __in ULONG Index
-        ) PURE;
-
-    // Recovers JIT_DEBUG_INFO information at the given
-    // address from the debuggee and sets current
-    // debugger scope context from it.
-    // Equivalent to '.jdinfo' command.
-    STDMETHOD(SetScopeFromJitDebugInfo)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG64 InfoOffset
-        ) PURE;
-
-    // Switches the current debugger scope to
-    // the stored event information.
-    // Equivalent to the '.ecxr' command.
-    STDMETHOD(SetScopeFromStoredEvent)(
-        THIS
-        ) PURE;
-
-    // Takes the first symbol hit and outputs it.
-    // Controlled with DEBUG_OUTSYM_* flags.
-    STDMETHOD(OutputSymbolByOffset)(
-        THIS_
-        __in ULONG OutputControl,
-        __in ULONG Flags,
-        __in ULONG64 Offset
-        ) PURE;
-
-    // Function entry information for a particular
-    // piece of code can be retrieved by this method.
-    // The actual data returned is system-dependent.
-    STDMETHOD(GetFunctionEntryByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_bcount_opt(BufferSize) PVOID Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG BufferNeeded
-        ) PURE;
-
-    // Given a type which can contain members
-    // this method returns the type ID and offset of a
-    // particular member within the type.
-    // Field gives the dot-separated path
-    // to the field of interest.
-    STDMETHOD(GetFieldTypeAndOffset)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG ContainerTypeId,
-        __in PCSTR Field,
-        __out_opt PULONG FieldTypeId,
-        __out_opt PULONG Offset
-        ) PURE;
-    STDMETHOD(GetFieldTypeAndOffsetWide)(
-        THIS_
-        __in ULONG64 Module,
-        __in ULONG ContainerTypeId,
-        __in PCWSTR Field,
-        __out_opt PULONG FieldTypeId,
-        __out_opt PULONG Offset
-        ) PURE;
-
-    // Artificial symbols can be created in any
-    // existing module as a way to name an address.
-    // The address must not already have symbol
-    // information.
-    // A reload will discard synthetic symbols
-    // for all address regions reloaded.
-    STDMETHOD(AddSyntheticSymbol)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Size,
-        __in PCSTR Name,
-        __in ULONG Flags,
-        __out_opt PDEBUG_MODULE_AND_ID Id
-        ) PURE;
-    STDMETHOD(AddSyntheticSymbolWide)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Size,
-        __in PCWSTR Name,
-        __in ULONG Flags,
-        __out_opt PDEBUG_MODULE_AND_ID Id
-        ) PURE;
-    STDMETHOD(RemoveSyntheticSymbol)(
-        THIS_
-        __in PDEBUG_MODULE_AND_ID Id
-        ) PURE;
-
-    // The following methods can return multiple
-    // hits for symbol lookups to allow for all
-    // possible hits to be returned.
-    STDMETHOD(GetSymbolEntriesByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_ecount_opt(IdsCount) PDEBUG_MODULE_AND_ID Ids,
-        __out_ecount_opt(IdsCount) PULONG64 Displacements,
-        __in ULONG IdsCount,
-        __out_opt PULONG Entries
-        ) PURE;
-    STDMETHOD(GetSymbolEntriesByName)(
-        THIS_
-        __in PCSTR Symbol,
-        __in ULONG Flags,
-        __out_ecount_opt(IdsCount) PDEBUG_MODULE_AND_ID Ids,
-        __in ULONG IdsCount,
-        __out_opt PULONG Entries
-        ) PURE;
-    STDMETHOD(GetSymbolEntriesByNameWide)(
-        THIS_
-        __in PCWSTR Symbol,
-        __in ULONG Flags,
-        __out_ecount_opt(IdsCount) PDEBUG_MODULE_AND_ID Ids,
-        __in ULONG IdsCount,
-        __out_opt PULONG Entries
-        ) PURE;
-    // Symbol lookup by managed metadata token.
-    STDMETHOD(GetSymbolEntryByToken)(
-        THIS_
-        __in ULONG64 ModuleBase,
-        __in ULONG Token,
-        __out PDEBUG_MODULE_AND_ID Id
-        ) PURE;
-
-    // Retrieves full symbol entry information from an ID.
-    STDMETHOD(GetSymbolEntryInformation)(
-        THIS_
-        __in PDEBUG_MODULE_AND_ID Id,
-        __out PDEBUG_SYMBOL_ENTRY Info
-        ) PURE;
-    STDMETHOD(GetSymbolEntryString)(
-        THIS_
-        __in PDEBUG_MODULE_AND_ID Id,
-        __in ULONG Which,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-    STDMETHOD(GetSymbolEntryStringWide)(
-        THIS_
-        __in PDEBUG_MODULE_AND_ID Id,
-        __in ULONG Which,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-    // Returns all known memory regions associated
-    // with the given symbol.  Simple symbols will
-    // have a single region starting from their base.
-    // More complicated regions, such as functions
-    // with multiple code areas, can have an arbitrarily
-    // large number of regions.
-    // The quality of information returned is highly
-    // dependent on the symbolic information availble.
-    STDMETHOD(GetSymbolEntryOffsetRegions)(
-        THIS_
-        __in PDEBUG_MODULE_AND_ID Id,
-        __in ULONG Flags,
-        __out_ecount_opt(RegionsCount) PDEBUG_OFFSET_REGION Regions,
-        __in ULONG RegionsCount,
-        __out_opt PULONG RegionsAvail
-        ) PURE;
-
-    // This method allows navigating within the
-    // symbol entry hierarchy.
-    STDMETHOD(GetSymbolEntryBySymbolEntry)(
-        THIS_
-        __in PDEBUG_MODULE_AND_ID FromId,
-        __in ULONG Flags,
-        __out PDEBUG_MODULE_AND_ID ToId
-        ) PURE;
-
-    // The following methods can return multiple
-    // hits for source lookups to allow for all
-    // possible hits to be returned.
-    STDMETHOD(GetSourceEntriesByOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __in ULONG Flags,
-        __out_ecount_opt(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
-        __in ULONG EntriesCount,
-        __out_opt PULONG EntriesAvail
-        ) PURE;
-    STDMETHOD(GetSourceEntriesByLine)(
-        THIS_
-        __in ULONG Line,
-        __in PCSTR File,
-        __in ULONG Flags,
-        __out_ecount_opt(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
-        __in ULONG EntriesCount,
-        __out_opt PULONG EntriesAvail
-        ) PURE;
-    STDMETHOD(GetSourceEntriesByLineWide)(
-        THIS_
-        __in ULONG Line,
-        __in PCWSTR File,
-        __in ULONG Flags,
-        __out_ecount_opt(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
-        __in ULONG EntriesCount,
-        __out_opt PULONG EntriesAvail
-        ) PURE;
-
-    STDMETHOD(GetSourceEntryString)(
-        THIS_
-        __in PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
-        __in ULONG Which,
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-    STDMETHOD(GetSourceEntryStringWide)(
-        THIS_
-        __in PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
-        __in ULONG Which,
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG StringSize
-        ) PURE;
-    // Returns all known memory regions associated
-    // with the given source entry.  As with
-    // GetSymbolEntryOffsetRegions the regions available
-    // are variable.
-    STDMETHOD(GetSourceEntryOffsetRegions)(
-        THIS_
-        __in PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
-        __in ULONG Flags,
-        __out_ecount_opt(RegionsCount) PDEBUG_OFFSET_REGION Regions,
-        __in ULONG RegionsCount,
-        __out_opt PULONG RegionsAvail
-        ) PURE;
-
-    // This method allows navigating within the
-    // source entries.
-    STDMETHOD(GetSourceEntryBySourceEntry)(
-        THIS_
-        __in PDEBUG_SYMBOL_SOURCE_ENTRY FromEntry,
-        __in ULONG Flags,
-        __out PDEBUG_SYMBOL_SOURCE_ENTRY ToEntry
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// IDebugSystemObjects
-//
-//----------------------------------------------------------------------------
-
-#undef INTERFACE
-#define INTERFACE IDebugSystemObjects
-DECLARE_INTERFACE_(IDebugSystemObjects, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugSystemObjects.
-
-    // In user mode debugging the debugger
-    // tracks all threads and processes and
-    // enumerates them through the following
-    // methods.  When enumerating threads
-    // the threads are enumerated for the current
-    // process.
-    // Kernel mode debugging currently is
-    // limited to enumerating only the threads
-    // assigned to processors, not all of
-    // the threads in the system.  Process
-    // enumeration is limited to a single
-    // virtual process representing kernel space.
-
-    // Returns the ID of the thread on which
-    // the last event occurred.
-    STDMETHOD(GetEventThread)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetEventProcess)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-
-    // Controls implicit thread used by the
-    // debug engine.  The debuggers current
-    // thread is just a piece of data held
-    // by the debugger for calls which use
-    // thread-specific information.  In those
-    // calls the debuggers current thread is used.
-    // The debuggers current thread is not related
-    // to any system thread attribute.
-    // IDs for threads are small integer IDs
-    // maintained by the engine.  They are not
-    // related to system thread IDs.
-    STDMETHOD(GetCurrentThreadId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(SetCurrentThreadId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-    // The current process is the process
-    // that owns the current thread.
-    STDMETHOD(GetCurrentProcessId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    // Setting the current process automatically
-    // sets the current thread to the thread that
-    // was last current in that process.
-    STDMETHOD(SetCurrentProcessId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-
-    // Gets the number of threads in the current process.
-    STDMETHOD(GetNumberThreads)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // Gets thread count information for all processes
-    // and the largest number of threads in a single process.
-    STDMETHOD(GetTotalNumberThreads)(
-        THIS_
-        __out PULONG Total,
-        __out PULONG LargestProcess
-        ) PURE;
-    STDMETHOD(GetThreadIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount_opt(Count) PULONG Ids,
-        __out_ecount_opt(Count) PULONG SysIds
-        ) PURE;
-    // Gets the debugger ID for the thread
-    // currently running on the given
-    // processor.  Only works in kernel
-    // debugging.
-    STDMETHOD(GetThreadIdByProcessor)(
-        THIS_
-        __in ULONG Processor,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current threads
-    // system data structure.  When kernel debugging
-    // this is the offset of the KTHREAD.
-    // When user debugging it is the offset
-    // of the current TEB.
-    STDMETHOD(GetCurrentThreadDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger thread ID for the given
-    // system thread data structure.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByDataOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current threads
-    // TEB.  In user mode this is equivalent to
-    // the threads data offset.
-    STDMETHOD(GetCurrentThreadTeb)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger thread ID for the given TEB.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByTeb)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the system unique ID for the current thread.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetCurrentThreadSystemId)(
-        THIS_
-        __out PULONG SysId
-        ) PURE;
-    // Looks up a debugger thread ID for the given
-    // system thread ID.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdBySystemId)(
-        THIS_
-        __in ULONG SysId,
-        __out PULONG Id
-        ) PURE;
-    // Returns the handle of the current thread.
-    // In kernel mode the value returned is the
-    // index of the processor the thread is
-    // executing on plus one.
-    STDMETHOD(GetCurrentThreadHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    // Looks up a debugger thread ID for the given handle.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByHandle)(
-        THIS_
-        __in ULONG64 Handle,
-        __out PULONG Id
-        ) PURE;
-
-    // Currently kernel mode sessions will only have
-    // a single process representing kernel space.
-    STDMETHOD(GetNumberProcesses)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetProcessIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount_opt(Count) PULONG Ids,
-        __out_ecount_opt(Count) PULONG SysIds
-        ) PURE;
-    // Returns the offset of the current processs
-    // system data structure.  When kernel debugging
-    // this is the offset of the KPROCESS of
-    // the process that owns the current thread.
-    // When user debugging it is the offset
-    // of the current PEB.
-    STDMETHOD(GetCurrentProcessDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger process ID for the given
-    // system process data structure.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdByDataOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current processs
-    // PEB.  In user mode this is equivalent to
-    // the processs data offset.
-    STDMETHOD(GetCurrentProcessPeb)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger process ID for the given PEB.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdByPeb)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the system unique ID for the current process.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetCurrentProcessSystemId)(
-        THIS_
-        __out PULONG SysId
-        ) PURE;
-    // Looks up a debugger process ID for the given
-    // system process ID.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdBySystemId)(
-        THIS_
-        __in ULONG SysId,
-        __out PULONG Id
-        ) PURE;
-    // Returns the handle of the current process.
-    // In kernel mode this is the kernel processs
-    // artificial handle used for symbol operations
-    // and so can only be used with dbghelp APIs.
-    STDMETHOD(GetCurrentProcessHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    // Looks up a debugger process ID for the given handle.
-    STDMETHOD(GetProcessIdByHandle)(
-        THIS_
-        __in ULONG64 Handle,
-        __out PULONG Id
-        ) PURE;
-    // Retrieve the name of the executable loaded
-    // in the process.  This may fail if no executable
-    // was identified.
-    STDMETHOD(GetCurrentProcessExecutableName)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ExeSize
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugSystemObjects2
-DECLARE_INTERFACE_(IDebugSystemObjects2, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugSystemObjects.
-
-    // In user mode debugging the debugger
-    // tracks all threads and processes and
-    // enumerates them through the following
-    // methods.  When enumerating threads
-    // the threads are enumerated for the current
-    // process.
-    // Kernel mode debugging currently is
-    // limited to enumerating only the threads
-    // assigned to processors, not all of
-    // the threads in the system.  Process
-    // enumeration is limited to a single
-    // virtual process representing kernel space.
-
-    // Returns the ID of the thread on which
-    // the last event occurred.
-    STDMETHOD(GetEventThread)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetEventProcess)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-
-    // Controls implicit thread used by the
-    // debug engine.  The debuggers current
-    // thread is just a piece of data held
-    // by the debugger for calls which use
-    // thread-specific information.  In those
-    // calls the debuggers current thread is used.
-    // The debuggers current thread is not related
-    // to any system thread attribute.
-    // IDs for threads are small integer IDs
-    // maintained by the engine.  They are not
-    // related to system thread IDs.
-    STDMETHOD(GetCurrentThreadId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(SetCurrentThreadId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-    // The current process is the process
-    // that owns the current thread.
-    STDMETHOD(GetCurrentProcessId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    // Setting the current process automatically
-    // sets the current thread to the thread that
-    // was last current in that process.
-    STDMETHOD(SetCurrentProcessId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-
-    // Gets the number of threads in the current process.
-    STDMETHOD(GetNumberThreads)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // Gets thread count information for all processes
-    // and the largest number of threads in a single process.
-    STDMETHOD(GetTotalNumberThreads)(
-        THIS_
-        __out PULONG Total,
-        __out PULONG LargestProcess
-        ) PURE;
-    STDMETHOD(GetThreadIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount_opt(Count) PULONG Ids,
-        __out_ecount_opt(Count) PULONG SysIds
-        ) PURE;
-    // Gets the debugger ID for the thread
-    // currently running on the given
-    // processor.  Only works in kernel
-    // debugging.
-    STDMETHOD(GetThreadIdByProcessor)(
-        THIS_
-        __in ULONG Processor,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current threads
-    // system data structure.  When kernel debugging
-    // this is the offset of the KTHREAD.
-    // When user debugging it is the offset
-    // of the current TEB.
-    STDMETHOD(GetCurrentThreadDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger thread ID for the given
-    // system thread data structure.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByDataOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current threads
-    // TEB.  In user mode this is equivalent to
-    // the threads data offset.
-    STDMETHOD(GetCurrentThreadTeb)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger thread ID for the given TEB.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByTeb)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the system unique ID for the current thread.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetCurrentThreadSystemId)(
-        THIS_
-        __out PULONG SysId
-        ) PURE;
-    // Looks up a debugger thread ID for the given
-    // system thread ID.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdBySystemId)(
-        THIS_
-        __in ULONG SysId,
-        __out PULONG Id
-        ) PURE;
-    // Returns the handle of the current thread.
-    // In kernel mode the value returned is the
-    // index of the processor the thread is
-    // executing on plus one.
-    STDMETHOD(GetCurrentThreadHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    // Looks up a debugger thread ID for the given handle.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByHandle)(
-        THIS_
-        __in ULONG64 Handle,
-        __out PULONG Id
-        ) PURE;
-
-    // Currently kernel mode sessions will only have
-    // a single process representing kernel space.
-    STDMETHOD(GetNumberProcesses)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetProcessIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount_opt(Count) PULONG Ids,
-        __out_ecount_opt(Count) PULONG SysIds
-        ) PURE;
-    // Returns the offset of the current processs
-    // system data structure.  When kernel debugging
-    // this is the offset of the KPROCESS of
-    // the process that owns the current thread.
-    // When user debugging it is the offset
-    // of the current PEB.
-    STDMETHOD(GetCurrentProcessDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger process ID for the given
-    // system process data structure.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdByDataOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current processs
-    // PEB.  In user mode this is equivalent to
-    // the processs data offset.
-    STDMETHOD(GetCurrentProcessPeb)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger process ID for the given PEB.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdByPeb)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the system unique ID for the current process.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetCurrentProcessSystemId)(
-        THIS_
-        __out PULONG SysId
-        ) PURE;
-    // Looks up a debugger process ID for the given
-    // system process ID.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdBySystemId)(
-        THIS_
-        __in ULONG SysId,
-        __out PULONG Id
-        ) PURE;
-    // Returns the handle of the current process.
-    // In kernel mode this is the kernel processs
-    // artificial handle used for symbol operations
-    // and so can only be used with dbghelp APIs.
-    STDMETHOD(GetCurrentProcessHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    // Looks up a debugger process ID for the given handle.
-    STDMETHOD(GetProcessIdByHandle)(
-        THIS_
-        __in ULONG64 Handle,
-        __out PULONG Id
-        ) PURE;
-    // Retrieve the name of the executable loaded
-    // in the process.  This may fail if no executable
-    // was identified.
-    STDMETHOD(GetCurrentProcessExecutableName)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ExeSize
-        ) PURE;
-
-    // IDebugSystemObjects2.
-
-    // Return the number of seconds that the current
-    // process has been running.
-    STDMETHOD(GetCurrentProcessUpTime)(
-        THIS_
-        __out PULONG UpTime
-        ) PURE;
-
-    // During kernel sessions the debugger retrieves
-    // some information from the system thread and process
-    // running on the current processor.  For example,
-    // the debugger will retrieve virtual memory translation
-    // information for when the debugger needs to
-    // carry out its own virtual to physical translations.
-    // Occasionally it can be interesting to perform
-    // similar operations but on a process which isnt
-    // currently running.  The follow methods allow a caller
-    // to override the data offsets used by the debugger
-    // so that other system threads and processes can
-    // be used instead.  These values are defaulted to
-    // the thread and process running on the current
-    // processor each time the debuggee executes or
-    // the current processor changes.
-    // The thread and process settings are independent so
-    // it is possible to refer to a thread in a process
-    // other than the current process and vice versa.
-    // Setting an offset of zero will reload the
-    // default value.
-    STDMETHOD(GetImplicitThreadDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(SetImplicitThreadDataOffset)(
-        THIS_
-        __in ULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetImplicitProcessDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(SetImplicitProcessDataOffset)(
-        THIS_
-        __in ULONG64 Offset
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugSystemObjects3
-DECLARE_INTERFACE_(IDebugSystemObjects3, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugSystemObjects.
-
-    // In user mode debugging the debugger
-    // tracks all threads and processes and
-    // enumerates them through the following
-    // methods.  When enumerating threads
-    // the threads are enumerated for the current
-    // process.
-    // Kernel mode debugging currently is
-    // limited to enumerating only the threads
-    // assigned to processors, not all of
-    // the threads in the system.  Process
-    // enumeration is limited to a single
-    // virtual process representing kernel space.
-
-    // Returns the ID of the thread on which
-    // the last event occurred.
-    STDMETHOD(GetEventThread)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetEventProcess)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-
-    // Controls implicit thread used by the
-    // debug engine.  The debuggers current
-    // thread is just a piece of data held
-    // by the debugger for calls which use
-    // thread-specific information.  In those
-    // calls the debuggers current thread is used.
-    // The debuggers current thread is not related
-    // to any system thread attribute.
-    // IDs for threads are small integer IDs
-    // maintained by the engine.  They are not
-    // related to system thread IDs.
-    STDMETHOD(GetCurrentThreadId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(SetCurrentThreadId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-    // The current process is the process
-    // that owns the current thread.
-    STDMETHOD(GetCurrentProcessId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    // Setting the current process automatically
-    // sets the current thread to the thread that
-    // was last current in that process.
-    STDMETHOD(SetCurrentProcessId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-
-    // Gets the number of threads in the current process.
-    STDMETHOD(GetNumberThreads)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // Gets thread count information for all processes
-    // and the largest number of threads in a single process.
-    STDMETHOD(GetTotalNumberThreads)(
-        THIS_
-        __out PULONG Total,
-        __out PULONG LargestProcess
-        ) PURE;
-    STDMETHOD(GetThreadIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount_opt(Count) PULONG Ids,
-        __out_ecount_opt(Count) PULONG SysIds
-        ) PURE;
-    // Gets the debugger ID for the thread
-    // currently running on the given
-    // processor.  Only works in kernel
-    // debugging.
-    STDMETHOD(GetThreadIdByProcessor)(
-        THIS_
-        __in ULONG Processor,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current threads
-    // system data structure.  When kernel debugging
-    // this is the offset of the KTHREAD.
-    // When user debugging it is the offset
-    // of the current TEB.
-    STDMETHOD(GetCurrentThreadDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger thread ID for the given
-    // system thread data structure.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByDataOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current threads
-    // TEB.  In user mode this is equivalent to
-    // the threads data offset.
-    STDMETHOD(GetCurrentThreadTeb)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger thread ID for the given TEB.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByTeb)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the system unique ID for the current thread.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetCurrentThreadSystemId)(
-        THIS_
-        __out PULONG SysId
-        ) PURE;
-    // Looks up a debugger thread ID for the given
-    // system thread ID.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdBySystemId)(
-        THIS_
-        __in ULONG SysId,
-        __out PULONG Id
-        ) PURE;
-    // Returns the handle of the current thread.
-    // In kernel mode the value returned is the
-    // index of the processor the thread is
-    // executing on plus one.
-    STDMETHOD(GetCurrentThreadHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    // Looks up a debugger thread ID for the given handle.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByHandle)(
-        THIS_
-        __in ULONG64 Handle,
-        __out PULONG Id
-        ) PURE;
-
-    // Currently kernel mode sessions will only have
-    // a single process representing kernel space.
-    STDMETHOD(GetNumberProcesses)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetProcessIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount_opt(Count) PULONG Ids,
-        __out_ecount_opt(Count) PULONG SysIds
-        ) PURE;
-    // Returns the offset of the current processs
-    // system data structure.  When kernel debugging
-    // this is the offset of the KPROCESS of
-    // the process that owns the current thread.
-    // When user debugging it is the offset
-    // of the current PEB.
-    STDMETHOD(GetCurrentProcessDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger process ID for the given
-    // system process data structure.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdByDataOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current processs
-    // PEB.  In user mode this is equivalent to
-    // the processs data offset.
-    STDMETHOD(GetCurrentProcessPeb)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger process ID for the given PEB.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdByPeb)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the system unique ID for the current process.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetCurrentProcessSystemId)(
-        THIS_
-        __out PULONG SysId
-        ) PURE;
-    // Looks up a debugger process ID for the given
-    // system process ID.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdBySystemId)(
-        THIS_
-        __in ULONG SysId,
-        __out PULONG Id
-        ) PURE;
-    // Returns the handle of the current process.
-    // In kernel mode this is the kernel processs
-    // artificial handle used for symbol operations
-    // and so can only be used with dbghelp APIs.
-    STDMETHOD(GetCurrentProcessHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    // Looks up a debugger process ID for the given handle.
-    STDMETHOD(GetProcessIdByHandle)(
-        THIS_
-        __in ULONG64 Handle,
-        __out PULONG Id
-        ) PURE;
-    // Retrieve the name of the executable loaded
-    // in the process.  This may fail if no executable
-    // was identified.
-    STDMETHOD(GetCurrentProcessExecutableName)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ExeSize
-        ) PURE;
-
-    // IDebugSystemObjects2.
-
-    // Return the number of seconds that the current
-    // process has been running.
-    STDMETHOD(GetCurrentProcessUpTime)(
-        THIS_
-        __out PULONG UpTime
-        ) PURE;
-
-    // During kernel sessions the debugger retrieves
-    // some information from the system thread and process
-    // running on the current processor.  For example,
-    // the debugger will retrieve virtual memory translation
-    // information for when the debugger needs to
-    // carry out its own virtual to physical translations.
-    // Occasionally it can be interesting to perform
-    // similar operations but on a process which isnt
-    // currently running.  The follow methods allow a caller
-    // to override the data offsets used by the debugger
-    // so that other system threads and processes can
-    // be used instead.  These values are defaulted to
-    // the thread and process running on the current
-    // processor each time the debuggee executes or
-    // the current processor changes.
-    // The thread and process settings are independent so
-    // it is possible to refer to a thread in a process
-    // other than the current process and vice versa.
-    // Setting an offset of zero will reload the
-    // default value.
-    STDMETHOD(GetImplicitThreadDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(SetImplicitThreadDataOffset)(
-        THIS_
-        __in ULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetImplicitProcessDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(SetImplicitProcessDataOffset)(
-        THIS_
-        __in ULONG64 Offset
-        ) PURE;
-
-    // IDebugSystemObjects3.
-
-    STDMETHOD(GetEventSystem)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-
-    STDMETHOD(GetCurrentSystemId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(SetCurrentSystemId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-
-    STDMETHOD(GetNumberSystems)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetSystemIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Ids
-        ) PURE;
-    STDMETHOD(GetTotalNumberThreadsAndProcesses)(
-        THIS_
-        __out PULONG TotalThreads,
-        __out PULONG TotalProcesses,
-        __out PULONG LargestProcessThreads,
-        __out PULONG LargestSystemThreads,
-        __out PULONG LargestSystemProcesses
-        ) PURE;
-    STDMETHOD(GetCurrentSystemServer)(
-        THIS_
-        __out PULONG64 Server
-        ) PURE;
-    STDMETHOD(GetSystemByServer)(
-        THIS_
-        __in ULONG64 Server,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetCurrentSystemServerName)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-};
-
-#undef INTERFACE
-#define INTERFACE IDebugSystemObjects4
-DECLARE_INTERFACE_(IDebugSystemObjects4, IUnknown)
-{
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        ) PURE;
-    STDMETHOD_(ULONG, AddRef)(
-        THIS
-        ) PURE;
-    STDMETHOD_(ULONG, Release)(
-        THIS
-        ) PURE;
-
-    // IDebugSystemObjects.
-
-    // In user mode debugging the debugger
-    // tracks all threads and processes and
-    // enumerates them through the following
-    // methods.  When enumerating threads
-    // the threads are enumerated for the current
-    // process.
-    // Kernel mode debugging currently is
-    // limited to enumerating only the threads
-    // assigned to processors, not all of
-    // the threads in the system.  Process
-    // enumeration is limited to a single
-    // virtual process representing kernel space.
-
-    // Returns the ID of the thread on which
-    // the last event occurred.
-    STDMETHOD(GetEventThread)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetEventProcess)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-
-    // Controls implicit thread used by the
-    // debug engine.  The debuggers current
-    // thread is just a piece of data held
-    // by the debugger for calls which use
-    // thread-specific information.  In those
-    // calls the debuggers current thread is used.
-    // The debuggers current thread is not related
-    // to any system thread attribute.
-    // IDs for threads are small integer IDs
-    // maintained by the engine.  They are not
-    // related to system thread IDs.
-    STDMETHOD(GetCurrentThreadId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(SetCurrentThreadId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-    // The current process is the process
-    // that owns the current thread.
-    STDMETHOD(GetCurrentProcessId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    // Setting the current process automatically
-    // sets the current thread to the thread that
-    // was last current in that process.
-    STDMETHOD(SetCurrentProcessId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-
-    // Gets the number of threads in the current process.
-    STDMETHOD(GetNumberThreads)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    // Gets thread count information for all processes
-    // and the largest number of threads in a single process.
-    STDMETHOD(GetTotalNumberThreads)(
-        THIS_
-        __out PULONG Total,
-        __out PULONG LargestProcess
-        ) PURE;
-    STDMETHOD(GetThreadIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount_opt(Count) PULONG Ids,
-        __out_ecount_opt(Count) PULONG SysIds
-        ) PURE;
-    // Gets the debugger ID for the thread
-    // currently running on the given
-    // processor.  Only works in kernel
-    // debugging.
-    STDMETHOD(GetThreadIdByProcessor)(
-        THIS_
-        __in ULONG Processor,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current threads
-    // system data structure.  When kernel debugging
-    // this is the offset of the KTHREAD.
-    // When user debugging it is the offset
-    // of the current TEB.
-    STDMETHOD(GetCurrentThreadDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger thread ID for the given
-    // system thread data structure.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByDataOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current threads
-    // TEB.  In user mode this is equivalent to
-    // the threads data offset.
-    STDMETHOD(GetCurrentThreadTeb)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger thread ID for the given TEB.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByTeb)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the system unique ID for the current thread.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetCurrentThreadSystemId)(
-        THIS_
-        __out PULONG SysId
-        ) PURE;
-    // Looks up a debugger thread ID for the given
-    // system thread ID.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdBySystemId)(
-        THIS_
-        __in ULONG SysId,
-        __out PULONG Id
-        ) PURE;
-    // Returns the handle of the current thread.
-    // In kernel mode the value returned is the
-    // index of the processor the thread is
-    // executing on plus one.
-    STDMETHOD(GetCurrentThreadHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    // Looks up a debugger thread ID for the given handle.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    STDMETHOD(GetThreadIdByHandle)(
-        THIS_
-        __in ULONG64 Handle,
-        __out PULONG Id
-        ) PURE;
-
-    // Currently kernel mode sessions will only have
-    // a single process representing kernel space.
-    STDMETHOD(GetNumberProcesses)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetProcessIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount_opt(Count) PULONG Ids,
-        __out_ecount_opt(Count) PULONG SysIds
-        ) PURE;
-    // Returns the offset of the current processs
-    // system data structure.  When kernel debugging
-    // this is the offset of the KPROCESS of
-    // the process that owns the current thread.
-    // When user debugging it is the offset
-    // of the current PEB.
-    STDMETHOD(GetCurrentProcessDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger process ID for the given
-    // system process data structure.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdByDataOffset)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the offset of the current processs
-    // PEB.  In user mode this is equivalent to
-    // the processs data offset.
-    STDMETHOD(GetCurrentProcessPeb)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    // Looks up a debugger process ID for the given PEB.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdByPeb)(
-        THIS_
-        __in ULONG64 Offset,
-        __out PULONG Id
-        ) PURE;
-    // Returns the system unique ID for the current process.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetCurrentProcessSystemId)(
-        THIS_
-        __out PULONG SysId
-        ) PURE;
-    // Looks up a debugger process ID for the given
-    // system process ID.
-    // Not currently supported when kernel debugging.
-    STDMETHOD(GetProcessIdBySystemId)(
-        THIS_
-        __in ULONG SysId,
-        __out PULONG Id
-        ) PURE;
-    // Returns the handle of the current process.
-    // In kernel mode this is the kernel processs
-    // artificial handle used for symbol operations
-    // and so can only be used with dbghelp APIs.
-    STDMETHOD(GetCurrentProcessHandle)(
-        THIS_
-        __out PULONG64 Handle
-        ) PURE;
-    // Looks up a debugger process ID for the given handle.
-    STDMETHOD(GetProcessIdByHandle)(
-        THIS_
-        __in ULONG64 Handle,
-        __out PULONG Id
-        ) PURE;
-    // Retrieve the name of the executable loaded
-    // in the process.  This may fail if no executable
-    // was identified.
-    STDMETHOD(GetCurrentProcessExecutableName)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ExeSize
-        ) PURE;
-
-    // IDebugSystemObjects2.
-
-    // Return the number of seconds that the current
-    // process has been running.
-    STDMETHOD(GetCurrentProcessUpTime)(
-        THIS_
-        __out PULONG UpTime
-        ) PURE;
-
-    // During kernel sessions the debugger retrieves
-    // some information from the system thread and process
-    // running on the current processor.  For example,
-    // the debugger will retrieve virtual memory translation
-    // information for when the debugger needs to
-    // carry out its own virtual to physical translations.
-    // Occasionally it can be interesting to perform
-    // similar operations but on a process which isnt
-    // currently running.  The follow methods allow a caller
-    // to override the data offsets used by the debugger
-    // so that other system threads and processes can
-    // be used instead.  These values are defaulted to
-    // the thread and process running on the current
-    // processor each time the debuggee executes or
-    // the current processor changes.
-    // The thread and process settings are independent so
-    // it is possible to refer to a thread in a process
-    // other than the current process and vice versa.
-    // Setting an offset of zero will reload the
-    // default value.
-    STDMETHOD(GetImplicitThreadDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(SetImplicitThreadDataOffset)(
-        THIS_
-        __in ULONG64 Offset
-        ) PURE;
-    STDMETHOD(GetImplicitProcessDataOffset)(
-        THIS_
-        __out PULONG64 Offset
-        ) PURE;
-    STDMETHOD(SetImplicitProcessDataOffset)(
-        THIS_
-        __in ULONG64 Offset
-        ) PURE;
-
-    // IDebugSystemObjects3.
-
-    STDMETHOD(GetEventSystem)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-
-    STDMETHOD(GetCurrentSystemId)(
-        THIS_
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(SetCurrentSystemId)(
-        THIS_
-        __in ULONG Id
-        ) PURE;
-
-    STDMETHOD(GetNumberSystems)(
-        THIS_
-        __out PULONG Number
-        ) PURE;
-    STDMETHOD(GetSystemIdsByIndex)(
-        THIS_
-        __in ULONG Start,
-        __in ULONG Count,
-        __out_ecount(Count) PULONG Ids
-        ) PURE;
-    STDMETHOD(GetTotalNumberThreadsAndProcesses)(
-        THIS_
-        __out PULONG TotalThreads,
-        __out PULONG TotalProcesses,
-        __out PULONG LargestProcessThreads,
-        __out PULONG LargestSystemThreads,
-        __out PULONG LargestSystemProcesses
-        ) PURE;
-    STDMETHOD(GetCurrentSystemServer)(
-        THIS_
-        __out PULONG64 Server
-        ) PURE;
-    STDMETHOD(GetSystemByServer)(
-        THIS_
-        __in ULONG64 Server,
-        __out PULONG Id
-        ) PURE;
-    STDMETHOD(GetCurrentSystemServerName)(
-        THIS_
-        __out_ecount_opt(BufferSize) PSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-
-    // IDebugSystemObjects4.
-
-    STDMETHOD(GetCurrentProcessExecutableNameWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG ExeSize
-        ) PURE;
-
-    STDMETHOD(GetCurrentSystemServerNameWide)(
-        THIS_
-        __out_ecount_opt(BufferSize) PWSTR Buffer,
-        __in ULONG BufferSize,
-        __out_opt PULONG NameSize
-        ) PURE;
-};
-
-//----------------------------------------------------------------------------
-//
-// Debugger/debuggee communication.
-//
-// A distinguished exception, DBG_COMMAND_EXCEPTION (0x40010009),
-// can be used by a debuggee to communicate with the debugger.
-// The arguments of the exception must be:
-// 1. Exception ID.
-// 2. Command code.
-// 3. Size of argument.
-// 4. Pointer to argument.
-//
-// The arguments depend on the command code.
-//
-//----------------------------------------------------------------------------
-
-#define DEBUG_COMMAND_EXCEPTION_ID 0xdbe00dbe
-
-// Invalid command code.
-#define DEBUG_CMDEX_INVALID             0x00000000
-
-//
-// The debugger can collect strings for display at the
-// next event.  A debuggee can use this to register information
-// about a program situation before places where an event
-// may occur, such as a risky operation or assertion.
-// The strings are automatically flushed on the next
-// event continuation.  Strings are kept on a per-thread basis.
-//
-// When adding, the argument is the string to add.
-// Reset has no arguments and clears all strings.
-//
-#define DEBUG_CMDEX_ADD_EVENT_STRING    0x00000001
-#define DEBUG_CMDEX_RESET_EVENT_STRINGS 0x00000002
-
-#ifndef DEBUG_NO_IMPLEMENTATION
-
-FORCEINLINE void
-DebugCommandException(ULONG Command, ULONG ArgSize, PVOID Arg)
-{
-    ULONG_PTR ExArgs[4];
-
-    ExArgs[0] = DEBUG_COMMAND_EXCEPTION_ID;
-    ExArgs[1] = Command;
-    ExArgs[2] = ArgSize;
-    ExArgs[3] = (ULONG_PTR)Arg;
-    RaiseException(DBG_COMMAND_EXCEPTION, 0, 4, ExArgs);
-}
-
-#endif // #ifndef DEBUG_NO_IMPLEMENTATION
-
-//----------------------------------------------------------------------------
-//
-// Extension callbacks.
-//
-//----------------------------------------------------------------------------
-
-// Returns a version with the major version in
-// the high word and the minor version in the low word.
-#define DEBUG_EXTENSION_VERSION(Major, Minor) \
-    ((((Major) & 0xffff) << 16) | ((Minor) & 0xffff))
-
-//
-// Descriptive flags returned from extension initialization.
-//
-
-// Extension has a !help command which can give
-// per-command help.
-#define DEBUG_EXTINIT_HAS_COMMAND_HELP 0x00000001
-
-// Initialization routine.  Called once when the extension DLL
-// is loaded.  Returns a version and returns flags detailing
-// overall qualities of the extension DLL.
-// A session may or may not be active at the time the DLL
-// is loaded so initialization routines should not expect
-// to be able to query session information.
-typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_INITIALIZE)
-    (__out PULONG Version, __out PULONG Flags);
-// Exit routine.  Called once just before the extension DLL is
-// unloaded.  As with initialization, a session may or
-// may not be active at the time of the call.
-typedef void (CALLBACK* PDEBUG_EXTENSION_UNINITIALIZE)
-    (void);
-
-// A debuggee has been discovered for the session.  It
-// is not necessarily halted.
-#define DEBUG_NOTIFY_SESSION_ACTIVE       0x00000000
-// The session no longer has a debuggee.
-#define DEBUG_NOTIFY_SESSION_INACTIVE     0x00000001
-// The debuggee is halted and accessible.
-#define DEBUG_NOTIFY_SESSION_ACCESSIBLE   0x00000002
-// The debuggee is running or inaccessible.
-#define DEBUG_NOTIFY_SESSION_INACCESSIBLE 0x00000003
-
-typedef void (CALLBACK* PDEBUG_EXTENSION_NOTIFY)
-    (__in ULONG Notify, __in ULONG64 Argument);
-
-// A PDEBUG_EXTENSION_CALL function can return this code
-// to indicate that it was unable to handle the request
-// and that the search for an extension function should
-// continue down the extension DLL chain.
-// Taken from STATUS_VALIDATE_CONTINUE.
-#define DEBUG_EXTENSION_CONTINUE_SEARCH \
-    HRESULT_FROM_NT(0xC0000271L)
-
-// A PDEBUG_EXTENSION_CALL function can return this code
-// to indicate that the engine should unload and reload
-// the extension binary.  This allows extensions to implement
-// auto-update functionality.
-#define DEBUG_EXTENSION_RELOAD_EXTENSION \
-    HRESULT_FROM_NT(0xC00000EEL)
-
-// Every routine in an extension DLL has the following prototype.
-// The extension may be called from multiple clients so it
-// should not cache the client value between calls.
-typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_CALL)
-    (__in PDEBUG_CLIENT Client, __in_opt PCSTR Args);
-
-//
-// KnownStructOutput[Ex] flags
-//
-
-// Return names of supported structs.
-#define DEBUG_KNOWN_STRUCT_GET_NAMES              1
-// Return value output for type.
-#define DEBUG_KNOWN_STRUCT_GET_SINGLE_LINE_OUTPUT 2
-// Return S_OK if suppressing type name.
-#define DEBUG_KNOWN_STRUCT_SUPPRESS_TYPE_NAME     3
-
-// Extensions may export this callback in order to dump structs that
-// are well known to them.  The engine calls this to inject extension
-// output into dt's struct dump.
-typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_KNOWN_STRUCT)
-    (__in ULONG Flags,
-     __in ULONG64 Offset,
-     __in_opt PSTR TypeName,
-     __out_ecount_opt(*BufferChars) PSTR Buffer,
-     __inout_opt PULONG BufferChars);
-typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_KNOWN_STRUCT_EX)
-    (__in PDEBUG_CLIENT Client,
-     __in ULONG Flags,
-     __in ULONG64 Offset,
-     __in_opt PCSTR TypeName,
-     __out_ecount_opt(*BufferChars) PSTR Buffer,
-     __inout_opt PULONG BufferChars);
-
-// Backwards compatibility with old, incorrect name.
-typedef PDEBUG_EXTENSION_KNOWN_STRUCT PDEBUG_ENTENSION_KNOWNSTRUCT;
-
-//
-// Extensions can provide pseudo-register values that
-// operate similiarly to the debugger's built-in $teb, etc.
-//
-
-#define DEBUG_EXT_QVALUE_DEFAULT 0x00000000
-
-typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_QUERY_VALUE_NAMES)
-    (__in PDEBUG_CLIENT Client,
-     __in ULONG Flags,
-     __out_ecount(BufferChars) PWSTR Buffer,
-     __in ULONG BufferChars,
-     __out PULONG BufferNeeded);
-
-#define DEBUG_EXT_PVALUE_DEFAULT 0x00000000
-
-#define DEBUG_EXT_PVTYPE_IS_VALUE   0x00000000
-#define DEBUG_EXT_PVTYPE_IS_POINTER 0x00000001
-
-typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_PROVIDE_VALUE)
-    (__in PDEBUG_CLIENT Client,
-     __in ULONG Flags,
-     __in PCWSTR Name,
-     __out PULONG64 Value,
-     __out PULONG64 TypeModBase,
-     __out PULONG TypeId,
-     __out PULONG TypeFlags);
-
-//----------------------------------------------------------------------------
-//
-// Extension functions.
-//
-// Extension functions differ from extension callbacks in that
-// they are arbitrary functions exported from an extension DLL
-// for other code callers instead of for human invocation from
-// debugger commands.  Extension function pointers are retrieved
-// for an extension DLL with IDebugControl::GetExtensionFunction.
-//
-// Extension function names must begin with _EFN_.  Other than that
-// they can have any name and prototype.  Extension functions
-// must be public exports of their extension DLL.  They should
-// have a typedef for their function pointer prototype in an
-// extension header so that callers have a header file to include
-// with a type that allows a correctly-formed invocation of the
-// extension function.
-//
-// The engine does not perform any validation of calls to
-// extension functions.  Once the extension function pointer
-// is retrieved with GetExtensionFunction all calls go
-// directly between the caller and the extension function and
-// are not mediated by the engine.
-//
-//----------------------------------------------------------------------------
-
-#ifdef __cplusplus
-};
-
-//----------------------------------------------------------------------------
-//
-// C++ implementation helper classes.
-//
-//----------------------------------------------------------------------------
-
-#if !defined(DEBUG_NO_IMPLEMENTATION) && !defined(_M_CEE_PURE)
-
-//
-// DebugBaseEventCallbacks provides a do-nothing base implementation
-// of IDebugEventCallbacks.  A program can derive their own
-// event callbacks class from DebugBaseEventCallbacks and implement
-// only the methods they are interested in.  Programs must be
-// careful to implement GetInterestMask appropriately.
-//
-class DebugBaseEventCallbacks : public IDebugEventCallbacks
-{
-public:
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        )
-    {
-        *Interface = NULL;
-
-#if _MSC_VER >= 1100
-        if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
-            IsEqualIID(InterfaceId, __uuidof(IDebugEventCallbacks)))
-#else
-        if (IsEqualIID(InterfaceId, IID_IUnknown) ||
-            IsEqualIID(InterfaceId, IID_IDebugEventCallbacks))
-#endif
-        {
-            *Interface = (IDebugEventCallbacks *)this;
-            AddRef();
-            return S_OK;
-        }
-        else
-        {
-            return E_NOINTERFACE;
-        }
-    }
-
-    // IDebugEventCallbacks.
-
-    STDMETHOD(Breakpoint)(
-        THIS_
-        __in PDEBUG_BREAKPOINT Bp
-        )
-    {
-        UNREFERENCED_PARAMETER(Bp);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(Exception)(
-        THIS_
-        __in PEXCEPTION_RECORD64 Exception,
-        __in ULONG FirstChance
-        )
-    {
-        UNREFERENCED_PARAMETER(Exception);
-        UNREFERENCED_PARAMETER(FirstChance);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(CreateThread)(
-        THIS_
-        __in ULONG64 Handle,
-        __in ULONG64 DataOffset,
-        __in ULONG64 StartOffset
-        )
-    {
-        UNREFERENCED_PARAMETER(Handle);
-        UNREFERENCED_PARAMETER(DataOffset);
-        UNREFERENCED_PARAMETER(StartOffset);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(ExitThread)(
-        THIS_
-        __in ULONG ExitCode
-        )
-    {
-        UNREFERENCED_PARAMETER(ExitCode);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(CreateProcess)(
-        THIS_
-        __in ULONG64 ImageFileHandle,
-        __in ULONG64 Handle,
-        __in ULONG64 BaseOffset,
-        __in ULONG ModuleSize,
-        __in PCSTR ModuleName,
-        __in PCSTR ImageName,
-        __in ULONG CheckSum,
-        __in ULONG TimeDateStamp,
-        __in ULONG64 InitialThreadHandle,
-        __in ULONG64 ThreadDataOffset,
-        __in ULONG64 StartOffset
-        )
-    {
-        UNREFERENCED_PARAMETER(ImageFileHandle);
-        UNREFERENCED_PARAMETER(Handle);
-        UNREFERENCED_PARAMETER(BaseOffset);
-        UNREFERENCED_PARAMETER(ModuleSize);
-        UNREFERENCED_PARAMETER(ModuleName);
-        UNREFERENCED_PARAMETER(ImageName);
-        UNREFERENCED_PARAMETER(CheckSum);
-        UNREFERENCED_PARAMETER(TimeDateStamp);
-        UNREFERENCED_PARAMETER(InitialThreadHandle);
-        UNREFERENCED_PARAMETER(ThreadDataOffset);
-        UNREFERENCED_PARAMETER(StartOffset);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(ExitProcess)(
-        THIS_
-        __in ULONG ExitCode
-        )
-    {
-        UNREFERENCED_PARAMETER(ExitCode);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(LoadModule)(
-        THIS_
-        __in ULONG64 ImageFileHandle,
-        __in ULONG64 BaseOffset,
-        __in ULONG ModuleSize,
-        __in PCSTR ModuleName,
-        __in PCSTR ImageName,
-        __in ULONG CheckSum,
-        __in ULONG TimeDateStamp
-        )
-    {
-        UNREFERENCED_PARAMETER(ImageFileHandle);
-        UNREFERENCED_PARAMETER(BaseOffset);
-        UNREFERENCED_PARAMETER(ModuleSize);
-        UNREFERENCED_PARAMETER(ModuleName);
-        UNREFERENCED_PARAMETER(ImageName);
-        UNREFERENCED_PARAMETER(CheckSum);
-        UNREFERENCED_PARAMETER(TimeDateStamp);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(UnloadModule)(
-        THIS_
-        __in PCSTR ImageBaseName,
-        __in ULONG64 BaseOffset
-        )
-    {
-        UNREFERENCED_PARAMETER(ImageBaseName);
-        UNREFERENCED_PARAMETER(BaseOffset);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(SystemError)(
-        THIS_
-        __in ULONG Error,
-        __in ULONG Level
-        )
-    {
-        UNREFERENCED_PARAMETER(Error);
-        UNREFERENCED_PARAMETER(Level);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(SessionStatus)(
-        THIS_
-        __in ULONG Status
-        )
-    {
-        UNREFERENCED_PARAMETER(Status);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(ChangeDebuggeeState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        )
-    {
-        UNREFERENCED_PARAMETER(Flags);
-        UNREFERENCED_PARAMETER(Argument);
-        return S_OK;
-    }
-    STDMETHOD(ChangeEngineState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        )
-    {
-        UNREFERENCED_PARAMETER(Flags);
-        UNREFERENCED_PARAMETER(Argument);
-        return S_OK;
-    }
-    STDMETHOD(ChangeSymbolState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        )
-    {
-        UNREFERENCED_PARAMETER(Flags);
-        UNREFERENCED_PARAMETER(Argument);
-        return S_OK;
-    }
-};
-
-class DebugBaseEventCallbacksWide : public IDebugEventCallbacksWide
-{
-public:
-    // IUnknown.
-    STDMETHOD(QueryInterface)(
-        THIS_
-        __in REFIID InterfaceId,
-        __out PVOID* Interface
-        )
-    {
-        *Interface = NULL;
-
-#if _MSC_VER >= 1100
-        if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
-            IsEqualIID(InterfaceId, __uuidof(IDebugEventCallbacksWide)))
-#else
-        if (IsEqualIID(InterfaceId, IID_IUnknown) ||
-            IsEqualIID(InterfaceId, IID_IDebugEventCallbacksWide))
-#endif
-        {
-            *Interface = (IDebugEventCallbacksWide *)this;
-            AddRef();
-            return S_OK;
-        }
-        else
-        {
-            return E_NOINTERFACE;
-        }
-    }
-
-    // IDebugEventCallbacksWide.
-
-    STDMETHOD(Breakpoint)(
-        THIS_
-        __in PDEBUG_BREAKPOINT2 Bp
-        )
-    {
-        UNREFERENCED_PARAMETER(Bp);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(Exception)(
-        THIS_
-        __in PEXCEPTION_RECORD64 Exception,
-        __in ULONG FirstChance
-        )
-    {
-        UNREFERENCED_PARAMETER(Exception);
-        UNREFERENCED_PARAMETER(FirstChance);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(CreateThread)(
-        THIS_
-        __in ULONG64 Handle,
-        __in ULONG64 DataOffset,
-        __in ULONG64 StartOffset
-        )
-    {
-        UNREFERENCED_PARAMETER(Handle);
-        UNREFERENCED_PARAMETER(DataOffset);
-        UNREFERENCED_PARAMETER(StartOffset);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(ExitThread)(
-        THIS_
-        __in ULONG ExitCode
-        )
-    {
-        UNREFERENCED_PARAMETER(ExitCode);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(CreateProcess)(
-        THIS_
-        __in ULONG64 ImageFileHandle,
-        __in ULONG64 Handle,
-        __in ULONG64 BaseOffset,
-        __in ULONG ModuleSize,
-        __in PCWSTR ModuleName,
-        __in PCWSTR ImageName,
-        __in ULONG CheckSum,
-        __in ULONG TimeDateStamp,
-        __in ULONG64 InitialThreadHandle,
-        __in ULONG64 ThreadDataOffset,
-        __in ULONG64 StartOffset
-        )
-    {
-        UNREFERENCED_PARAMETER(ImageFileHandle);
-        UNREFERENCED_PARAMETER(Handle);
-        UNREFERENCED_PARAMETER(BaseOffset);
-        UNREFERENCED_PARAMETER(ModuleSize);
-        UNREFERENCED_PARAMETER(ModuleName);
-        UNREFERENCED_PARAMETER(ImageName);
-        UNREFERENCED_PARAMETER(CheckSum);
-        UNREFERENCED_PARAMETER(TimeDateStamp);
-        UNREFERENCED_PARAMETER(InitialThreadHandle);
-        UNREFERENCED_PARAMETER(ThreadDataOffset);
-        UNREFERENCED_PARAMETER(StartOffset);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(ExitProcess)(
-        THIS_
-        __in ULONG ExitCode
-        )
-    {
-        UNREFERENCED_PARAMETER(ExitCode);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(LoadModule)(
-        THIS_
-        __in ULONG64 ImageFileHandle,
-        __in ULONG64 BaseOffset,
-        __in ULONG ModuleSize,
-        __in PCWSTR ModuleName,
-        __in PCWSTR ImageName,
-        __in ULONG CheckSum,
-        __in ULONG TimeDateStamp
-        )
-    {
-        UNREFERENCED_PARAMETER(ImageFileHandle);
-        UNREFERENCED_PARAMETER(BaseOffset);
-        UNREFERENCED_PARAMETER(ModuleSize);
-        UNREFERENCED_PARAMETER(ModuleName);
-        UNREFERENCED_PARAMETER(ImageName);
-        UNREFERENCED_PARAMETER(CheckSum);
-        UNREFERENCED_PARAMETER(TimeDateStamp);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(UnloadModule)(
-        THIS_
-        __in PCWSTR ImageBaseName,
-        __in ULONG64 BaseOffset
-        )
-    {
-        UNREFERENCED_PARAMETER(ImageBaseName);
-        UNREFERENCED_PARAMETER(BaseOffset);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(SystemError)(
-        THIS_
-        __in ULONG Error,
-        __in ULONG Level
-        )
-    {
-        UNREFERENCED_PARAMETER(Error);
-        UNREFERENCED_PARAMETER(Level);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(SessionStatus)(
-        THIS_
-        __in ULONG Status
-        )
-    {
-        UNREFERENCED_PARAMETER(Status);
-        return DEBUG_STATUS_NO_CHANGE;
-    }
-    STDMETHOD(ChangeDebuggeeState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        )
-    {
-        UNREFERENCED_PARAMETER(Flags);
-        UNREFERENCED_PARAMETER(Argument);
-        return S_OK;
-    }
-    STDMETHOD(ChangeEngineState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        )
-    {
-        UNREFERENCED_PARAMETER(Flags);
-        UNREFERENCED_PARAMETER(Argument);
-        return S_OK;
-    }
-    STDMETHOD(ChangeSymbolState)(
-        THIS_
-        __in ULONG Flags,
-        __in ULONG64 Argument
-        )
-    {
-        UNREFERENCED_PARAMETER(Flags);
-        UNREFERENCED_PARAMETER(Argument);
-        return S_OK;
-    }
-};
-
-#endif // #ifndef DEBUG_NO_IMPLEMENTATION
-
-#ifdef DEBUG_UNICODE_MACROS
-
-#ifdef UNICODE
-
-#define IDebugEventCallbacksT IDebugEventCallbacksWide
-#define IID_IDebugEventCallbacksT IID_IDebugEventCallbacksWide
-#define IDebugOutputCallbacksT IDebugOutputCallbacksWide
-#define IID_IDebugOutputCallbacksT IID_IDebugOutputCallbacksWide
-#define DebugBaseEventCallbacksT DebugBaseEventCallbacksWide
-
-#define DebugConnectT DebugConnectWide
-#define GetSourceFileInformationT GetSourceFileInformationWide
-#define FindSourceFileAndTokenT FindSourceFileAndTokenWide
-#define GetSymbolInformationT GetSymbolInformationWide
-#define GetCommandT GetCommandWide
-#define SetCommandT SetCommandWide
-#define GetOffsetExpressionT GetOffsetExpressionWide
-#define SetOffsetExpressionT SetOffsetExpressionWide
-#define GetRunningProcessSystemIdByExecutableNameT GetRunningProcessSystemIdByExecutableNameWide
-#define GetRunningProcessDescriptionT GetRunningProcessDescriptionWide
-#define CreateProcessT CreateProcessWide
-#define CreateProcessAndAttachT CreateProcessAndAttachWide
-#define AddDumpInformationFileT AddDumpInformationFileWide
-#define GetDumpFileT GetDumpFileWide
-#define AttachKernelT AttachKernelWide
-#define GetKernelConnectionOptionsT GetKernelConnectionOptionsWide
-#define SetKernelConnectionOptionsT SetKernelConnectionOptionsWide
-#define StartProcessServerT StartProcessServerWide
-#define ConnectProcessServerT ConnectProcessServerWide
-#define StartServerT StartServerWide
-#define OutputServersT OutputServersWide
-#define GetOutputCallbacksT GetOutputCallbacksWide
-#define SetOutputCallbacksT SetOutputCallbacksWide
-#define GetOutputLinePrefixT GetOutputLinePrefixWide
-#define SetOutputLinePrefixT SetOutputLinePrefixWide
-#define GetIdentityT GetIdentityWide
-#define OutputIdentityT OutputIdentityWide
-#define GetEventCallbacksT GetEventCallbacksWide
-#define SetEventCallbacksT SetEventCallbacksWide
-#define CreateProcess2T CreateProcess2Wide
-#define CreateProcessAndAttach2T CreateProcessAndAttach2Wide
-#define PushOutputLinePrefixT PushOutputLinePrefixWide
-#define GetQuitLockStringT GetQuitLockStringWide
-#define SetQuitLockStringT SetQuitLockStringWide
-#define GetLogFileT GetLogFileWide
-#define OpenLogFileT OpenLogFileWide
-#define InputT InputWide
-#define ReturnInputT ReturnInputWide
-#define OutputT OutputWide
-#define OutputVaListT OutputVaListWide
-#define ControlledOutputT ControlledOutputWide
-#define ControlledOutputVaListT ControlledOutputVaListWide
-#define OutputPromptT OutputPromptWide
-#define OutputPromptVaListT OutputPromptVaListWide
-#define GetPromptTextT GetPromptTextWide
-#define AssembleT AssembleWide
-#define DisassembleT DisassembleWide
-#define GetProcessorTypeNamesT GetProcessorTypeNamesWide
-#define GetTextMacroT GetTextMacroWide
-#define SetTextMacroT SetTextMacroWide
-#define EvaluateT EvaluateWide
-#define ExecuteT ExecuteWide
-#define ExecuteCommandFileT ExecuteCommandFileWide
-#define AddExtensionT AddExtensionWide
-#define GetExtensionByPathT GetExtensionByPathWide
-#define CallExtensionT CallExtensionWide
-#define GetExtensionFunctionT GetExtensionFunctionWide
-#define GetEventFilterTextT GetEventFilterTextWide
-#define GetEventFilterCommandT GetEventFilterCommandWide
-#define SetEventFilterCommandT SetEventFilterCommandWide
-#define GetSpecificFilterArgumentT GetSpecificFilterArgumentWide
-#define SetSpecificFilterArgumentT SetSpecificFilterArgumentWide
-#define GetExceptionFilterSecondCommandT GetExceptionFilterSecondCommandWide
-#define SetExceptionFilterSecondCommandT SetExceptionFilterSecondCommandWide
-#define GetLastEventInformationT GetLastEventInformationWide
-#define GetTextReplacementT GetTextReplacementWide
-#define SetTextReplacementT SetTextReplacementWide
-#define SetExpressionSyntaxByNameT SetExpressionSyntaxByNameWide
-#define GetExpressionSyntaxNamesT GetExpressionSyntaxNamesWide
-#define GetEventIndexDescriptionT GetEventIndexDescriptionWide
-#define GetLogFile2T GetLogFile2Wide
-#define OpenLogFile2T OpenLogFile2Wide
-#define GetSystemVersionStringT GetSystemVersionStringWide
-#define ReadMultiByteStringVirtualT ReadMultiByteStringVirtualWide
-#define ReadUnicodeStringVirtualT ReadUnicodeStringVirtualWide
-#define GetDescriptionT GetDescriptionWide
-#define GetIndexByNameT GetIndexByNameWide
-#define GetPseudoDescriptionT GetPseudoDescriptionWide
-#define GetPseudoIndexByNameT GetPseudoIndexByNameWide
-#define AddSymbolT AddSymbolWide
-#define RemoveSymbolByNameT RemoveSymbolByNameWide
-#define GetSymbolNameT GetSymbolNameWide
-#define WriteSymbolT WriteSymbolWide
-#define OutputAsTypeT OutputAsTypeWide
-#define GetSymbolTypeNameT GetSymbolTypeNameWide
-#define GetSymbolValueTextT GetSymbolValueTextWide
-#define GetNameByOffsetT GetNameByOffsetWide
-#define GetOffsetByNameT GetOffsetByNameWide
-#define GetNearNameByOffsetT GetNearNameByOffsetWide
-#define GetLineByOffsetT GetLineByOffsetWide
-#define GetOffsetByLineT GetOffsetByLineWide
-#define GetModuleByModuleNameT GetModuleByModuleNameWide
-#define GetModuleByModuleName2T GetModuleByModuleName2Wide
-#define GetSymbolModuleT GetSymbolModuleWide
-#define GetTypeNameT GetTypeNameWide
-#define GetTypeIdT GetTypeIdWide
-#define GetFieldOffsetT GetFieldOffsetWide
-#define GetSymbolTypeIdT GetSymbolTypeIdWide
-#define StartSymbolMatchT StartSymbolMatchWide
-#define GetNextSymbolMatchT GetNextSymbolMatchWide
-#define ReloadT ReloadWide
-#define GetSymbolPathT GetSymbolPathWide
-#define SetSymbolPathT SetSymbolPathWide
-#define AppendSymbolPathT AppendSymbolPathWide
-#define GetImagePathT GetImagePathWide
-#define SetImagePathT SetImagePathWide
-#define AppendImagePathT AppendImagePathWide
-#define GetSourcePathT GetSourcePathWide
-#define GetSourcePathElementT GetSourcePathElementWide
-#define SetSourcePathT SetSourcePathWide
-#define AppendSourcePathT AppendSourcePathWide
-#define FindSourceFileT FindSourceFileWide
-#define GetSourceFileLineOffsetsT GetSourceFileLineOffsetsWide
-#define GetModuleVersionInformationT GetModuleVersionInformationWide
-#define GetModuleNameStringT GetModuleNameStringWide
-#define GetConstantNameT GetConstantNameWide
-#define GetFieldNameT GetFieldNameWide
-#define GetFieldTypeAndOffsetT GetFieldTypeAndOffsetWide
-#define GetSymbolEntriesByNameT GetSymbolEntriesByNameWide
-#define GetSymbolEntryStringT GetSymbolEntryStringWide
-#define GetSourceEntriesByLineT GetSourceEntriesByLineWide
-#define GetSourceEntryStringT GetSourceEntryStringWide
-#define GetCurrentProcessExecutableNameT GetCurrentProcessExecutableNameWide
-#define GetCurrentSystemServerNameT GetCurrentSystemServerNameWide
-
-#else // #ifdef UNICODE
-
-#define IDebugEventCallbacksT IDebugEventCallbacks
-#define IID_IDebugEventCallbacksT IID_IDebugEventCallbacks
-#define IDebugOutputCallbacksT IDebugOutputCallbacks
-#define IID_IDebugOutputCallbacksT IID_IDebugOutputCallbacks
-#define DebugBaseEventCallbacksT DebugBaseEventCallbacks
-
-#define DebugConnectT DebugConnect
-#define GetSourceFileInformationT GetSourceFileInformation
-#define FindSourceFileAndTokenT FindSourceFileAndToken
-#define GetSymbolInformationT GetSymbolInformation
-#define GetCommandT GetCommand
-#define SetCommandT SetCommand
-#define GetOffsetExpressionT GetOffsetExpression
-#define SetOffsetExpressionT SetOffsetExpression
-#define GetRunningProcessSystemIdByExecutableNameT GetRunningProcessSystemIdByExecutableName
-#define GetRunningProcessDescriptionT GetRunningProcessDescription
-#define CreateProcessT CreateProcess
-#define CreateProcessAndAttachT CreateProcessAndAttach
-#define AddDumpInformationFileT AddDumpInformationFile
-#define GetDumpFileT GetDumpFile
-#define AttachKernelT AttachKernel
-#define GetKernelConnectionOptionsT GetKernelConnectionOptions
-#define SetKernelConnectionOptionsT SetKernelConnectionOptions
-#define StartProcessServerT StartProcessServer
-#define ConnectProcessServerT ConnectProcessServer
-#define StartServerT StartServer
-#define OutputServersT OutputServers
-#define GetOutputCallbacksT GetOutputCallbacks
-#define SetOutputCallbacksT SetOutputCallbacks
-#define GetOutputLinePrefixT GetOutputLinePrefix
-#define SetOutputLinePrefixT SetOutputLinePrefix
-#define GetIdentityT GetIdentity
-#define OutputIdentityT OutputIdentity
-#define GetEventCallbacksT GetEventCallbacks
-#define SetEventCallbacksT SetEventCallbacks
-#define CreateProcess2T CreateProcess2
-#define CreateProcessAndAttach2T CreateProcessAndAttach2
-#define PushOutputLinePrefixT PushOutputLinePrefix
-#define GetQuitLockStringT GetQuitLockString
-#define SetQuitLockStringT SetQuitLockString
-#define GetLogFileT GetLogFile
-#define OpenLogFileT OpenLogFile
-#define InputT Input
-#define ReturnInputT ReturnInput
-#define OutputT Output
-#define OutputVaListT OutputVaList
-#define ControlledOutputT ControlledOutput
-#define ControlledOutputVaListT ControlledOutputVaList
-#define OutputPromptT OutputPrompt
-#define OutputPromptVaListT OutputPromptVaList
-#define GetPromptTextT GetPromptText
-#define AssembleT Assemble
-#define DisassembleT Disassemble
-#define GetProcessorTypeNamesT GetProcessorTypeNames
-#define GetTextMacroT GetTextMacro
-#define SetTextMacroT SetTextMacro
-#define EvaluateT Evaluate
-#define ExecuteT Execute
-#define ExecuteCommandFileT ExecuteCommandFile
-#define AddExtensionT AddExtension
-#define GetExtensionByPathT GetExtensionByPath
-#define CallExtensionT CallExtension
-#define GetExtensionFunctionT GetExtensionFunction
-#define GetEventFilterTextT GetEventFilterText
-#define GetEventFilterCommandT GetEventFilterCommand
-#define SetEventFilterCommandT SetEventFilterCommand
-#define GetSpecificFilterArgumentT GetSpecificFilterArgument
-#define SetSpecificFilterArgumentT SetSpecificFilterArgument
-#define GetExceptionFilterSecondCommandT GetExceptionFilterSecondCommand
-#define SetExceptionFilterSecondCommandT SetExceptionFilterSecondCommand
-#define GetLastEventInformationT GetLastEventInformation
-#define GetTextReplacementT GetTextReplacement
-#define SetTextReplacementT SetTextReplacement
-#define SetExpressionSyntaxByNameT SetExpressionSyntaxByName
-#define GetExpressionSyntaxNamesT GetExpressionSyntaxNames
-#define GetEventIndexDescriptionT GetEventIndexDescription
-#define GetLogFile2T GetLogFile2
-#define OpenLogFile2T OpenLogFile2
-#define GetSystemVersionStringT GetSystemVersionString
-#define ReadMultiByteStringVirtualT ReadMultiByteStringVirtual
-#define ReadUnicodeStringVirtualT ReadUnicodeStringVirtual
-#define GetDescriptionT GetDescription
-#define GetIndexByNameT GetIndexByName
-#define GetPseudoDescriptionT GetPseudoDescription
-#define GetPseudoIndexByNameT GetPseudoIndexByName
-#define AddSymbolT AddSymbol
-#define RemoveSymbolByNameT RemoveSymbolByName
-#define GetSymbolNameT GetSymbolName
-#define WriteSymbolT WriteSymbol
-#define OutputAsTypeT OutputAsType
-#define GetSymbolTypeNameT GetSymbolTypeName
-#define GetSymbolValueTextT GetSymbolValueText
-#define GetNameByOffsetT GetNameByOffset
-#define GetOffsetByNameT GetOffsetByName
-#define GetNearNameByOffsetT GetNearNameByOffset
-#define GetLineByOffsetT GetLineByOffset
-#define GetOffsetByLineT GetOffsetByLine
-#define GetModuleByModuleNameT GetModuleByModuleName
-#define GetModuleByModuleName2T GetModuleByModuleName2
-#define GetSymbolModuleT GetSymbolModule
-#define GetTypeNameT GetTypeName
-#define GetTypeIdT GetTypeId
-#define GetFieldOffsetT GetFieldOffset
-#define GetSymbolTypeIdT GetSymbolTypeId
-#define StartSymbolMatchT StartSymbolMatch
-#define GetNextSymbolMatchT GetNextSymbolMatch
-#define ReloadT Reload
-#define GetSymbolPathT GetSymbolPath
-#define SetSymbolPathT SetSymbolPath
-#define AppendSymbolPathT AppendSymbolPath
-#define GetImagePathT GetImagePath
-#define SetImagePathT SetImagePath
-#define AppendImagePathT AppendImagePath
-#define GetSourcePathT GetSourcePath
-#define GetSourcePathElementT GetSourcePathElement
-#define SetSourcePathT SetSourcePath
-#define AppendSourcePathT AppendSourcePath
-#define FindSourceFileT FindSourceFile
-#define GetSourceFileLineOffsetsT GetSourceFileLineOffsets
-#define GetModuleVersionInformationT GetModuleVersionInformation
-#define GetModuleNameStringT GetModuleNameString
-#define GetConstantNameT GetConstantName
-#define GetFieldNameT GetFieldName
-#define GetFieldTypeAndOffsetT GetFieldTypeAndOffset
-#define GetSymbolEntriesByNameT GetSymbolEntriesByName
-#define GetSymbolEntryStringT GetSymbolEntryString
-#define GetSourceEntriesByLineT GetSourceEntriesByLine
-#define GetSourceEntryStringT GetSourceEntryString
-#define GetCurrentProcessExecutableNameT GetCurrentProcessExecutableName
-#define GetCurrentSystemServerNameT GetCurrentSystemServerName
-
-#endif // #ifdef UNICODE
-
-#endif // #ifdef DEBUG_UNICODE_MACROS
-
-#endif // #ifdef __cplusplus
-
-#endif // #ifndef __DBGENG_H__
diff --git a/src/SOS/Strike/inc/dbghelp.h b/src/SOS/Strike/inc/dbghelp.h
deleted file mode 100644 (file)
index 8075929..0000000
+++ /dev/null
@@ -1,4540 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*++ BUILD Version: 0000     Increment this if a change has global effects
-
-
-Module Name:
-
-    dbghelp.h
-
-Abstract:
-
-    This module defines the prototypes and constants required for the image
-    help routines.
-
-    Contains debugging support routines that are redistributable.
-
-Revision History:
-
---*/
-
-#ifndef _DBGHELP_
-#define _DBGHELP_
-
-#if _MSC_VER > 1020
-#pragma once
-#endif
-
-
-// As a general principal always call the 64 bit version
-// of every API, if a choice exists.  The 64 bit version
-// works great on 32 bit platforms, and is forward
-// compatible to 64 bit platforms.
-
-#ifdef _WIN64
-#ifndef _IMAGEHLP64
-#define _IMAGEHLP64
-#endif
-#endif
-
-// For those without specstrings.h
-// Since there are different versions of this header, I need to
-// individually test each item and define it if it is not around.
-
-#ifndef __in
- #define __in
-#endif
-#ifndef __out
- #define __out
-#endif
-#ifndef __inout
- #define __inout
-#endif
-#ifndef __in_opt
- #define __in_opt
-#endif
-#ifndef __out_opt
- #define __out_opt
-#endif
-#ifndef __inout_opt
- #define __inout_opt
-#endif
-#ifndef __in_ecount
- #define __in_ecount(x)
-#endif
-#ifndef __out_ecount
- #define __out_ecount(x)
-#endif
-#ifndef __inout_ecount
- #define __inout_ecount(x)
-#endif
-#ifndef __in_bcount
- #define __in_bcount(x)
-#endif
-#ifndef __out_bcount
- #define __out_bcount(x)
-#endif
-#ifndef __inout_bcount
- #define __inout_bcount(x)
-#endif
-#ifndef __out_xcount
- #define __out_xcount(x)
-#endif
-#ifndef __deref_opt_out
- #define __deref_opt_out
-#endif
-#ifndef __deref_out
- #define __deref_out
-#endif
-#ifndef __out_ecount_opt
- #define __out_ecount_opt(x)
-#endif
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _IMAGEHLP_SOURCE_
- #define IMAGEAPI __stdcall
- #define DBHLP_DEPRECIATED
-#else
- #define IMAGEAPI DECLSPEC_IMPORT __stdcall
- #if (_MSC_VER >= 1300) && !defined(MIDL_PASS)
-  #define DBHLP_DEPRECIATED   __declspec(deprecated)
- #else
-  #define DBHLP_DEPRECIATED
- #endif
-#endif
-
-#define DBHLPAPI IMAGEAPI
-
-#define IMAGE_SEPARATION (64*1024)
-
-// Observant readers may notice that 2 new fields,
-// 'fReadOnly' and 'Version' have been added to
-// the LOADED_IMAGE structure after 'fDOSImage'.
-// This does not change the size of the structure 
-// from previous headers.  That is because while 
-// 'fDOSImage' is a byte, it is padded by the 
-// compiler to 4 bytes.  So the 2 new fields are 
-// slipped into the extra space.
-
-typedef struct _LOADED_IMAGE {
-    PSTR                  ModuleName;
-    HANDLE                hFile;
-    PUCHAR                MappedAddress;
-#ifdef _IMAGEHLP64
-    PIMAGE_NT_HEADERS64   FileHeader;
-#else
-    PIMAGE_NT_HEADERS32   FileHeader;
-#endif
-    PIMAGE_SECTION_HEADER LastRvaSection;
-    ULONG                 NumberOfSections;
-    PIMAGE_SECTION_HEADER Sections;
-    ULONG                 Characteristics;
-    BOOLEAN               fSystemImage;
-    BOOLEAN               fDOSImage;
-    BOOLEAN               fReadOnly;
-    UCHAR                 Version;
-    LIST_ENTRY            Links;
-    ULONG                 SizeOfImage;
-} LOADED_IMAGE, *PLOADED_IMAGE;
-
-#define MAX_SYM_NAME            2000
-
-
-// Error codes set by dbghelp functions.  Call GetLastError
-// to see them.
-// Dbghelp also sets error codes found in winerror.h
-
-#define ERROR_IMAGE_NOT_STRIPPED    0x8800  // the image is not stripped.  No dbg file available.
-#define ERROR_NO_DBG_POINTER        0x8801  // image is stripped but there is no pointer to a dbg file
-#define ERROR_NO_PDB_POINTER        0x8802  // image does not point to a pdb file
-
-typedef BOOL
-(CALLBACK *PFIND_DEBUG_FILE_CALLBACK)(
-    __in HANDLE FileHandle,
-    __in PCSTR FileName,
-    __in PVOID CallerData
-    );
-
-HANDLE
-IMAGEAPI
-SymFindDebugInfoFile(
-    __in HANDLE hProcess,
-    __in PCSTR FileName,
-    __out_ecount(MAX_PATH + 1) PSTR DebugFilePath,
-    __in_opt PFIND_DEBUG_FILE_CALLBACK Callback,
-    __in_opt PVOID CallerData
-    );
-
-typedef BOOL
-(CALLBACK *PFIND_DEBUG_FILE_CALLBACKW)(
-    __in HANDLE FileHandle,
-    __in PCWSTR FileName,
-    __in PVOID  CallerData
-    );
-
-HANDLE
-IMAGEAPI
-SymFindDebugInfoFileW(
-    __in HANDLE hProcess,
-    __in PCWSTR FileName,
-    __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath,
-    __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback,
-    __in_opt PVOID CallerData
-    );
-
-HANDLE
-IMAGEAPI
-FindDebugInfoFile (
-    __in PCSTR FileName,
-    __in PCSTR SymbolPath,
-    __out_ecount(MAX_PATH + 1) PSTR DebugFilePath
-    );
-
-HANDLE
-IMAGEAPI
-FindDebugInfoFileEx (
-    __in PCSTR FileName,
-    __in PCSTR SymbolPath,
-    __out_ecount(MAX_PATH + 1) PSTR  DebugFilePath,
-    __in_opt PFIND_DEBUG_FILE_CALLBACK Callback,
-    __in_opt PVOID CallerData
-    );
-
-HANDLE
-IMAGEAPI
-FindDebugInfoFileExW (
-    __in PCWSTR FileName,
-    __in PCWSTR SymbolPath,
-    __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath,
-    __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback,
-    __in_opt PVOID CallerData
-    );
-
-typedef BOOL
-(CALLBACK *PFINDFILEINPATHCALLBACK)(
-    PCSTR filename,
-    PVOID context
-    );
-
-BOOL
-IMAGEAPI
-SymFindFileInPath(
-    __in HANDLE hprocess,
-    __in_opt PCSTR SearchPath,
-    __in PCSTR FileName,
-    __in_opt PVOID id,
-    __in DWORD two,
-    __in DWORD three,
-    __in DWORD flags,
-    __out_ecount(MAX_PATH + 1) PSTR FoundFile,
-    __in_opt PFINDFILEINPATHCALLBACK callback,
-    __in_opt PVOID context
-    );
-
-typedef BOOL
-(CALLBACK *PFINDFILEINPATHCALLBACKW)(
-    __in PCWSTR filename,
-    __in PVOID context
-    );
-
-BOOL
-IMAGEAPI
-SymFindFileInPathW(
-    __in HANDLE hprocess,
-    __in_opt PCWSTR SearchPath,
-    __in PCWSTR FileName,
-    __in_opt PVOID id,
-    __in DWORD two,
-    __in DWORD three,
-    __in DWORD flags,
-    __out_ecount(MAX_PATH + 1) PWSTR FoundFile,
-    __in_opt PFINDFILEINPATHCALLBACKW callback,
-    __in_opt PVOID context
-    );
-
-typedef BOOL
-(CALLBACK *PFIND_EXE_FILE_CALLBACK)(
-    __in HANDLE FileHandle,
-    __in PCSTR FileName,
-    __in_opt PVOID CallerData
-    );
-
-HANDLE
-IMAGEAPI
-SymFindExecutableImage(
-    __in HANDLE hProcess,
-    __in PCSTR FileName,
-    __out_ecount(MAX_PATH + 1) PSTR ImageFilePath,
-    __in PFIND_EXE_FILE_CALLBACK Callback,
-    __in PVOID CallerData
-    );
-
-typedef BOOL
-(CALLBACK *PFIND_EXE_FILE_CALLBACKW)(
-    __in HANDLE FileHandle,
-    __in PCWSTR FileName,
-    __in_opt PVOID CallerData
-    );
-
-HANDLE
-IMAGEAPI
-SymFindExecutableImageW(
-    __in HANDLE hProcess,
-    __in PCWSTR FileName,
-    __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath,
-    __in PFIND_EXE_FILE_CALLBACKW Callback,
-    __in PVOID CallerData
-    );
-
-HANDLE
-IMAGEAPI
-FindExecutableImage(
-    __in PCSTR FileName,
-    __in PCSTR SymbolPath,
-    __out_ecount(MAX_PATH + 1) PSTR ImageFilePath
-    );
-
-HANDLE
-IMAGEAPI
-FindExecutableImageEx(
-    __in PCSTR FileName,
-    __in PCSTR SymbolPath,
-    __out_ecount(MAX_PATH + 1) PSTR ImageFilePath,
-    __in_opt PFIND_EXE_FILE_CALLBACK Callback,
-    __in_opt PVOID CallerData
-    );
-
-HANDLE
-IMAGEAPI
-FindExecutableImageExW(
-    __in PCWSTR FileName,
-    __in PCWSTR SymbolPath,
-    __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath,
-    __in_opt PFIND_EXE_FILE_CALLBACKW Callback,
-    __in PVOID CallerData
-    );
-
-PIMAGE_NT_HEADERS
-IMAGEAPI
-ImageNtHeader (
-    __in PVOID Base
-    );
-
-PVOID
-IMAGEAPI
-ImageDirectoryEntryToDataEx (
-    __in PVOID Base,
-    __in BOOLEAN MappedAsImage,
-    __in USHORT DirectoryEntry,
-    __out PULONG Size,
-    __out_opt PIMAGE_SECTION_HEADER *FoundHeader
-    );
-
-PVOID
-IMAGEAPI
-ImageDirectoryEntryToData (
-    __in PVOID Base,
-    __in BOOLEAN MappedAsImage,
-    __in USHORT DirectoryEntry,
-    __out PULONG Size
-    );
-
-PIMAGE_SECTION_HEADER
-IMAGEAPI
-ImageRvaToSection(
-    __in PIMAGE_NT_HEADERS NtHeaders,
-    __in PVOID Base,
-    __in ULONG Rva
-    );
-
-PVOID
-IMAGEAPI
-ImageRvaToVa(
-    __in PIMAGE_NT_HEADERS NtHeaders,
-    __in PVOID Base,
-    __in ULONG Rva,
-    __in_opt OUT PIMAGE_SECTION_HEADER *LastRvaSection
-    );
-
-#ifndef _WIN64
-// This api won't be ported to Win64 - Fix your code.
-
-typedef struct _IMAGE_DEBUG_INFORMATION {
-    LIST_ENTRY List;
-    DWORD ReservedSize;
-    PVOID ReservedMappedBase;
-    USHORT ReservedMachine;
-    USHORT ReservedCharacteristics;
-    DWORD ReservedCheckSum;
-    DWORD ImageBase;
-    DWORD SizeOfImage;
-
-    DWORD ReservedNumberOfSections;
-    PIMAGE_SECTION_HEADER ReservedSections;
-
-    DWORD ReservedExportedNamesSize;
-    PSTR ReservedExportedNames;
-
-    DWORD ReservedNumberOfFunctionTableEntries;
-    PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries;
-    DWORD ReservedLowestFunctionStartingAddress;
-    DWORD ReservedHighestFunctionEndingAddress;
-
-    DWORD ReservedNumberOfFpoTableEntries;
-    PFPO_DATA ReservedFpoTableEntries;
-
-    DWORD SizeOfCoffSymbols;
-    PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols;
-
-    DWORD ReservedSizeOfCodeViewSymbols;
-    PVOID ReservedCodeViewSymbols;
-
-    PSTR ImageFilePath;
-    PSTR ImageFileName;
-    PSTR ReservedDebugFilePath;
-
-    DWORD ReservedTimeDateStamp;
-
-    BOOL  ReservedRomImage;
-    PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory;
-    DWORD ReservedNumberOfDebugDirectories;
-
-    DWORD ReservedOriginalFunctionTableBaseAddress;
-
-    DWORD Reserved[ 2 ];
-
-} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION;
-
-
-PIMAGE_DEBUG_INFORMATION
-IMAGEAPI
-MapDebugInformation(
-    __in_opt HANDLE FileHandle,
-    __in PCSTR FileName,
-    __in_opt PCSTR SymbolPath,
-    __in ULONG ImageBase
-    );
-
-BOOL
-IMAGEAPI
-UnmapDebugInformation(
-    __out_xcount(unknown) PIMAGE_DEBUG_INFORMATION DebugInfo
-    );
-
-#endif
-
-BOOL
-IMAGEAPI
-SearchTreeForFile(
-    __in PCSTR RootPath,
-    __in PCSTR InputPathName,
-    __out_ecount(MAX_PATH + 1) PSTR OutputPathBuffer
-    );
-
-BOOL
-IMAGEAPI
-SearchTreeForFileW(
-    __in PCWSTR RootPath,
-    __in PCWSTR InputPathName,
-    __out_ecount(MAX_PATH + 1) PWSTR OutputPathBuffer
-    );
-
-typedef BOOL
-(CALLBACK *PENUMDIRTREE_CALLBACK)(
-    __in PCSTR FilePath,
-    __in_opt PVOID CallerData
-    );
-
-BOOL
-IMAGEAPI
-EnumDirTree(
-    __in_opt HANDLE hProcess,
-    __in PCSTR RootPath,
-    __in PCSTR InputPathName,
-    __out_ecount_opt(MAX_PATH + 1) PSTR OutputPathBuffer,
-    __in_opt PENUMDIRTREE_CALLBACK cb,
-    __in_opt PVOID data
-    );
-
-typedef BOOL
-(CALLBACK *PENUMDIRTREE_CALLBACKW)(
-    __in PCWSTR FilePath,
-    __in_opt PVOID CallerData
-    );
-
-BOOL
-IMAGEAPI
-EnumDirTreeW(
-    __in_opt HANDLE hProcess,
-    __in PCWSTR RootPath,
-    __in PCWSTR InputPathName,
-    __out_ecount_opt(MAX_PATH + 1) PWSTR OutputPathBuffer,
-    __in_opt PENUMDIRTREE_CALLBACKW cb,
-    __in_opt PVOID data
-    );
-
-BOOL
-IMAGEAPI
-MakeSureDirectoryPathExists(
-    __in PCSTR DirPath
-    );
-
-//
-// UnDecorateSymbolName Flags
-//
-
-#define UNDNAME_COMPLETE                 (0x0000)  // Enable full undecoration
-#define UNDNAME_NO_LEADING_UNDERSCORES   (0x0001)  // Remove leading underscores from MS extended keywords
-#define UNDNAME_NO_MS_KEYWORDS           (0x0002)  // Disable expansion of MS extended keywords
-#define UNDNAME_NO_FUNCTION_RETURNS      (0x0004)  // Disable expansion of return type for primary declaration
-#define UNDNAME_NO_ALLOCATION_MODEL      (0x0008)  // Disable expansion of the declaration model
-#define UNDNAME_NO_ALLOCATION_LANGUAGE   (0x0010)  // Disable expansion of the declaration language specifier
-#define UNDNAME_NO_MS_THISTYPE           (0x0020)  // NYI Disable expansion of MS keywords on the 'this' type for primary declaration
-#define UNDNAME_NO_CV_THISTYPE           (0x0040)  // NYI Disable expansion of CV modifiers on the 'this' type for primary declaration
-#define UNDNAME_NO_THISTYPE              (0x0060)  // Disable all modifiers on the 'this' type
-#define UNDNAME_NO_ACCESS_SPECIFIERS     (0x0080)  // Disable expansion of access specifiers for members
-#define UNDNAME_NO_THROW_SIGNATURES      (0x0100)  // Disable expansion of 'throw-signatures' for functions and pointers to functions
-#define UNDNAME_NO_MEMBER_TYPE           (0x0200)  // Disable expansion of 'static' or 'virtual'ness of members
-#define UNDNAME_NO_RETURN_UDT_MODEL      (0x0400)  // Disable expansion of MS model for UDT returns
-#define UNDNAME_32_BIT_DECODE            (0x0800)  // Undecorate 32-bit decorated names
-#define UNDNAME_NAME_ONLY                (0x1000)  // Crack only the name for primary declaration;
-                                                                                                   //  return just [scope::]name.  Does expand template params
-#define UNDNAME_NO_ARGUMENTS             (0x2000)  // Don't undecorate arguments to function
-#define UNDNAME_NO_SPECIAL_SYMS          (0x4000)  // Don't undecorate special names (v-table, vcall, vector xxx, metatype, etc)
-
-DWORD
-IMAGEAPI
-WINAPI
-UnDecorateSymbolName(
-    __in PCSTR name,
-    __out_ecount(maxStringLength) PSTR outputString,
-    __in DWORD maxStringLength,
-    __in DWORD flags
-    );
-
-DWORD
-IMAGEAPI
-WINAPI
-UnDecorateSymbolNameW(
-    __in PCWSTR name,
-    __out_ecount(maxStringLength) PWSTR outputString,
-    __in DWORD maxStringLength,
-    __in DWORD flags
-    );
-
-//
-// these values are used for synthesized file types
-// that can be passed in as image headers instead of
-// the standard ones from ntimage.h
-//
-
-#define DBHHEADER_DEBUGDIRS     0x1
-#define DBHHEADER_CVMISC        0x2
-
-typedef struct _MODLOAD_DATA {
-    DWORD   ssize;                  // size of this struct
-    DWORD   ssig;                   // signature identifying the passed data
-    PVOID   data;                   // pointer to passed data
-    DWORD   size;                   // size of passed data
-    DWORD   flags;                  // options
-} MODLOAD_DATA, *PMODLOAD_DATA;
-
-typedef struct _MODLOAD_CVMISC {
-    DWORD   oCV;                    // ofset to the codeview record
-    size_t  cCV;                    // size of the codeview record
-    DWORD   oMisc;                  // offset to the misc record
-    size_t  cMisc;                  // size of the misc record
-    DWORD   dtImage;                // datetime stamp of the image
-    DWORD   cImage;                 // size of the image
-} MODLOAD_CVMISC, *PMODLOAD_CVMISC;
-
-//
-// StackWalking API
-//
-
-typedef enum {
-    AddrMode1616,
-    AddrMode1632,
-    AddrModeReal,
-    AddrModeFlat
-} ADDRESS_MODE;
-
-typedef struct _tagADDRESS64 {
-    DWORD64       Offset;
-    WORD          Segment;
-    ADDRESS_MODE  Mode;
-} ADDRESS64, *LPADDRESS64;
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define ADDRESS ADDRESS64
-#define LPADDRESS LPADDRESS64
-#else
-typedef struct _tagADDRESS {
-    DWORD         Offset;
-    WORD          Segment;
-    ADDRESS_MODE  Mode;
-} ADDRESS, *LPADDRESS;
-
-__inline
-void
-Address32To64(
-    __in LPADDRESS a32,
-    __out LPADDRESS64 a64
-    )
-{
-    a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset;
-    a64->Segment = a32->Segment;
-    a64->Mode = a32->Mode;
-}
-
-__inline
-void
-Address64To32(
-    __in LPADDRESS64 a64,
-    __out LPADDRESS a32
-    )
-{
-    a32->Offset = (ULONG)a64->Offset;
-    a32->Segment = a64->Segment;
-    a32->Mode = a64->Mode;
-}
-#endif
-
-//
-// This structure is included in the STACKFRAME structure,
-// and is used to trace through usermode callbacks in a thread's
-// kernel stack.  The values must be copied by the kernel debugger
-// from the DBGKD_GET_VERSION and WAIT_STATE_CHANGE packets.
-//
-
-//
-// New KDHELP structure for 64 bit system support.
-// This structure is preferred in new code.
-//
-typedef struct _KDHELP64 {
-
-    //
-    // address of kernel thread object, as provided in the
-    // WAIT_STATE_CHANGE packet.
-    //
-    DWORD64   Thread;
-
-    //
-    // offset in thread object to pointer to the current callback frame
-    // in kernel stack.
-    //
-    DWORD   ThCallbackStack;
-
-    //
-    // offset in thread object to pointer to the current callback backing
-    // store frame in kernel stack.
-    //
-    DWORD   ThCallbackBStore;
-
-    //
-    // offsets to values in frame:
-    //
-    // address of next callback frame
-    DWORD   NextCallback;
-
-    // address of saved frame pointer (if applicable)
-    DWORD   FramePointer;
-
-
-    //
-    // Address of the kernel function that calls out to user mode
-    //
-    DWORD64   KiCallUserMode;
-
-    //
-    // Address of the user mode dispatcher function
-    //
-    DWORD64   KeUserCallbackDispatcher;
-
-    //
-    // Lowest kernel mode address
-    //
-    DWORD64   SystemRangeStart;
-
-    //
-    // Address of the user mode exception dispatcher function.
-    // Added in API version 10.
-    //
-    DWORD64   KiUserExceptionDispatcher;
-
-    //
-    // Stack bounds, added in API version 11.
-    //
-    DWORD64   StackBase;
-    DWORD64   StackLimit;
-
-    DWORD64   Reserved[5];
-
-} KDHELP64, *PKDHELP64;
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define KDHELP KDHELP64
-#define PKDHELP PKDHELP64
-#else
-typedef struct _KDHELP {
-
-    //
-    // address of kernel thread object, as provided in the
-    // WAIT_STATE_CHANGE packet.
-    //
-    DWORD   Thread;
-
-    //
-    // offset in thread object to pointer to the current callback frame
-    // in kernel stack.
-    //
-    DWORD   ThCallbackStack;
-
-    //
-    // offsets to values in frame:
-    //
-    // address of next callback frame
-    DWORD   NextCallback;
-
-    // address of saved frame pointer (if applicable)
-    DWORD   FramePointer;
-
-    //
-    // Address of the kernel function that calls out to user mode
-    //
-    DWORD   KiCallUserMode;
-
-    //
-    // Address of the user mode dispatcher function
-    //
-    DWORD   KeUserCallbackDispatcher;
-
-    //
-    // Lowest kernel mode address
-    //
-    DWORD   SystemRangeStart;
-
-    //
-    // offset in thread object to pointer to the current callback backing
-    // store frame in kernel stack.
-    //
-    DWORD   ThCallbackBStore;
-
-    //
-    // Address of the user mode exception dispatcher function.
-    // Added in API version 10.
-    //
-    DWORD   KiUserExceptionDispatcher;
-
-    //
-    // Stack bounds, added in API version 11.
-    //
-    DWORD   StackBase;
-    DWORD   StackLimit;
-
-    DWORD   Reserved[5];
-
-} KDHELP, *PKDHELP;
-
-__inline
-void
-KdHelp32To64(
-    __in PKDHELP p32,
-    __out PKDHELP64 p64
-    )
-{
-    p64->Thread = p32->Thread;
-    p64->ThCallbackStack = p32->ThCallbackStack;
-    p64->NextCallback = p32->NextCallback;
-    p64->FramePointer = p32->FramePointer;
-    p64->KiCallUserMode = p32->KiCallUserMode;
-    p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher;
-    p64->SystemRangeStart = p32->SystemRangeStart;
-    p64->KiUserExceptionDispatcher = p32->KiUserExceptionDispatcher;
-    p64->StackBase = p32->StackBase;
-    p64->StackLimit = p32->StackLimit;
-}
-#endif
-
-typedef struct _tagSTACKFRAME64 {
-    ADDRESS64   AddrPC;               // program counter
-    ADDRESS64   AddrReturn;           // return address
-    ADDRESS64   AddrFrame;            // frame pointer
-    ADDRESS64   AddrStack;            // stack pointer
-    ADDRESS64   AddrBStore;           // backing store pointer
-    PVOID       FuncTableEntry;       // pointer to pdata/fpo or NULL
-    DWORD64     Params[4];            // possible arguments to the function
-    BOOL        Far;                  // WOW far call
-    BOOL        Virtual;              // is this a virtual frame?
-    DWORD64     Reserved[3];
-    KDHELP64    KdHelp;
-} STACKFRAME64, *LPSTACKFRAME64;
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define STACKFRAME STACKFRAME64
-#define LPSTACKFRAME LPSTACKFRAME64
-#else
-typedef struct _tagSTACKFRAME {
-    ADDRESS     AddrPC;               // program counter
-    ADDRESS     AddrReturn;           // return address
-    ADDRESS     AddrFrame;            // frame pointer
-    ADDRESS     AddrStack;            // stack pointer
-    PVOID       FuncTableEntry;       // pointer to pdata/fpo or NULL
-    DWORD       Params[4];            // possible arguments to the function
-    BOOL        Far;                  // WOW far call
-    BOOL        Virtual;              // is this a virtual frame?
-    DWORD       Reserved[3];
-    KDHELP      KdHelp;
-    ADDRESS     AddrBStore;           // backing store pointer
-} STACKFRAME, *LPSTACKFRAME;
-#endif
-
-
-typedef
-BOOL
-(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(
-    __in HANDLE hProcess,
-    __in DWORD64 qwBaseAddress,
-    __out_bcount(nSize) PVOID lpBuffer,
-    __in DWORD nSize,
-    __out LPDWORD lpNumberOfBytesRead
-    );
-
-typedef
-PVOID
-(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)(
-    __in HANDLE ahProcess,
-    __in DWORD64 AddrBase
-    );
-
-typedef
-DWORD64
-(__stdcall *PGET_MODULE_BASE_ROUTINE64)(
-    __in HANDLE hProcess,
-    __in DWORD64 Address
-    );
-
-typedef
-DWORD64
-(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(
-    __in HANDLE hProcess,
-    __in HANDLE hThread,
-    __in LPADDRESS64 lpaddr
-    );
-
-BOOL
-IMAGEAPI
-StackWalk64(
-    __in DWORD MachineType,
-    __in HANDLE hProcess,
-    __in HANDLE hThread,
-    __inout LPSTACKFRAME64 StackFrame,
-    __inout PVOID ContextRecord,
-    __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
-    __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
-    __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
-    __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-
-#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64
-#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64
-#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64
-#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64
-
-#define StackWalk StackWalk64
-
-#else
-
-typedef
-BOOL
-(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE)(
-    __in HANDLE hProcess,
-    __in DWORD lpBaseAddress,
-    __out_bcount(nSize) PVOID lpBuffer,
-    __in DWORD nSize,
-    __out PDWORD lpNumberOfBytesRead
-    );
-
-typedef
-PVOID
-(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE)(
-    __in HANDLE hProcess,
-    __in DWORD AddrBase
-    );
-
-typedef
-DWORD
-(__stdcall *PGET_MODULE_BASE_ROUTINE)(
-    __in HANDLE hProcess,
-    __in DWORD Address
-    );
-
-typedef
-DWORD
-(__stdcall *PTRANSLATE_ADDRESS_ROUTINE)(
-    __in HANDLE hProcess,
-    __in HANDLE hThread,
-    __out LPADDRESS lpaddr
-    );
-
-BOOL
-IMAGEAPI
-StackWalk(
-    DWORD MachineType,
-    __in HANDLE hProcess,
-    __in HANDLE hThread,
-    __inout LPSTACKFRAME StackFrame,
-    __inout PVOID ContextRecord,
-    __in_opt PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
-    __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
-    __in_opt PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
-    __in_opt PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
-    );
-
-#endif
-
-
-#define API_VERSION_NUMBER 11
-
-typedef struct API_VERSION {
-    USHORT  MajorVersion;
-    USHORT  MinorVersion;
-    USHORT  Revision;
-    USHORT  Reserved;
-} API_VERSION, *LPAPI_VERSION;
-
-LPAPI_VERSION
-IMAGEAPI
-ImagehlpApiVersion(
-    VOID
-    );
-
-LPAPI_VERSION
-IMAGEAPI
-ImagehlpApiVersionEx(
-    __in LPAPI_VERSION AppVersion
-    );
-
-DWORD
-IMAGEAPI
-GetTimestampForLoadedLibrary(
-    __in HMODULE Module
-    );
-
-//
-// typedefs for function pointers
-//
-typedef BOOL
-(CALLBACK *PSYM_ENUMMODULES_CALLBACK64)(
-    __in PCSTR ModuleName,
-    __in DWORD64 BaseOfDll,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMMODULES_CALLBACKW64)(
-    __in PCWSTR ModuleName,
-    __in DWORD64 BaseOfDll,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PENUMLOADED_MODULES_CALLBACK64)(
-    __in PCSTR ModuleName,
-    __in DWORD64 ModuleBase,
-    __in ULONG ModuleSize,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PENUMLOADED_MODULES_CALLBACKW64)(
-    __in PCWSTR ModuleName,
-    __in DWORD64 ModuleBase,
-    __in ULONG ModuleSize,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64)(
-    __in PCSTR SymbolName,
-    __in DWORD64 SymbolAddress,
-    __in ULONG SymbolSize,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64W)(
-    __in PCWSTR SymbolName,
-    __in DWORD64 SymbolAddress,
-    __in ULONG SymbolSize,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYMBOL_REGISTERED_CALLBACK64)(
-    __in HANDLE hProcess,
-    __in ULONG ActionCode,
-    __in_opt ULONG64 CallbackData,
-    __in_opt ULONG64 UserContext
-    );
-
-typedef
-PVOID
-(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)(
-    __in HANDLE hProcess,
-    __in DWORD AddrBase,
-    __in_opt PVOID UserContext
-    );
-
-typedef
-PVOID
-(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)(
-    __in HANDLE hProcess,
-    __in ULONG64 AddrBase,
-    __in ULONG64 UserContext
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-
-#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64
-#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64
-#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W
-#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64
-#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64
-#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64
-
-#else
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMMODULES_CALLBACK)(
-    __in PCSTR ModuleName,
-    __in ULONG BaseOfDll,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK)(
-    __in PCSTR SymbolName,
-    __in ULONG SymbolAddress,
-    __in ULONG SymbolSize,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACKW)(
-    __in PCWSTR SymbolName,
-    __in ULONG SymbolAddress,
-    __in ULONG SymbolSize,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PENUMLOADED_MODULES_CALLBACK)(
-    __in PCSTR ModuleName,
-    __in ULONG ModuleBase,
-    __in ULONG ModuleSize,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYMBOL_REGISTERED_CALLBACK)(
-    __in HANDLE hProcess,
-    __in ULONG ActionCode,
-    __in_opt PVOID CallbackData,
-    __in_opt PVOID UserContext
-    );
-
-#endif
-
-
-// values found in SYMBOL_INFO.Tag
-//
-// This was taken from cvconst.h and should
-// not override any values found there.
-//
-// #define _NO_CVCONST_H_ if you don't
-// have access to that file...
-
-#ifdef _NO_CVCONST_H
-
-// DIA enums
-
-enum SymTagEnum
-{
-    SymTagNull,
-    SymTagExe,
-    SymTagCompiland,
-    SymTagCompilandDetails,
-    SymTagCompilandEnv,
-    SymTagFunction,
-    SymTagBlock,
-    SymTagData,
-    SymTagAnnotation,
-    SymTagLabel,
-    SymTagPublicSymbol,
-    SymTagUDT,
-    SymTagEnum,
-    SymTagFunctionType,
-    SymTagPointerType,
-    SymTagArrayType,
-    SymTagBaseType,
-    SymTagTypedef,
-    SymTagBaseClass,
-    SymTagFriend,
-    SymTagFunctionArgType,
-    SymTagFuncDebugStart,
-    SymTagFuncDebugEnd,
-    SymTagUsingNamespace,
-    SymTagVTableShape,
-    SymTagVTable,
-    SymTagCustom,
-    SymTagThunk,
-    SymTagCustomType,
-    SymTagManagedType,
-    SymTagDimension,
-    SymTagMax
-};
-
-#endif
-
-//
-// flags found in SYMBOL_INFO.Flags
-//
-
-#define SYMFLAG_VALUEPRESENT     0x00000001
-#define SYMFLAG_REGISTER         0x00000008
-#define SYMFLAG_REGREL           0x00000010
-#define SYMFLAG_FRAMEREL         0x00000020
-#define SYMFLAG_PARAMETER        0x00000040
-#define SYMFLAG_LOCAL            0x00000080
-#define SYMFLAG_CONSTANT         0x00000100
-#define SYMFLAG_EXPORT           0x00000200
-#define SYMFLAG_FORWARDER        0x00000400
-#define SYMFLAG_FUNCTION         0x00000800
-#define SYMFLAG_VIRTUAL          0x00001000
-#define SYMFLAG_THUNK            0x00002000
-#define SYMFLAG_TLSREL           0x00004000
-#define SYMFLAG_SLOT             0x00008000
-#define SYMFLAG_ILREL            0x00010000
-#define SYMFLAG_METADATA         0x00020000
-#define SYMFLAG_CLR_TOKEN        0x00040000
-
-// this resets SymNext/Prev to the beginning
-// of the module passed in the address field
-
-#define SYMFLAG_RESET            0x80000000
-
-//
-// symbol type enumeration
-//
-typedef enum {
-    SymNone = 0,
-    SymCoff,
-    SymCv,
-    SymPdb,
-    SymExport,
-    SymDeferred,
-    SymSym,       // .sym file
-    SymDia,
-    SymVirtual,
-    NumSymTypes
-} SYM_TYPE;
-
-//
-// symbol data structure
-//
-
-typedef struct _IMAGEHLP_SYMBOL64 {
-    DWORD   SizeOfStruct;           // set to sizeof(IMAGEHLP_SYMBOL64)
-    DWORD64 Address;                // virtual address including dll base address
-    DWORD   Size;                   // estimated size of symbol, can be zero
-    DWORD   Flags;                  // info about the symbols, see the SYMF defines
-    DWORD   MaxNameLength;          // maximum size of symbol name in 'Name'
-    CHAR    Name[1];                // symbol name (null terminated string)
-} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
-
-typedef struct _IMAGEHLP_SYMBOL64_PACKAGE {
-    IMAGEHLP_SYMBOL64 sym;
-    CHAR              name[MAX_SYM_NAME + 1];
-} IMAGEHLP_SYMBOL64_PACKAGE, *PIMAGEHLP_SYMBOL64_PACKAGE;
-
-typedef struct _IMAGEHLP_SYMBOLW64 {
-    DWORD   SizeOfStruct;           // set to sizeof(IMAGEHLP_SYMBOLW64)
-    DWORD64 Address;                // virtual address including dll base address
-    DWORD   Size;                   // estimated size of symbol, can be zero
-    DWORD   Flags;                  // info about the symbols, see the SYMF defines
-    DWORD   MaxNameLength;          // maximum size of symbol name in 'Name'
-    WCHAR   Name[1];                // symbol name (null terminated string)
-} IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64;
-
-typedef struct _IMAGEHLP_SYMBOLW64_PACKAGE {
-    IMAGEHLP_SYMBOLW64 sym;
-    WCHAR              name[MAX_SYM_NAME + 1];
-} IMAGEHLP_SYMBOLW64_PACKAGE, *PIMAGEHLP_SYMBOLW64_PACKAGE;
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-
- #define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64
- #define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64
- #define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE
- #define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE
- #define IMAGEHLP_SYMBOLW IMAGEHLP_SYMBOLW64
- #define PIMAGEHLP_SYMBOLW PIMAGEHLP_SYMBOLW64
- #define IMAGEHLP_SYMBOLW_PACKAGE IMAGEHLP_SYMBOLW64_PACKAGE
- #define PIMAGEHLP_SYMBOLW_PACKAGE PIMAGEHLP_SYMBOLW64_PACKAGE
-
-#else
-
- typedef struct _IMAGEHLP_SYMBOL {
-     DWORD SizeOfStruct;           // set to sizeof(IMAGEHLP_SYMBOL)
-     DWORD Address;                // virtual address including dll base address
-     DWORD Size;                   // estimated size of symbol, can be zero
-     DWORD Flags;                  // info about the symbols, see the SYMF defines
-     DWORD                       MaxNameLength;          // maximum size of symbol name in 'Name'
-     CHAR                        Name[1];                // symbol name (null terminated string)
- } IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL;
-
- typedef struct _IMAGEHLP_SYMBOL_PACKAGE {
-     IMAGEHLP_SYMBOL sym;
-     CHAR            name[MAX_SYM_NAME + 1];
- } IMAGEHLP_SYMBOL_PACKAGE, *PIMAGEHLP_SYMBOL_PACKAGE;
-
- typedef struct _IMAGEHLP_SYMBOLW {
-     DWORD SizeOfStruct;           // set to sizeof(IMAGEHLP_SYMBOLW)
-     DWORD Address;                // virtual address including dll base address
-     DWORD Size;                   // estimated size of symbol, can be zero
-     DWORD Flags;                  // info about the symbols, see the SYMF defines
-     DWORD                       MaxNameLength;          // maximum size of symbol name in 'Name'
-     WCHAR                       Name[1];                // symbol name (null terminated string)
- } IMAGEHLP_SYMBOLW, *PIMAGEHLP_SYMBOLW;
-
- typedef struct _IMAGEHLP_SYMBOLW_PACKAGE {
-     IMAGEHLP_SYMBOLW sym;
-     WCHAR            name[MAX_SYM_NAME + 1];
- } IMAGEHLP_SYMBOLW_PACKAGE, *PIMAGEHLP_SYMBOLW_PACKAGE;
-
-#endif
-
-//
-// module data structure
-//
-
-typedef struct _IMAGEHLP_MODULE64 {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_MODULE64)
-    DWORD64  BaseOfImage;            // base load address of module
-    DWORD    ImageSize;              // virtual size of the loaded module
-    DWORD    TimeDateStamp;          // date/time stamp from pe header
-    DWORD    CheckSum;               // checksum from the pe header
-    DWORD    NumSyms;                // number of symbols in the symbol table
-    SYM_TYPE SymType;                // type of symbols loaded
-    CHAR     ModuleName[32];         // module name
-    CHAR     ImageName[256];         // image name
-    CHAR     LoadedImageName[256];   // symbol file name
-    // new elements: 07-Jun-2002
-    CHAR     LoadedPdbName[256];     // pdb file name
-    DWORD    CVSig;                  // Signature of the CV record in the debug directories
-    CHAR     CVData[MAX_PATH * 3];   // Contents of the CV record
-    DWORD    PdbSig;                 // Signature of PDB
-    GUID     PdbSig70;               // Signature of PDB (VC 7 and up)
-    DWORD    PdbAge;                 // DBI age of pdb
-    BOOL     PdbUnmatched;           // loaded an unmatched pdb
-    BOOL     DbgUnmatched;           // loaded an unmatched dbg
-    BOOL     LineNumbers;            // we have line number information
-    BOOL     GlobalSymbols;          // we have internal symbol information
-    BOOL     TypeInfo;               // we have type information
-    // new elements: 17-Dec-2003
-    BOOL     SourceIndexed;          // pdb supports source server
-    BOOL     Publics;                // contains public symbols
-} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64;
-
-typedef struct _IMAGEHLP_MODULEW64 {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_MODULE64)
-    DWORD64  BaseOfImage;            // base load address of module
-    DWORD    ImageSize;              // virtual size of the loaded module
-    DWORD    TimeDateStamp;          // date/time stamp from pe header
-    DWORD    CheckSum;               // checksum from the pe header
-    DWORD    NumSyms;                // number of symbols in the symbol table
-    SYM_TYPE SymType;                // type of symbols loaded
-    WCHAR    ModuleName[32];         // module name
-    WCHAR    ImageName[256];         // image name
-    // new elements: 07-Jun-2002
-    WCHAR    LoadedImageName[256];   // symbol file name
-    WCHAR    LoadedPdbName[256];     // pdb file name
-    DWORD    CVSig;                  // Signature of the CV record in the debug directories
-    WCHAR        CVData[MAX_PATH * 3];   // Contents of the CV record
-    DWORD    PdbSig;                 // Signature of PDB
-    GUID     PdbSig70;               // Signature of PDB (VC 7 and up)
-    DWORD    PdbAge;                 // DBI age of pdb
-    BOOL     PdbUnmatched;           // loaded an unmatched pdb
-    BOOL     DbgUnmatched;           // loaded an unmatched dbg
-    BOOL     LineNumbers;            // we have line number information
-    BOOL     GlobalSymbols;          // we have internal symbol information
-    BOOL     TypeInfo;               // we have type information
-    // new elements: 17-Dec-2003
-    BOOL     SourceIndexed;          // pdb supports source server
-    BOOL     Publics;                // contains public symbols
-} IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64;
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define IMAGEHLP_MODULE IMAGEHLP_MODULE64
-#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64
-#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64
-#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64
-#else
-typedef struct _IMAGEHLP_MODULE {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_MODULE)
-    DWORD    BaseOfImage;            // base load address of module
-    DWORD    ImageSize;              // virtual size of the loaded module
-    DWORD    TimeDateStamp;          // date/time stamp from pe header
-    DWORD    CheckSum;               // checksum from the pe header
-    DWORD    NumSyms;                // number of symbols in the symbol table
-    SYM_TYPE SymType;                // type of symbols loaded
-    CHAR     ModuleName[32];         // module name
-    CHAR     ImageName[256];         // image name
-    CHAR     LoadedImageName[256];   // symbol file name
-} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE;
-
-typedef struct _IMAGEHLP_MODULEW {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_MODULE)
-    DWORD    BaseOfImage;            // base load address of module
-    DWORD    ImageSize;              // virtual size of the loaded module
-    DWORD    TimeDateStamp;          // date/time stamp from pe header
-    DWORD    CheckSum;               // checksum from the pe header
-    DWORD    NumSyms;                // number of symbols in the symbol table
-    SYM_TYPE SymType;                // type of symbols loaded
-    WCHAR    ModuleName[32];         // module name
-    WCHAR    ImageName[256];         // image name
-    WCHAR    LoadedImageName[256];   // symbol file name
-} IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW;
-#endif
-
-//
-// source file line data structure
-//
-
-typedef struct _IMAGEHLP_LINE64 {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_LINE64)
-    PVOID    Key;                    // internal
-    DWORD    LineNumber;             // line number in file
-    PCHAR    FileName;               // full filename
-    DWORD64  Address;                // first instruction of line
-} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
-
-typedef struct _IMAGEHLP_LINEW64 {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_LINE64)
-    PVOID    Key;                    // internal
-    DWORD    LineNumber;             // line number in file
-    PWSTR    FileName;               // full filename
-    DWORD64  Address;                // first instruction of line
-} IMAGEHLP_LINEW64, *PIMAGEHLP_LINEW64;
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define IMAGEHLP_LINE IMAGEHLP_LINE64
-#define PIMAGEHLP_LINE PIMAGEHLP_LINE64
-#else
-typedef struct _IMAGEHLP_LINE {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_LINE)
-    PVOID    Key;                    // internal
-    DWORD    LineNumber;             // line number in file
-    PCHAR    FileName;               // full filename
-    DWORD    Address;                // first instruction of line
-} IMAGEHLP_LINE, *PIMAGEHLP_LINE;
-
-typedef struct _IMAGEHLP_LINEW {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_LINE64)
-    PVOID    Key;                    // internal
-    DWORD    LineNumber;             // line number in file
-    PCHAR    FileName;               // full filename
-    DWORD64  Address;                // first instruction of line
-} IMAGEHLP_LINEW, *PIMAGEHLP_LINEW;
-#endif
-
-//
-// source file structure
-//
-
-typedef struct _SOURCEFILE {
-    DWORD64  ModBase;                // base address of loaded module
-    PCHAR    FileName;               // full filename of source
-} SOURCEFILE, *PSOURCEFILE;
-
-typedef struct _SOURCEFILEW {
-    DWORD64  ModBase;                // base address of loaded module
-    PWSTR    FileName;               // full filename of source
-} SOURCEFILEW, *PSOURCEFILEW;
-
-//
-// data structures used for registered symbol callbacks
-//
-
-#define CBA_DEFERRED_SYMBOL_LOAD_START          0x00000001
-#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE       0x00000002
-#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE        0x00000003
-#define CBA_SYMBOLS_UNLOADED                    0x00000004
-#define CBA_DUPLICATE_SYMBOL                    0x00000005
-#define CBA_READ_MEMORY                         0x00000006
-#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL         0x00000007
-#define CBA_SET_OPTIONS                         0x00000008
-#define CBA_EVENT                               0x00000010
-#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL        0x00000020
-#define CBA_DEBUG_INFO                          0x10000000
-#define CBA_SRCSRV_INFO                         0x20000000
-#define CBA_SRCSRV_EVENT                        0x40000000
-
-typedef struct _IMAGEHLP_CBA_READ_MEMORY {
-    DWORD64   addr;                                     // address to read from
-    PVOID     buf;                                      // buffer to read to
-    DWORD     bytes;                                    // amount of bytes to read
-    DWORD    *bytesread;                                // pointer to store amount of bytes read
-} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY;
-
-enum {
-    sevInfo = 0,
-    sevProblem,
-    sevAttn,
-    sevFatal,
-    sevMax  // unused
-};
-
-#define EVENT_SRCSPEW_START 100
-#define EVENT_SRCSPEW       100
-#define EVENT_SRCSPEW_END   199
-
-typedef struct _IMAGEHLP_CBA_EVENT {
-    DWORD severity;                                     // values from sevInfo to sevFatal
-    DWORD code;                                         // numerical code IDs the error
-    PCHAR desc;                                         // may contain a text description of the error
-    PVOID object;                                       // value dependant upon the error code
-} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT;
-
-typedef struct _IMAGEHLP_CBA_EVENTW {
-    DWORD  severity;                                     // values from sevInfo to sevFatal
-    DWORD  code;                                         // numerical code IDs the error
-    PCWSTR desc;                                         // may contain a text description of the error
-    PVOID  object;                                       // value dependant upon the error code
-} IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW;
-
-typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
-    DWORD64  BaseOfImage;            // base load address of module
-    DWORD    CheckSum;               // checksum from the pe header
-    DWORD    TimeDateStamp;          // date/time stamp from pe header
-    CHAR     FileName[MAX_PATH];     // symbols file or image name
-    BOOLEAN  Reparse;                // load failure reparse
-    HANDLE   hFile;                  // file handle, if passed
-    DWORD    Flags;                     //
-} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64;
-
-typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOADW64)
-    DWORD64  BaseOfImage;            // base load address of module
-    DWORD    CheckSum;               // checksum from the pe header
-    DWORD    TimeDateStamp;          // date/time stamp from pe header
-    WCHAR    FileName[MAX_PATH + 1]; // symbols file or image name
-    BOOLEAN  Reparse;                // load failure reparse
-    HANDLE   hFile;                  // file handle, if passed
-    DWORD    Flags;         //
-} IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64;
-
-#define DSLFLAG_MISMATCHED_PDB  0x1
-#define DSLFLAG_MISMATCHED_DBG  0x2
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64
-#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64
-#else
-typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD {
-    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD)
-    DWORD    BaseOfImage;            // base load address of module
-    DWORD    CheckSum;               // checksum from the pe header
-    DWORD    TimeDateStamp;          // date/time stamp from pe header
-    CHAR     FileName[MAX_PATH];     // symbols file or image name
-    BOOLEAN  Reparse;                // load failure reparse
-    HANDLE   hFile;                  // file handle, if passed
-} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD;
-#endif
-
-typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 {
-    DWORD              SizeOfStruct;           // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64)
-    DWORD              NumberOfDups;           // number of duplicates in the Symbol array
-    PIMAGEHLP_SYMBOL64 Symbol;                 // array of duplicate symbols
-    DWORD              SelectedSymbol;         // symbol selected (-1 to start)
-} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64;
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64
-#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64
-#else
-typedef struct _IMAGEHLP_DUPLICATE_SYMBOL {
-    DWORD            SizeOfStruct;           // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL)
-    DWORD            NumberOfDups;           // number of duplicates in the Symbol array
-    PIMAGEHLP_SYMBOL Symbol;                 // array of duplicate symbols
-    DWORD            SelectedSymbol;         // symbol selected (-1 to start)
-} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL;
-#endif
-
-// If dbghelp ever needs to display graphical UI, it will use this as the parent window.
-
-BOOL
-IMAGEAPI
-SymSetParentWindow(
-    __in HWND hwnd
-    );
-
-PCHAR
-IMAGEAPI
-SymSetHomeDirectory(
-    __in_opt HANDLE hProcess,
-    __in_opt PCSTR dir
-    );
-
-PWSTR
-IMAGEAPI
-SymSetHomeDirectoryW(
-    __in_opt HANDLE hProcess,
-    __in_opt PCWSTR dir
-    );
-
-PCHAR
-IMAGEAPI
-SymGetHomeDirectory(
-    __in DWORD type,
-    __out_ecount(size) PSTR dir,
-    __in size_t size
-    );
-
-PWSTR
-IMAGEAPI
-SymGetHomeDirectoryW(
-    __in DWORD type,
-    __out_ecount(size) PWSTR dir,
-    __in size_t size
-    );
-
-typedef enum {
-    hdBase = 0, // root directory for dbghelp
-    hdSym,      // where symbols are stored
-    hdSrc,      // where source is stored
-    hdMax       // end marker
-};
-
-typedef struct _OMAP {
-    ULONG  rva;
-    ULONG  rvaTo;
-} OMAP, *POMAP;
-
-BOOL
-IMAGEAPI
-SymGetOmaps(
-    __in HANDLE hProcess,
-    __in DWORD64 BaseOfDll,
-    __out POMAP *OmapTo,
-    __out PDWORD64 cOmapTo,
-    __out POMAP *OmapFrom,
-    __out PDWORD64 cOmapFrom
-    );
-
-//
-// options that are set/returned by SymSetOptions() & SymGetOptions()
-// these are used as a mask
-//
-#define SYMOPT_CASE_INSENSITIVE          0x00000001
-#define SYMOPT_UNDNAME                   0x00000002
-#define SYMOPT_DEFERRED_LOADS            0x00000004
-#define SYMOPT_NO_CPP                    0x00000008
-#define SYMOPT_LOAD_LINES                0x00000010
-#define SYMOPT_OMAP_FIND_NEAREST         0x00000020
-#define SYMOPT_LOAD_ANYTHING             0x00000040
-#define SYMOPT_IGNORE_CVREC              0x00000080
-#define SYMOPT_NO_UNQUALIFIED_LOADS      0x00000100
-#define SYMOPT_FAIL_CRITICAL_ERRORS      0x00000200
-#define SYMOPT_EXACT_SYMBOLS             0x00000400
-#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS    0x00000800
-#define SYMOPT_IGNORE_NT_SYMPATH         0x00001000
-#define SYMOPT_INCLUDE_32BIT_MODULES     0x00002000
-#define SYMOPT_PUBLICS_ONLY              0x00004000
-#define SYMOPT_NO_PUBLICS                0x00008000
-#define SYMOPT_AUTO_PUBLICS              0x00010000
-#define SYMOPT_NO_IMAGE_SEARCH           0x00020000
-#define SYMOPT_SECURE                    0x00040000
-#define SYMOPT_NO_PROMPTS                0x00080000
-#define SYMOPT_OVERWRITE                 0x00100000
-#define SYMOPT_IGNORE_IMAGEDIR           0x00200000
-#define SYMOPT_FLAT_DIRECTORY            0x00400000
-#define SYMOPT_FAVOR_COMPRESSED          0x00800000
-#define SYMOPT_ALLOW_ZERO_ADDRESS        0x01000000
-#define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000
-
-#define SYMOPT_DEBUG                     0x80000000
-
-DWORD
-IMAGEAPI
-SymSetOptions(
-    __in DWORD   SymOptions
-    );
-
-DWORD
-IMAGEAPI
-SymGetOptions(
-    VOID
-    );
-
-BOOL
-IMAGEAPI
-SymCleanup(
-    __in HANDLE hProcess
-    );
-
-BOOL
-IMAGEAPI
-SymMatchString(
-    __in PCSTR string,
-    __in PCSTR expression,
-    __in BOOL fCase
-    );
-
-BOOL
-IMAGEAPI
-SymMatchStringA(
-    __in PCSTR string,
-    __in PCSTR expression,
-    __in BOOL fCase
-    );
-
-BOOL
-IMAGEAPI
-SymMatchStringW(
-    __in PCWSTR string,
-    __in PCWSTR expression,
-    __in BOOL fCase
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACK)(
-    __in PSOURCEFILE pSourceFile,
-    __in_opt PVOID UserContext
-    );
-
-// for backwards compatibility - don't use this
-#define PSYM_ENUMSOURCFILES_CALLBACK PSYM_ENUMSOURCEFILES_CALLBACK
-
-BOOL
-IMAGEAPI
-SymEnumSourceFiles(
-    __in HANDLE hProcess,
-    __in ULONG64 ModBase,
-    __in_opt PCSTR Mask,
-    __in PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACKW)(
-    __in PSOURCEFILEW pSourceFile,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumSourceFilesW(
-    __in HANDLE hProcess,
-    __in ULONG64 ModBase,
-    __in_opt PCWSTR Mask,
-    __in PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumerateModules64(
-    __in HANDLE hProcess,
-    __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumerateModulesW64(
-    __in HANDLE hProcess,
-    __in PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback,
-    __in_opt PVOID UserContext
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymEnumerateModules SymEnumerateModules64
-#else
-BOOL
-IMAGEAPI
-SymEnumerateModules(
-    __in HANDLE hProcess,
-    __in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
-    __in_opt PVOID UserContext
-    );
-#endif
-
-BOOL
-IMAGEAPI
-EnumerateLoadedModulesEx(
-    __in HANDLE hProcess,
-    __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,
-    __in_opt PVOID UserContext
-    );
-    
-BOOL
-IMAGEAPI
-EnumerateLoadedModulesExW(
-    __in HANDLE hProcess,
-    __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-EnumerateLoadedModules64(
-    __in HANDLE hProcess,
-    __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-EnumerateLoadedModulesW64(
-    __in HANDLE hProcess,
-    __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback,
-    __in_opt PVOID UserContext
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define EnumerateLoadedModules EnumerateLoadedModules64
-#else
-BOOL
-IMAGEAPI
-EnumerateLoadedModules(
-    __in HANDLE hProcess,
-    __in PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
-    __in_opt PVOID UserContext
-    );
-#endif
-
-PVOID
-IMAGEAPI
-SymFunctionTableAccess64(
-    __in HANDLE hProcess,
-    __in DWORD64 AddrBase
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymFunctionTableAccess SymFunctionTableAccess64
-#else
-PVOID
-IMAGEAPI
-SymFunctionTableAccess(
-    __in HANDLE hProcess,
-    __in DWORD AddrBase
-    );
-#endif
-
-BOOL
-IMAGEAPI
-SymGetUnwindInfo(
-    __in HANDLE hProcess,
-    __in DWORD64 Address,
-    __out_bcount_opt(*Size) PVOID Buffer,
-    __inout PULONG Size
-    );
-
-BOOL
-IMAGEAPI
-SymGetModuleInfo64(
-    __in HANDLE hProcess,
-    __in DWORD64 qwAddr,
-    __out PIMAGEHLP_MODULE64 ModuleInfo
-    );
-
-BOOL
-IMAGEAPI
-SymGetModuleInfoW64(
-    __in HANDLE hProcess,
-    __in DWORD64 qwAddr,
-    __out PIMAGEHLP_MODULEW64 ModuleInfo
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetModuleInfo   SymGetModuleInfo64
-#define SymGetModuleInfoW  SymGetModuleInfoW64
-#else
-BOOL
-IMAGEAPI
-SymGetModuleInfo(
-    __in HANDLE hProcess,
-    __in DWORD dwAddr,
-    __out PIMAGEHLP_MODULE ModuleInfo
-    );
-
-BOOL
-IMAGEAPI
-SymGetModuleInfoW(
-    __in HANDLE hProcess,
-    __in DWORD dwAddr,
-    __out PIMAGEHLP_MODULEW ModuleInfo
-    );
-#endif
-
-DWORD64
-IMAGEAPI
-SymGetModuleBase64(
-    __in HANDLE hProcess,
-    __in DWORD64 qwAddr
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetModuleBase SymGetModuleBase64
-#else
-DWORD
-IMAGEAPI
-SymGetModuleBase(
-    __in HANDLE hProcess,
-    __in DWORD dwAddr
-    );
-#endif
-
-typedef struct _SRCCODEINFO {
-    DWORD   SizeOfStruct;           // set to sizeof(SRCCODEINFO)
-    PVOID   Key;                    // not used
-    DWORD64 ModBase;                // base address of module this applies to
-    CHAR    Obj[MAX_PATH + 1];      // the object file within the module
-    CHAR    FileName[MAX_PATH + 1]; // full filename
-    DWORD   LineNumber;             // line number in file
-    DWORD64 Address;                // first instruction of line
-} SRCCODEINFO, *PSRCCODEINFO;
-
-typedef struct _SRCCODEINFOW {
-    DWORD   SizeOfStruct;           // set to sizeof(SRCCODEINFO)
-    PVOID   Key;                    // not used
-    DWORD64 ModBase;                // base address of module this applies to
-    WCHAR   Obj[MAX_PATH + 1];      // the object file within the module
-    WCHAR   FileName[MAX_PATH + 1]; // full filename
-    DWORD   LineNumber;             // line number in file
-    DWORD64 Address;                // first instruction of line
-} SRCCODEINFOW, *PSRCCODEINFOW;
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMLINES_CALLBACK)(
-    __in PSRCCODEINFO LineInfo,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumLines(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in_opt PCSTR Obj,
-    __in_opt PCSTR File,
-    __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMLINES_CALLBACKW)(
-    __in PSRCCODEINFOW LineInfo,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumLinesW(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in_opt PCWSTR Obj,
-    __in_opt PCWSTR File,
-    __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymGetLineFromAddr64(
-    __in HANDLE hProcess,
-    __in DWORD64 qwAddr,
-    __out PDWORD pdwDisplacement,
-    __out PIMAGEHLP_LINE64 Line64
-    );
-
-BOOL
-IMAGEAPI
-SymGetLineFromAddrW64(
-    __in HANDLE hProcess,
-    __in DWORD64 dwAddr,
-    __out PDWORD pdwDisplacement,
-    __out PIMAGEHLP_LINEW64 Line
-    );
-
-BOOL
-IMAGEAPI
-SymEnumSourceLines(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in_opt PCSTR Obj,
-    __in_opt PCSTR File,
-    __in_opt DWORD Line,
-    __in DWORD Flags,
-    __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumSourceLinesW(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in_opt PCWSTR Obj,
-    __in_opt PCWSTR File,
-    __in_opt DWORD Line,
-    __in DWORD Flags,
-    __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback,
-    __in_opt PVOID UserContext
-    );
-
-// flags for SymEnumSourceLines
-
-#define ESLFLAG_FULLPATH        0x1
-#define ESLFLAG_NEAREST         0x2
-#define ESLFLAG_PREV            0x4
-#define ESLFLAG_NEXT            0x8
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetLineFromAddr SymGetLineFromAddr64
-#define SymGetLineFromAddrW SymGetLineFromAddrW64
-#else
-BOOL
-IMAGEAPI
-SymGetLineFromAddr(
-    __in HANDLE hProcess,
-    __in DWORD dwAddr,
-    __out PDWORD pdwDisplacement,
-    __out PIMAGEHLP_LINE Line
-    );
-
-BOOL
-IMAGEAPI
-SymGetLineFromAddrW(
-    __in HANDLE hProcess,
-    __in DWORD dwAddr,
-    __out PDWORD pdwDisplacement,
-    __out PIMAGEHLP_LINEW Line
-    );
-#endif
-
-BOOL
-IMAGEAPI
-SymGetLineFromName64(
-    __in HANDLE hProcess,
-    __in_opt PCSTR ModuleName,
-    __in_opt PCSTR FileName,
-    __in DWORD dwLineNumber,
-    __out PLONG plDisplacement,
-    __inout PIMAGEHLP_LINE64 Line
-    );
-
-BOOL
-IMAGEAPI
-SymGetLineFromNameW64(
-    __in HANDLE hProcess,
-    __in_opt PCWSTR ModuleName,
-    __in_opt PCWSTR FileName,
-    __in DWORD dwLineNumber,
-    __out PLONG plDisplacement,
-    __inout PIMAGEHLP_LINEW64 Line
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetLineFromName SymGetLineFromName64
-#else
-BOOL
-IMAGEAPI
-SymGetLineFromName(
-    __in HANDLE hProcess,
-    __in_opt PCSTR ModuleName,
-    __in_opt PCSTR FileName,
-    __in DWORD dwLineNumber,
-    __out PLONG plDisplacement,
-    __inout PIMAGEHLP_LINE Line
-    );
-#endif
-
-BOOL
-IMAGEAPI
-SymGetLineNext64(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_LINE64 Line
-    );
-
-BOOL
-IMAGEAPI
-SymGetLineNextW64(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_LINEW64 Line
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetLineNext SymGetLineNext64
-#else
-BOOL
-IMAGEAPI
-SymGetLineNext(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_LINE Line
-    );
-
-BOOL
-IMAGEAPI
-SymGetLineNextW(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_LINEW Line
-    );
-#endif
-
-BOOL
-IMAGEAPI
-SymGetLinePrev64(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_LINE64 Line
-    );
-
-BOOL
-IMAGEAPI
-SymGetLinePrevW64(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_LINEW64 Line
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetLinePrev SymGetLinePrev64
-#else
-BOOL
-IMAGEAPI
-SymGetLinePrev(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_LINE Line
-    );
-
-BOOL
-IMAGEAPI
-SymGetLinePrevW(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_LINEW Line
-    );
-#endif
-
-ULONG
-IMAGEAPI
-SymGetFileLineOffsets64(
-    __in HANDLE hProcess,
-    __in_opt PCSTR ModuleName,
-    __in PCSTR FileName,
-    __out_ecount(BufferLines) PDWORD64 Buffer,
-    __in ULONG BufferLines
-    );
-
-BOOL
-IMAGEAPI
-SymMatchFileName(
-    __in PCSTR FileName,
-    __in PCSTR Match,
-    __deref_opt_out PSTR *FileNameStop,
-    __deref_opt_out PSTR *MatchStop
-    );
-
-BOOL
-IMAGEAPI
-SymMatchFileNameW(
-    __in PCWSTR FileName,
-    __in PCWSTR Match,
-    __deref_opt_out PWSTR *FileNameStop,
-    __deref_opt_out PWSTR *MatchStop
-    );
-
-BOOL
-IMAGEAPI
-SymGetSourceFile(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in_opt PCSTR Params,
-    __in PCSTR FileSpec,
-    __out_ecount(Size) PSTR FilePath,
-    __in DWORD Size
-    );
-
-BOOL
-IMAGEAPI
-SymGetSourceFileW(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in_opt PCWSTR Params,
-    __in PCWSTR FileSpec,
-    __out_ecount(Size) PWSTR FilePath,
-    __in DWORD Size
-    );
-
-BOOL
-IMAGEAPI
-SymGetSourceFileToken(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in PCSTR FileSpec,
-    __deref_out PVOID *Token,
-    __out DWORD *Size
-    );
-
-BOOL
-IMAGEAPI
-SymGetSourceFileTokenW(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in PCWSTR FileSpec,
-    __deref_out PVOID *Token,
-    __out DWORD *Size
-    );
-
-BOOL
-IMAGEAPI
-SymGetSourceFileFromToken(
-    __in HANDLE hProcess,
-    __in PVOID Token,
-    __in_opt PCSTR Params,
-    __out_ecount(Size) PSTR FilePath,
-    __in DWORD Size
-    );
-
-BOOL
-IMAGEAPI
-SymGetSourceFileFromTokenW(
-    __in HANDLE hProcess,
-    __in PVOID Token,
-    __in_opt PCWSTR Params,
-    __out_ecount(Size) PWSTR FilePath,
-    __in DWORD Size
-    );
-
-BOOL
-IMAGEAPI
-SymGetSourceVarFromToken(
-    __in HANDLE hProcess,
-    __in PVOID Token,
-    __in_opt PCSTR Params,
-    __in PCSTR VarName,
-    __out_ecount(Size) PSTR Value,
-    __in DWORD Size
-    );
-
-BOOL
-IMAGEAPI
-SymGetSourceVarFromTokenW(
-    __in HANDLE hProcess,
-    __in PVOID Token,
-    __in_opt PCWSTR Params,
-    __in PCWSTR VarName,
-    __out_ecount(Size) PWSTR Value,
-    __in DWORD Size
-    );
-
-typedef BOOL (CALLBACK *PENUMSOURCEFILETOKENSCALLBACK)(__in PVOID token,  __in size_t size);
-
-BOOL
-IMAGEAPI
-SymEnumSourceFileTokens(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in PENUMSOURCEFILETOKENSCALLBACK Callback
-    );
-
-BOOL
-IMAGEAPI
-SymInitialize(
-    __in HANDLE hProcess,
-    __in_opt PCSTR UserSearchPath,
-    __in BOOL fInvadeProcess
-    );
-
-BOOL
-IMAGEAPI
-SymInitializeW(
-    __in HANDLE hProcess,
-    __in_opt PCWSTR UserSearchPath,
-    __in BOOL fInvadeProcess
-    );
-
-BOOL
-IMAGEAPI
-SymGetSearchPath(
-    __in HANDLE hProcess,
-    __out_ecount(SearchPathLength) PSTR SearchPath,
-    __in DWORD SearchPathLength
-    );
-
-BOOL
-IMAGEAPI
-SymGetSearchPathW(
-    __in HANDLE hProcess,
-    __out_ecount(SearchPathLength) PWSTR SearchPath,
-    __in DWORD SearchPathLength
-    );
-
-BOOL
-IMAGEAPI
-SymSetSearchPath(
-    __in HANDLE hProcess,
-    __in_opt PCSTR SearchPath
-    );
-
-BOOL
-IMAGEAPI
-SymSetSearchPathW(
-    __in HANDLE hProcess,
-    __in_opt PCWSTR SearchPath
-    );
-
-#define SLMFLAG_VIRTUAL     0x1
-#define SLMFLAG_ALT_INDEX   0x2
-#define SLMFLAG_NO_SYMBOLS  0x4
-
-DWORD64
-IMAGEAPI
-SymLoadModuleEx(
-    __in HANDLE hProcess,
-    __in_opt HANDLE hFile,
-    __in_opt PCSTR ImageName,
-    __in_opt PCSTR ModuleName,
-    __in DWORD64 BaseOfDll,
-    __in DWORD DllSize,
-    __in_opt PMODLOAD_DATA Data,
-    __in_opt DWORD Flags
-    );
-
-DWORD64
-IMAGEAPI
-SymLoadModuleExW(
-    __in HANDLE hProcess,
-    __in_opt HANDLE hFile,
-    __in_opt PCWSTR ImageName,
-    __in_opt PCWSTR ModuleName,
-    __in DWORD64 BaseOfDll,
-    __in DWORD DllSize,
-    __in_opt PMODLOAD_DATA Data,
-    __in_opt DWORD Flags
-    );
-
-BOOL
-IMAGEAPI
-SymUnloadModule64(
-    __in HANDLE hProcess,
-    __in DWORD64 BaseOfDll
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymUnloadModule SymUnloadModule64
-#else
-BOOL
-IMAGEAPI
-SymUnloadModule(
-    __in HANDLE hProcess,
-    __in DWORD BaseOfDll
-    );
-#endif
-
-BOOL
-IMAGEAPI
-SymUnDName64(
-    __in PIMAGEHLP_SYMBOL64 sym,            // Symbol to undecorate
-    __out_ecount(UnDecNameLength) PSTR UnDecName,   // Buffer to store undecorated name in
-    __in DWORD UnDecNameLength              // Size of the buffer
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymUnDName SymUnDName64
-#else
-BOOL
-IMAGEAPI
-SymUnDName(
-    __in PIMAGEHLP_SYMBOL sym,              // Symbol to undecorate
-    __out_ecount(UnDecNameLength) PSTR UnDecName,   // Buffer to store undecorated name in
-    __in DWORD UnDecNameLength              // Size of the buffer
-    );
-#endif
-
-BOOL
-IMAGEAPI
-SymRegisterCallback64(
-    __in HANDLE hProcess,
-    __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
-    __in ULONG64 UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymRegisterCallbackW64(
-    __in HANDLE hProcess,
-    __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
-    __in ULONG64 UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymRegisterFunctionEntryCallback64(
-    __in HANDLE hProcess,
-    __in PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction,
-    __in ULONG64 UserContext
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymRegisterCallback SymRegisterCallback64
-#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64
-#else
-BOOL
-IMAGEAPI
-SymRegisterCallback(
-    __in HANDLE hProcess,
-    __in PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymRegisterFunctionEntryCallback(
-    __in HANDLE hProcess,
-    __in PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction,
-    __in_opt PVOID UserContext
-    );
-#endif
-
-
-typedef struct _IMAGEHLP_SYMBOL_SRC {
-    DWORD sizeofstruct;
-    DWORD type;
-    char  file[MAX_PATH];
-} IMAGEHLP_SYMBOL_SRC, *PIMAGEHLP_SYMBOL_SRC;
-
-typedef struct _MODULE_TYPE_INFO { // AKA TYPTYP
-    USHORT      dataLength;
-    USHORT      leaf;
-    BYTE        data[1];
-} MODULE_TYPE_INFO, *PMODULE_TYPE_INFO;
-
-typedef struct _SYMBOL_INFO {
-    ULONG       SizeOfStruct;
-    ULONG       TypeIndex;        // Type Index of symbol
-    ULONG64     Reserved[2];
-    ULONG       Index;
-    ULONG       Size;
-    ULONG64     ModBase;          // Base Address of module comtaining this symbol
-    ULONG       Flags;
-    ULONG64     Value;            // Value of symbol, ValuePresent should be 1
-    ULONG64     Address;          // Address of symbol including base address of module
-    ULONG       Register;         // register holding value or pointer to value
-    ULONG       Scope;            // scope of the symbol
-    ULONG       Tag;              // pdb classification
-    ULONG       NameLen;          // Actual length of name
-    ULONG       MaxNameLen;
-    CHAR        Name[1];          // Name of symbol
-} SYMBOL_INFO, *PSYMBOL_INFO;
-
-typedef struct _SYMBOL_INFO_PACKAGE {
-    SYMBOL_INFO si;
-    CHAR        name[MAX_SYM_NAME + 1];
-} SYMBOL_INFO_PACKAGE, *PSYMBOL_INFO_PACKAGE;
-
-typedef struct _SYMBOL_INFOW {
-    ULONG       SizeOfStruct;
-    ULONG       TypeIndex;        // Type Index of symbol
-    ULONG64     Reserved[2];
-    ULONG       Index;
-    ULONG       Size;
-    ULONG64     ModBase;          // Base Address of module comtaining this symbol
-    ULONG       Flags;
-    ULONG64     Value;            // Value of symbol, ValuePresent should be 1
-    ULONG64     Address;          // Address of symbol including base address of module
-    ULONG       Register;         // register holding value or pointer to value
-    ULONG       Scope;            // scope of the symbol
-    ULONG       Tag;              // pdb classification
-    ULONG       NameLen;          // Actual length of name
-    ULONG       MaxNameLen;
-    WCHAR       Name[1];          // Name of symbol
-} SYMBOL_INFOW, *PSYMBOL_INFOW;
-
-typedef struct _SYMBOL_INFO_PACKAGEW {
-    SYMBOL_INFOW si;
-    WCHAR        name[MAX_SYM_NAME + 1];
-} SYMBOL_INFO_PACKAGEW, *PSYMBOL_INFO_PACKAGEW;
-
-typedef struct _IMAGEHLP_STACK_FRAME
-{
-    ULONG64 InstructionOffset;
-    ULONG64 ReturnOffset;
-    ULONG64 FrameOffset;
-    ULONG64 StackOffset;
-    ULONG64 BackingStoreOffset;
-    ULONG64 FuncTableEntry;
-    ULONG64 Params[4];
-    ULONG64 Reserved[5];
-    BOOL    Virtual;
-    ULONG   Reserved2;
-} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME;
-
-typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT;
-
-
-BOOL
-IMAGEAPI
-SymSetContext(
-    __in HANDLE hProcess,
-    __in PIMAGEHLP_STACK_FRAME StackFrame,
-    __in_opt PIMAGEHLP_CONTEXT Context
-    );
-
-BOOL
-IMAGEAPI
-SymSetScopeFromAddr(
-    __in HANDLE hProcess,
-    __in ULONG64 Address
-    );
-
-BOOL
-IMAGEAPI
-SymSetScopeFromIndex(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in DWORD Index
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMPROCESSES_CALLBACK)(
-    __in HANDLE hProcess,
-    __in PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumProcesses(
-    __in PSYM_ENUMPROCESSES_CALLBACK EnumProcessesCallback,
-    __in PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymFromAddr(
-    __in HANDLE hProcess,
-    __in DWORD64 Address,
-    __out_opt PDWORD64 Displacement,
-    __inout PSYMBOL_INFO Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymFromAddrW(
-    __in HANDLE hProcess,
-    __in DWORD64 Address,
-    __out_opt PDWORD64 Displacement,
-    __inout PSYMBOL_INFOW Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymFromToken(
-    __in HANDLE hProcess,
-    __in DWORD64 Base,
-    __in DWORD Token,
-    __inout PSYMBOL_INFO Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymFromTokenW(
-    __in HANDLE hProcess,
-    __in DWORD64 Base,
-    __in DWORD Token,
-    __inout PSYMBOL_INFOW Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymNext(
-    __in HANDLE hProcess,
-    __inout PSYMBOL_INFO si
-    );
-
-BOOL
-IMAGEAPI
-SymNextW(
-    __in HANDLE hProcess,
-    __inout PSYMBOL_INFOW siw
-    );
-
-BOOL
-IMAGEAPI
-SymPrev(
-    __in HANDLE hProcess,
-    __inout PSYMBOL_INFO si
-    );
-
-BOOL
-IMAGEAPI
-SymPrevW(
-    __in HANDLE hProcess,
-    __inout PSYMBOL_INFOW siw
-    );
-
-// While SymFromName will provide a symbol from a name,
-// SymEnumSymbols can provide the same matching information
-// for ALL symbols with a matching name, even regular
-// expressions.  That way you can search across modules
-// and differentiate between identically named symbols.
-
-BOOL
-IMAGEAPI
-SymFromName(
-    __in HANDLE hProcess,
-    __in PCSTR Name,
-    __inout PSYMBOL_INFO Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymFromNameW(
-    __in HANDLE hProcess,
-    __in PCWSTR Name,
-    __inout PSYMBOL_INFOW Symbol
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)(
-    __in PSYMBOL_INFO pSymInfo,
-    __in ULONG SymbolSize,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumSymbols(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in_opt PCSTR Mask,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-typedef BOOL
-(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACKW)(
-    __in PSYMBOL_INFOW pSymInfo,
-    __in ULONG SymbolSize,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumSymbolsW(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in_opt PCWSTR Mask,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumSymbolsForAddr(
-    __in HANDLE hProcess,
-    __in DWORD64 Address,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumSymbolsForAddrW(
-    __in HANDLE hProcess,
-    __in DWORD64 Address,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-#define SYMSEARCH_MASKOBJS      0x01    // used internally to implement other APIs
-#define SYMSEARCH_RECURSE       0X02    // recurse scopes
-#define SYMSEARCH_GLOBALSONLY   0X04    // search only for global symbols
-#define SYMSEARCH_ALLITEMS      0X08    // search for everything in the pdb, not just normal scoped symbols
-
-BOOL
-IMAGEAPI
-SymSearch(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in_opt DWORD Index,
-    __in_opt DWORD SymTag,
-    __in_opt PCSTR Mask,
-    __in_opt DWORD64 Address,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
-    __in_opt PVOID UserContext,
-    __in DWORD Options
-    );
-
-BOOL
-IMAGEAPI
-SymSearchW(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in_opt DWORD Index,
-    __in_opt DWORD SymTag,
-    __in_opt PCWSTR Mask,
-    __in_opt DWORD64 Address,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
-    __in_opt PVOID UserContext,
-    __in DWORD Options
-    );
-
-BOOL
-IMAGEAPI
-SymGetScope(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in DWORD Index,
-    __inout PSYMBOL_INFO Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymGetScopeW(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in DWORD Index,
-    __inout PSYMBOL_INFOW Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymFromIndex(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in DWORD Index,
-    __inout PSYMBOL_INFO Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymFromIndexW(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in DWORD Index,
-    __inout PSYMBOL_INFOW Symbol
-    );
-
-typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO {
-    TI_GET_SYMTAG,
-    TI_GET_SYMNAME,
-    TI_GET_LENGTH,
-    TI_GET_TYPE,
-    TI_GET_TYPEID,
-    TI_GET_BASETYPE,
-    TI_GET_ARRAYINDEXTYPEID,
-    TI_FINDCHILDREN,
-    TI_GET_DATAKIND,
-    TI_GET_ADDRESSOFFSET,
-    TI_GET_OFFSET,
-    TI_GET_VALUE,
-    TI_GET_COUNT,
-    TI_GET_CHILDRENCOUNT,
-    TI_GET_BITPOSITION,
-    TI_GET_VIRTUALBASECLASS,
-    TI_GET_VIRTUALTABLESHAPEID,
-    TI_GET_VIRTUALBASEPOINTEROFFSET,
-    TI_GET_CLASSPARENTID,
-    TI_GET_NESTED,
-    TI_GET_SYMINDEX,
-    TI_GET_LEXICALPARENT,
-    TI_GET_ADDRESS,
-    TI_GET_THISADJUST,
-    TI_GET_UDTKIND,
-    TI_IS_EQUIV_TO,
-    TI_GET_CALLING_CONVENTION,
-    TI_IS_CLOSE_EQUIV_TO,
-    TI_GTIEX_REQS_VALID,
-    TI_GET_VIRTUALBASEOFFSET,
-    TI_GET_VIRTUALBASEDISPINDEX,
-    TI_GET_IS_REFERENCE,
-    TI_GET_INDIRECTVIRTUALBASECLASS,
-    IMAGEHLP_SYMBOL_TYPE_INFO_MAX,
-} IMAGEHLP_SYMBOL_TYPE_INFO;
-
-typedef struct _TI_FINDCHILDREN_PARAMS {
-    ULONG Count;
-    ULONG Start;
-    ULONG ChildId[1];
-} TI_FINDCHILDREN_PARAMS;
-
-BOOL
-IMAGEAPI
-SymGetTypeInfo(
-    __in HANDLE hProcess,
-    __in DWORD64 ModBase,
-    __in ULONG TypeId,
-    __in IMAGEHLP_SYMBOL_TYPE_INFO GetType,
-    __out PVOID pInfo
-    );
-
-#define IMAGEHLP_GET_TYPE_INFO_UNCACHED 0x00000001
-#define IMAGEHLP_GET_TYPE_INFO_CHILDREN 0x00000002
-
-typedef struct _IMAGEHLP_GET_TYPE_INFO_PARAMS {
-    IN  ULONG    SizeOfStruct;
-    IN  ULONG    Flags;
-    IN  ULONG    NumIds;
-    IN  PULONG   TypeIds;
-    IN  ULONG64  TagFilter;
-    IN  ULONG    NumReqs;
-    IN  IMAGEHLP_SYMBOL_TYPE_INFO* ReqKinds;
-    IN  PULONG_PTR ReqOffsets;
-    IN  PULONG   ReqSizes;
-    IN  ULONG_PTR ReqStride;
-    IN  ULONG_PTR BufferSize;
-    OUT PVOID    Buffer;
-    OUT ULONG    EntriesMatched;
-    OUT ULONG    EntriesFilled;
-    OUT ULONG64  TagsFound;
-    OUT ULONG64  AllReqsValid;
-    IN  ULONG    NumReqsValid;
-    OUT PULONG64 ReqsValid OPTIONAL;
-} IMAGEHLP_GET_TYPE_INFO_PARAMS, *PIMAGEHLP_GET_TYPE_INFO_PARAMS;
-
-BOOL
-IMAGEAPI
-SymGetTypeInfoEx(
-    __in HANDLE hProcess,
-    __in DWORD64 ModBase,
-    __inout PIMAGEHLP_GET_TYPE_INFO_PARAMS Params
-    );
-
-BOOL
-IMAGEAPI
-SymEnumTypes(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumTypesW(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumTypesByName(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in_opt PCSTR mask,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymEnumTypesByNameW(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in_opt PCWSTR mask,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-BOOL
-IMAGEAPI
-SymGetTypeFromName(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in PCSTR Name,
-    __inout PSYMBOL_INFO Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymGetTypeFromNameW(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in PCWSTR Name,
-    __inout PSYMBOL_INFOW Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymAddSymbol(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in PCSTR Name,
-    __in DWORD64 Address,
-    __in DWORD Size,
-    __in DWORD Flags
-    );
-
-BOOL
-IMAGEAPI
-SymAddSymbolW(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in PCWSTR Name,
-    __in DWORD64 Address,
-    __in DWORD Size,
-    __in DWORD Flags
-    );
-
-BOOL
-IMAGEAPI
-SymDeleteSymbol(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in_opt PCSTR Name,
-    __in DWORD64 Address,
-    __in DWORD Flags
-    );
-
-BOOL
-IMAGEAPI
-SymDeleteSymbolW(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in_opt PCWSTR Name,
-    __in DWORD64 Address,
-    __in DWORD Flags
-    );
-
-BOOL
-IMAGEAPI
-SymRefreshModuleList(
-    __in HANDLE hProcess
-    );
-
-BOOL
-IMAGEAPI
-SymAddSourceStream(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in_opt PCSTR StreamFile,
-    __in_bcount_opt(Size) PBYTE Buffer,
-    __in size_t Size
-    );
-
-typedef BOOL (WINAPI *SYMADDSOURCESTREAM)(HANDLE, ULONG64, PCSTR, PBYTE, size_t);
-
-BOOL
-IMAGEAPI
-SymAddSourceStreamA(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in_opt PCSTR StreamFile,
-    __in_bcount_opt(Size) PBYTE Buffer,
-    __in size_t Size
-    );
-
-typedef BOOL (WINAPI *SYMADDSOURCESTREAMA)(HANDLE, ULONG64, PCSTR, PBYTE, size_t);
-
-BOOL
-IMAGEAPI
-SymAddSourceStreamW(
-    __in HANDLE hProcess,
-    __in ULONG64 Base,
-    __in_opt PCWSTR FileSpec,
-    __in_bcount_opt(Size) PBYTE Buffer,
-    __in size_t Size
-    );
-
-BOOL
-IMAGEAPI
-SymSrvIsStoreW(
-    __in_opt HANDLE hProcess,
-    __in PCWSTR path
-    );
-
-BOOL
-IMAGEAPI
-SymSrvIsStore(
-    __in_opt HANDLE hProcess,
-    __in PCSTR path
-    );
-
-PCSTR
-IMAGEAPI
-SymSrvDeltaName(
-    __in HANDLE hProcess,
-    __in_opt PCSTR SymPath,
-    __in PCSTR Type,
-    __in PCSTR File1,
-    __in PCSTR File2
-    );
-
-PCWSTR
-IMAGEAPI
-SymSrvDeltaNameW(
-    __in HANDLE hProcess,
-    __in_opt PCWSTR SymPath,
-    __in PCWSTR Type,
-    __in PCWSTR File1,
-    __in PCWSTR File2
-    );
-
-PCSTR
-IMAGEAPI
-SymSrvGetSupplement(
-    __in HANDLE hProcess,
-    __in_opt PCSTR SymPath,
-    __in PCSTR Node,
-    __in PCSTR File
-    );
-
-PCWSTR
-IMAGEAPI
-SymSrvGetSupplementW(
-    __in HANDLE hProcess,
-    __in_opt PCWSTR SymPath,
-    __in PCWSTR Node,
-    __in PCWSTR File
-    );
-
-BOOL
-IMAGEAPI
-SymSrvGetFileIndexes(
-    __in PCSTR File,
-    __out GUID *Id,
-    __out PDWORD Val1,
-    __out_opt PDWORD Val2,
-    __in DWORD Flags
-    );
-
-BOOL
-IMAGEAPI
-SymSrvGetFileIndexesW(
-    __in PCWSTR File,
-    __out GUID *Id,
-    __out PDWORD Val1,
-    __out_opt PDWORD Val2,
-    __in DWORD Flags
-    );
-
-BOOL
-IMAGEAPI
-SymSrvGetFileIndexStringW(
-    __in HANDLE hProcess,
-    __in_opt PCWSTR SrvPath,
-    __in PCWSTR File,
-    __out_ecount(Size) PWSTR Index,
-    __in size_t Size,
-    __in DWORD Flags
-    );
-
-BOOL
-IMAGEAPI
-SymSrvGetFileIndexString(
-    __in HANDLE hProcess,
-    __in_opt PCSTR SrvPath,
-    __in PCSTR File,
-    __out_ecount(Size) PSTR Index,
-    __in size_t Size,
-    __in DWORD Flags
-    );
-
-typedef struct {
-    DWORD sizeofstruct;
-    char file[MAX_PATH +1];
-    BOOL  stripped;
-    DWORD timestamp;
-    DWORD size;
-    char dbgfile[MAX_PATH +1];
-    char pdbfile[MAX_PATH + 1];
-    GUID  guid;
-    DWORD sig;
-    DWORD age;
-} SYMSRV_INDEX_INFO, *PSYMSRV_INDEX_INFO;
-
-typedef struct {
-    DWORD sizeofstruct;
-    WCHAR file[MAX_PATH +1];
-    BOOL  stripped;
-    DWORD timestamp;
-    DWORD size;
-    WCHAR dbgfile[MAX_PATH +1];
-    WCHAR pdbfile[MAX_PATH + 1];
-    GUID  guid;
-    DWORD sig;
-    DWORD age;
-} SYMSRV_INDEX_INFOW, *PSYMSRV_INDEX_INFOW;
-
-BOOL
-IMAGEAPI
-SymSrvGetFileIndexInfo(
-    __in PCSTR File,
-    __out PSYMSRV_INDEX_INFO Info,
-    __in DWORD Flags
-    );
-
-BOOL
-IMAGEAPI
-SymSrvGetFileIndexInfoW(
-    __in PCWSTR File,
-    __out PSYMSRV_INDEX_INFOW Info,
-    __in DWORD Flags
-    );
-
-PCSTR
-IMAGEAPI
-SymSrvStoreSupplement(
-    __in HANDLE hProcess,
-    __in_opt PCSTR SrvPath,
-    __in PCSTR Node,
-    __in PCSTR File,
-    __in DWORD Flags
-    );
-
-PCWSTR
-IMAGEAPI
-SymSrvStoreSupplementW(
-    __in HANDLE hProcess,
-    __in_opt PCWSTR SymPath,
-    __in PCWSTR Node,
-    __in PCWSTR File,
-    __in DWORD Flags
-    );
-
-PCSTR
-IMAGEAPI
-SymSrvStoreFile(
-    __in HANDLE hProcess,
-    __in_opt PCSTR SrvPath,
-    __in PCSTR File,
-    __in DWORD Flags
-    );
-
-PCWSTR
-IMAGEAPI
-SymSrvStoreFileW(
-    __in HANDLE hProcess,
-    __in_opt PCWSTR SrvPath,
-    __in PCWSTR File,
-    __in DWORD Flags
-    );
-
-// used by SymGetSymbolFile's "Type" parameter
-
-typedef enum {
-    sfImage = 0,
-    sfDbg,
-    sfPdb,
-    sfMpd,
-    sfMax
-};
-
-BOOL
-IMAGEAPI
-SymGetSymbolFile(
-    __in_opt HANDLE hProcess,
-    __in_opt PCSTR SymPath,
-    __in PCSTR ImageFile,
-    __in DWORD Type,
-    __out_ecount(cSymbolFile) PSTR SymbolFile,
-    __in size_t cSymbolFile,
-    __out_ecount(cDbgFile) PSTR DbgFile,
-    __in size_t cDbgFile
-    );
-
-BOOL
-IMAGEAPI
-SymGetSymbolFileW(
-    __in_opt HANDLE hProcess,
-    __in_opt PCWSTR SymPath,
-    __in PCWSTR ImageFile,
-    __in DWORD Type,
-    __out_ecount(cSymbolFile) PWSTR SymbolFile,
-    __in size_t cSymbolFile,
-    __out_ecount(cDbgFile) PWSTR DbgFile,
-    __in size_t cDbgFile
-    );
-
-//
-// Full user-mode dump creation.
-//
-
-typedef BOOL (WINAPI *PDBGHELP_CREATE_USER_DUMP_CALLBACK)(
-    __in DWORD DataType,
-    __in PVOID* Data,
-    __out LPDWORD DataLength,
-    __in_opt PVOID UserData
-    );
-
-BOOL
-WINAPI
-DbgHelpCreateUserDump(
-    __in_opt LPCSTR FileName,
-    __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,
-    __in_opt PVOID UserData
-    );
-
-BOOL
-WINAPI
-DbgHelpCreateUserDumpW(
-    __in_opt LPCWSTR FileName,
-    __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,
-    __in_opt PVOID UserData
-    );
-
-// -----------------------------------------------------------------
-// The following 4 legacy APIs are fully supported, but newer
-// ones are recommended.  SymFromName and SymFromAddr provide
-// much more detailed info on the returned symbol.
-
-BOOL
-IMAGEAPI
-SymGetSymFromAddr64(
-    __in HANDLE hProcess,
-    __in DWORD64 qwAddr,
-    __out_opt PDWORD64 pdwDisplacement,
-    __inout PIMAGEHLP_SYMBOL64  Symbol
-    );
-
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetSymFromAddr SymGetSymFromAddr64
-#else
-BOOL
-IMAGEAPI
-SymGetSymFromAddr(
-    __in HANDLE hProcess,
-    __in DWORD dwAddr,
-    __out_opt PDWORD pdwDisplacement,
-    __inout PIMAGEHLP_SYMBOL Symbol
-    );
-#endif
-
-// While following two APIs will provide a symbol from a name,
-// SymEnumSymbols can provide the same matching information
-// for ALL symbols with a matching name, even regular
-// expressions.  That way you can search across modules
-// and differentiate between identically named symbols.
-
-BOOL
-IMAGEAPI
-SymGetSymFromName64(
-    __in HANDLE hProcess,
-    __in PCSTR Name,
-    __inout PIMAGEHLP_SYMBOL64 Symbol
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetSymFromName SymGetSymFromName64
-#else
-BOOL
-IMAGEAPI
-SymGetSymFromName(
-    __in HANDLE hProcess,
-    __in PCSTR Name,
-    __inout PIMAGEHLP_SYMBOL Symbol
-    );
-#endif
-
-
-// Symbol server exports
-
-typedef BOOL (WINAPI *PSYMBOLSERVERPROC)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVERPROCA)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVERPROCW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROC)(PCSTR, PCSTR, PCSTR, PSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCA)(PCSTR, PCSTR, PCSTR, PSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCW)(PCWSTR, PCWSTR, PCWSTR, PWSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVEROPENPROC)(VOID);
-typedef BOOL (WINAPI *PSYMBOLSERVERCLOSEPROC)(VOID);
-typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64);
-typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSWPROC)(UINT_PTR, ULONG64);
-typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action, ULONG64 data, ULONG64 context);
-typedef UINT_PTR (WINAPI *PSYMBOLSERVERGETOPTIONSPROC)();
-typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROC)(PCSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCA)(PCSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCW)(PCWSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVERGETVERSION)(LPAPI_VERSION);
-typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAME)(PCSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PSTR, size_t);
-typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAMEW)(PCWSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PWSTR, size_t);
-typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t);
-typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t);
-typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t, DWORD);
-typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t, DWORD);
-typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRING)(PVOID, DWORD, DWORD, PSTR, size_t);
-typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRINGW)(PVOID, DWORD, DWORD, PWSTR, size_t);
-typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILE)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR, size_t, DWORD);
-typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILEW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR, size_t, DWORD);
-typedef BOOL (WINAPI *PSYMBOLSERVERISSTORE)(PCSTR);
-typedef BOOL (WINAPI *PSYMBOLSERVERISSTOREW)(PCWSTR);
-typedef DWORD (WINAPI *PSYMBOLSERVERVERSION)();
-typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERMESSAGEPROC)(UINT_PTR action, ULONG64 data, ULONG64 context);
-
-#define SYMSRV_VERSION              2
-
-#define SSRVOPT_CALLBACK            0x00000001
-#define SSRVOPT_DWORD               0x00000002
-#define SSRVOPT_DWORDPTR            0x00000004
-#define SSRVOPT_GUIDPTR             0x00000008
-#define SSRVOPT_OLDGUIDPTR          0x00000010
-#define SSRVOPT_UNATTENDED          0x00000020
-#define SSRVOPT_NOCOPY              0x00000040
-#define SSRVOPT_GETPATH             0x00000040
-#define SSRVOPT_PARENTWIN           0x00000080
-#define SSRVOPT_PARAMTYPE           0x00000100
-#define SSRVOPT_SECURE              0x00000200
-#define SSRVOPT_TRACE               0x00000400
-#define SSRVOPT_SETCONTEXT          0x00000800
-#define SSRVOPT_PROXY               0x00001000
-#define SSRVOPT_DOWNSTREAM_STORE    0x00002000
-#define SSRVOPT_OVERWRITE           0x00004000
-#define SSRVOPT_RESETTOU            0x00008000
-#define SSRVOPT_CALLBACKW           0x00010000
-#define SSRVOPT_FLAT_DEFAULT_STORE  0x00020000
-#define SSRVOPT_PROXYW              0x00040000
-#define SSRVOPT_MESSAGE             0x00080000
-#define SSRVOPT_SERVICE             0x00100000   // deprecated
-#define SSRVOPT_FAVOR_COMPRESSED    0x00200000
-#define SSRVOPT_STRING              0x00400000
-#define SSRVOPT_WINHTTP             0x00800000
-#define SSRVOPT_WININET             0x01000000
-
-#define SSRVOPT_MAX                 0x0100000
-
-#define SSRVOPT_RESET               ((ULONG_PTR)-1)
-
-
-#define NUM_SSRVOPTS                30
-
-#define SSRVACTION_TRACE        1
-#define SSRVACTION_QUERYCANCEL  2
-#define SSRVACTION_EVENT        3
-#define SSRVACTION_EVENTW       4
-#define SSRVACTION_SIZE         5
-
-#define SYMSTOREOPT_COMPRESS        0x01
-#define SYMSTOREOPT_OVERWRITE       0x02
-#define SYMSTOREOPT_RETURNINDEX     0x04
-#define SYMSTOREOPT_POINTER         0x08
-#define SYMSTOREOPT_ALT_INDEX       0x10
-#define SYMSTOREOPT_UNICODE         0x20
-#define SYMSTOREOPT_PASS_IF_EXISTS  0x40
-
-#ifdef DBGHELP_TRANSLATE_TCHAR
- #define SymInitialize                     SymInitializeW
- #define SymAddSymbol                      SymAddSymbolW
- #define SymDeleteSymbol                   SymDeleteSymbolW
- #define SearchTreeForFile                 SearchTreeForFileW
- #define UnDecorateSymbolName              UnDecorateSymbolNameW
- #define SymGetLineFromName64              SymGetLineFromNameW64
- #define SymGetLineFromAddr64              SymGetLineFromAddrW64
- #define SymGetLineNext64                  SymGetLineNextW64
- #define SymGetLinePrev64                  SymGetLinePrevW64
- #define SymFromName                       SymFromNameW
- #define SymFindExecutableImage            SymFindExecutableImageW
- #define FindExecutableImageEx             FindExecutableImageExW
- #define SymSearch                         SymSearchW
- #define SymEnumLines                      SymEnumLinesW
- #define SymEnumSourceLines                SymEnumSourceLinesW
- #define SymGetTypeFromName                SymGetTypeFromNameW
- #define SymEnumSymbolsForAddr             SymEnumSymbolsForAddrW
- #define SymFromAddr                       SymFromAddrW
- #define SymMatchString                    SymMatchStringW
- #define SymEnumSourceFiles                SymEnumSourceFilesW
- #define SymEnumSymbols                    SymEnumSymbolsW
- #define SymLoadModuleEx                   SymLoadModuleExW
- #define SymSetSearchPath                  SymSetSearchPathW
- #define SymGetSearchPath                  SymGetSearchPathW
- #define EnumDirTree                       EnumDirTreeW
- #define SymFromToken                      SymFromTokenW
- #define SymFromIndex                      SymFromIndexW
- #define SymGetScope                       SymGetScopeW
- #define SymNext                           SymNextW
- #define SymPrev                           SymPrevW
- #define SymEnumTypes                      SymEnumTypesW
- #define SymEnumTypesByName                SymEnumTypesByNameW
- #define SymRegisterCallback64             SymRegisterCallbackW64
- #define SymFindDebugInfoFile              SymFindDebugInfoFileW
- #define FindDebugInfoFileEx               FindDebugInfoFileExW
- #define SymFindFileInPath                 SymFindFileInPathW
- #define SymEnumerateModules64             SymEnumerateModulesW64
- #define SymSetHomeDirectory               SymSetHomeDirectoryW
- #define SymGetHomeDirectory               SymGetHomeDirectoryW
- #define SymGetSourceFile                  SymGetSourceFileW
- #define SymGetSourceFileToken             SymGetSourceFileTokenW
- #define SymGetSourceFileFromToken         SymGetSourceFileFromTokenW
- #define SymGetSourceVarFromToken          SymGetSourceVarFromTokenW
- #define SymGetSourceFileToken             SymGetSourceFileTokenW
- #define SymGetFileLineOffsets64           SymGetFileLineOffsetsW64
- #define SymFindFileInPath                 SymFindFileInPathW
- #define SymMatchFileName                  SymMatchFileNameW
- #define SymGetSourceFileFromToken         SymGetSourceFileFromTokenW
- #define SymGetSourceVarFromToken          SymGetSourceVarFromTokenW
- #define SymGetModuleInfo64                SymGetModuleInfoW64
- #define SymSrvIsStore                     SymSrvIsStoreW
- #define SymSrvDeltaName                   SymSrvDeltaNameW
- #define SymSrvGetSupplement               SymSrvGetSupplementW
- #define SymSrvStoreSupplement             SymSrvStoreSupplementW
- #define SymSrvGetFileIndexes              SymSrvGetFileIndexes
- #define SymSrvGetFileIndexString          SymSrvGetFileIndexStringW
- #define SymSrvStoreFile                   SymSrvStoreFileW
- #define SymGetSymbolFile                  SymGetSymbolFileW
- #define EnumerateLoadedModules64          EnumerateLoadedModulesW64
- #define EnumerateLoadedModulesEx          EnumerateLoadedModulesExW
- #define SymSrvGetFileIndexInfo            SymSrvGetFileIndexInfoW
-
- #define IMAGEHLP_LINE64                   IMAGEHLP_LINEW64
- #define PIMAGEHLP_LINE64                  PIMAGEHLP_LINEW64
- #define SYMBOL_INFO                       SYMBOL_INFOW
- #define PSYMBOL_INFO                      PSYMBOL_INFOW
- #define SYMBOL_INFO_PACKAGE               SYMBOL_INFO_PACKAGEW
- #define PSYMBOL_INFO_PACKAGE              PSYMBOL_INFO_PACKAGEW
- #define FIND_EXE_FILE_CALLBACK            FIND_EXE_FILE_CALLBACKW
- #define PFIND_EXE_FILE_CALLBACK           PFIND_EXE_FILE_CALLBACKW
- #define SYM_ENUMERATESYMBOLS_CALLBACK     SYM_ENUMERATESYMBOLS_CALLBACKW
- #define PSYM_ENUMERATESYMBOLS_CALLBACK    PSYM_ENUMERATESYMBOLS_CALLBACKW
- #define SRCCODEINFO                       SRCCODEINFOW
- #define PSRCCODEINFO                      PSRCCODEINFOW
- #define SOURCEFILE                        SOURCEFILEW
- #define PSOURCEFILE                       PSOURCEFILEW
- #define SYM_ENUMSOURECFILES_CALLBACK      SYM_ENUMSOURCEFILES_CALLBACKW
- #define PSYM_ENUMSOURCEFILES_CALLBACK     PSYM_ENUMSOURECFILES_CALLBACKW
- #define IMAGEHLP_CBA_EVENT                IMAGEHLP_CBA_EVENTW
- #define PIMAGEHLP_CBA_EVENT               PIMAGEHLP_CBA_EVENTW
- #define PENUMDIRTREE_CALLBACK             PENUMDIRTREE_CALLBACKW
- #define IMAGEHLP_DEFERRED_SYMBOL_LOAD64   IMAGEHLP_DEFERRED_SYMBOL_LOADW64
- #define PIMAGEHLP_DEFERRED_SYMBOL_LOAD64  PIMAGEHLP_DEFERRED_SYMBOL_LOADW64
- #define PFIND_DEBUG_FILE_CALLBACK         PFIND_DEBUG_FILE_CALLBACKW
- #define PFINDFILEINPATHCALLBACK           PFINDFILEINPATHCALLBACKW
- #define IMAGEHLP_MODULE64                 IMAGEHLP_MODULEW64
- #define PIMAGEHLP_MODULE64                PIMAGEHLP_MODULEW64
- #define SYMSRV_INDEX_INFO                 SYMSRV_INDEX_INFOW
- #define PSYMSRV_INDEX_INFO                PSYMSRV_INDEX_INFOW
-
- #define PSYMBOLSERVERPROC                 PSYMBOLSERVERPROCW
- #define PSYMBOLSERVERPINGPROC             PSYMBOLSERVERPINGPROCW
-#endif
-
-// -----------------------------------------------------------------
-// The following APIs exist only for backwards compatibility
-// with a pre-release version documented in an MSDN release.
-
-// You should use SymFindFileInPath if you want to maintain
-// future compatibility.
-
-DBHLP_DEPRECIATED
-BOOL
-IMAGEAPI
-FindFileInPath(
-    __in HANDLE hprocess,
-    __in PCSTR SearchPath,
-    __in PCSTR FileName,
-    __in PVOID id,
-    __in DWORD two,
-    __in DWORD three,
-    __in DWORD flags,
-    __out_ecount(MAX_PATH + 1) PSTR FilePath
-    );
-
-// You should use SymFindFileInPath if you want to maintain
-// future compatibility.
-
-DBHLP_DEPRECIATED
-BOOL
-IMAGEAPI
-FindFileInSearchPath(
-    __in HANDLE hprocess,
-    __in PCSTR SearchPath,
-    __in PCSTR FileName,
-    __in DWORD one,
-    __in DWORD two,
-    __in DWORD three,
-    __out_ecount(MAX_PATH + 1) PSTR FilePath
-    );
-
-DBHLP_DEPRECIATED
-BOOL
-IMAGEAPI
-SymEnumSym(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-DBHLP_DEPRECIATED
-BOOL
-IMAGEAPI
-SymEnumerateSymbols64(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-DBHLP_DEPRECIATED
-BOOL
-IMAGEAPI
-SymEnumerateSymbolsW64(
-    __in HANDLE hProcess,
-    __in ULONG64 BaseOfDll,
-    __in PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymEnumerateSymbols SymEnumerateSymbols64
-#define SymEnumerateSymbolsW SymEnumerateSymbolsW64
-#else
-DBHLP_DEPRECIATED
-BOOL
-IMAGEAPI
-SymEnumerateSymbols(
-    __in HANDLE hProcess,
-    __in ULONG BaseOfDll,
-    __in PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-
-DBHLP_DEPRECIATED
-BOOL
-IMAGEAPI
-SymEnumerateSymbolsW(
-    __in HANDLE hProcess,
-    __in ULONG BaseOfDll,
-    __in PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback,
-    __in_opt PVOID UserContext
-    );
-#endif
-
-// use SymLoadModuleEx
-
-DWORD64
-IMAGEAPI
-SymLoadModule64(
-    __in HANDLE hProcess,
-    __in_opt HANDLE hFile,
-    __in_opt PCSTR ImageName,
-    __in_opt PCSTR ModuleName,
-    __in DWORD64 BaseOfDll,
-    __in DWORD SizeOfDll
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymLoadModule SymLoadModule64
-#else
-DWORD
-IMAGEAPI
-SymLoadModule(
-    __in HANDLE hProcess,
-    __in_opt HANDLE hFile,
-    __in_opt PCSTR ImageName,
-    __in_opt PCSTR ModuleName,
-    __in DWORD BaseOfDll,
-    __in DWORD SizeOfDll
-    );
-#endif
-
-BOOL
-IMAGEAPI
-SymGetSymNext64(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_SYMBOL64 Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymGetSymNextW64(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_SYMBOLW64 Symbol
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetSymNext SymGetSymNext64
-#define SymGetSymNextW SymGetSymNextW64
-#else
-BOOL
-IMAGEAPI
-SymGetSymNext(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_SYMBOL Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymGetSymNextW(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_SYMBOLW Symbol
-    );
-#endif
-
-BOOL
-IMAGEAPI
-SymGetSymPrev64(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_SYMBOL64 Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymGetSymPrevW64(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_SYMBOLW64 Symbol
-    );
-
-#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
-#define SymGetSymPrev SymGetSymPrev64
-#define SymGetSymPrevW SymGetSymPrevW64
-#else
-BOOL
-IMAGEAPI
-SymGetSymPrev(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_SYMBOL Symbol
-    );
-
-BOOL
-IMAGEAPI
-SymGetSymPrevW(
-    __in HANDLE hProcess,
-    __inout PIMAGEHLP_SYMBOLW Symbol
-    );
-#endif
-
-
-// These values should not be used.
-// They have been replaced by SYMFLAG_ values.
-
-#define SYMF_OMAP_GENERATED   0x00000001
-#define SYMF_OMAP_MODIFIED    0x00000002
-#define SYMF_REGISTER         0x00000008
-#define SYMF_REGREL           0x00000010
-#define SYMF_FRAMEREL         0x00000020
-#define SYMF_PARAMETER        0x00000040
-#define SYMF_LOCAL            0x00000080
-#define SYMF_CONSTANT         0x00000100
-#define SYMF_EXPORT           0x00000200
-#define SYMF_FORWARDER        0x00000400
-#define SYMF_FUNCTION         0x00000800
-#define SYMF_VIRTUAL          0x00001000
-#define SYMF_THUNK            0x00002000
-#define SYMF_TLSREL           0x00004000
-
-// These values should also not be used.
-// They have been replaced by SYMFLAG_ values.
-
-#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT          1
-#define IMAGEHLP_SYMBOL_INFO_REGISTER              SYMF_REGISTER        // 0x0008
-#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE           SYMF_REGREL          // 0x0010
-#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE         SYMF_FRAMEREL        // 0x0020
-#define IMAGEHLP_SYMBOL_INFO_PARAMETER             SYMF_PARAMETER       // 0x0040
-#define IMAGEHLP_SYMBOL_INFO_LOCAL                 SYMF_LOCAL           // 0x0080
-#define IMAGEHLP_SYMBOL_INFO_CONSTANT              SYMF_CONSTANT        // 0x0100
-#define IMAGEHLP_SYMBOL_FUNCTION                   SYMF_FUNCTION        // 0x0800
-#define IMAGEHLP_SYMBOL_VIRTUAL                    SYMF_VIRTUAL         // 0x1000
-#define IMAGEHLP_SYMBOL_THUNK                      SYMF_THUNK           // 0x2000
-#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE           SYMF_TLSREL          // 0x4000
-
-
-#include <pshpack4.h>
-
-#if defined(_MSC_VER)
-#if _MSC_VER >= 800
-#if _MSC_VER >= 1200
-#pragma warning(push)
-#endif
-#pragma warning(disable:4200)    /* Zero length array */
-#pragma warning(disable:4201)    /* Nameless struct/union */
-#endif
-#endif
-
-#define MINIDUMP_SIGNATURE ('PMDM')
-#define MINIDUMP_VERSION   (42899)
-typedef DWORD RVA;
-typedef ULONG64 RVA64;
-
-typedef struct _MINIDUMP_LOCATION_DESCRIPTOR {
-    ULONG32 DataSize;
-    RVA Rva;
-} MINIDUMP_LOCATION_DESCRIPTOR;
-
-typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 {
-    ULONG64 DataSize;
-    RVA64 Rva;
-} MINIDUMP_LOCATION_DESCRIPTOR64;
-
-
-typedef struct _MINIDUMP_MEMORY_DESCRIPTOR {
-    ULONG64 StartOfMemoryRange;
-    MINIDUMP_LOCATION_DESCRIPTOR Memory;
-} MINIDUMP_MEMORY_DESCRIPTOR, *PMINIDUMP_MEMORY_DESCRIPTOR;
-
-// DESCRIPTOR64 is used for full-memory minidumps where
-// all of the raw memory is laid out sequentially at the
-// end of the dump.  There is no need for individual RVAs
-// as the RVA is the base RVA plus the sum of the preceeding
-// data blocks.
-typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 {
-    ULONG64 StartOfMemoryRange;
-    ULONG64 DataSize;
-} MINIDUMP_MEMORY_DESCRIPTOR64, *PMINIDUMP_MEMORY_DESCRIPTOR64;
-
-
-typedef struct _MINIDUMP_HEADER {
-    ULONG32 Signature;
-    ULONG32 Version;
-    ULONG32 NumberOfStreams;
-    RVA StreamDirectoryRva;
-    ULONG32 CheckSum;
-    union {
-        ULONG32 Reserved;
-        ULONG32 TimeDateStamp;
-    };
-    ULONG64 Flags;
-} MINIDUMP_HEADER, *PMINIDUMP_HEADER;
-
-//
-// The MINIDUMP_HEADER field StreamDirectoryRva points to 
-// an array of MINIDUMP_DIRECTORY structures.
-//
-
-typedef struct _MINIDUMP_DIRECTORY {
-    ULONG32 StreamType;
-    MINIDUMP_LOCATION_DESCRIPTOR Location;
-} MINIDUMP_DIRECTORY, *PMINIDUMP_DIRECTORY;
-
-
-typedef struct _MINIDUMP_STRING {
-    ULONG32 Length;         // Length in bytes of the string
-    WCHAR   Buffer [0];     // Variable size buffer
-} MINIDUMP_STRING, *PMINIDUMP_STRING;
-
-
-
-//
-// The MINIDUMP_DIRECTORY field StreamType may be one of the following types.
-// Types will be added in the future, so if a program reading the minidump
-// header encounters a stream type it does not understand it should ignore
-// the data altogether. Any tag above LastReservedStream will not be used by
-// the system and is reserved for program-specific information.
-//
-
-typedef enum _MINIDUMP_STREAM_TYPE {
-
-    UnusedStream                = 0,
-    ReservedStream0             = 1,
-    ReservedStream1             = 2,
-    ThreadListStream            = 3,
-    ModuleListStream            = 4,
-    MemoryListStream            = 5,
-    ExceptionStream             = 6,
-    SystemInfoStream            = 7,
-    ThreadExListStream          = 8,
-    Memory64ListStream          = 9,
-    CommentStreamA              = 10,
-    CommentStreamW              = 11,
-    HandleDataStream            = 12,
-    FunctionTableStream         = 13,
-    UnloadedModuleListStream    = 14,
-    MiscInfoStream              = 15,
-    MemoryInfoListStream        = 16,
-    ThreadInfoListStream        = 17,
-    HandleOperationListStream   = 18,
-
-    ceStreamNull                = 0x8000,
-    ceStreamSystemInfo          = 0x8001,
-    ceStreamException           = 0x8002,
-    ceStreamModuleList          = 0x8003,
-    ceStreamProcessList         = 0x8004,
-    ceStreamThreadList          = 0x8005, 
-    ceStreamThreadContextList   = 0x8006,
-    ceStreamThreadCallStackList = 0x8007,
-    ceStreamMemoryVirtualList   = 0x8008,
-    ceStreamMemoryPhysicalList  = 0x8009,
-    ceStreamBucketParameters    = 0x800A,     
-
-    LastReservedStream          = 0xffff
-
-} MINIDUMP_STREAM_TYPE;
-
-
-//
-// The minidump system information contains processor and
-// Operating System specific information.
-// 
-
-//
-// CPU information is obtained from one of two places.
-//
-//  1) On x86 computers, CPU_INFORMATION is obtained from the CPUID
-//     instruction. You must use the X86 portion of the union for X86
-//     computers.
-//
-//  2) On non-x86 architectures, CPU_INFORMATION is obtained by calling
-//     IsProcessorFeatureSupported().
-//
-
-typedef union _CPU_INFORMATION {
-
-    //
-    // X86 platforms use CPUID function to obtain processor information.
-    //
-    
-    struct {
-
-        //
-        // CPUID Subfunction 0, register EAX (VendorId [0]),
-        // EBX (VendorId [1]) and ECX (VendorId [2]).
-        //
-        
-        ULONG32 VendorId [ 3 ];
-        
-        //
-        // CPUID Subfunction 1, register EAX
-        //
-        
-        ULONG32 VersionInformation;
-
-        //
-        // CPUID Subfunction 1, register EDX
-        //
-        
-        ULONG32 FeatureInformation;
-        
-
-        //
-        // CPUID, Subfunction 80000001, register EBX. This will only
-        // be obtained if the vendor id is "AuthenticAMD".
-        //
-        
-        ULONG32 AMDExtendedCpuFeatures;
-
-    } X86CpuInfo;
-
-    //
-    // Non-x86 platforms use processor feature flags.
-    //
-    
-    struct {
-
-        ULONG64 ProcessorFeatures [ 2 ];
-        
-    } OtherCpuInfo;
-
-} CPU_INFORMATION, *PCPU_INFORMATION;
-        
-typedef struct _MINIDUMP_SYSTEM_INFO {
-
-    //
-    // ProcessorArchitecture, ProcessorLevel and ProcessorRevision are all
-    // taken from the SYSTEM_INFO structure obtained by GetSystemInfo( ).
-    //
-    
-    USHORT ProcessorArchitecture;
-    USHORT ProcessorLevel;
-    USHORT ProcessorRevision;
-
-    union {
-        USHORT Reserved0;
-        struct {
-            UCHAR NumberOfProcessors;
-            UCHAR ProductType;
-        };
-    };
-
-    //
-    // MajorVersion, MinorVersion, BuildNumber, PlatformId and
-    // CSDVersion are all taken from the OSVERSIONINFO structure
-    // returned by GetVersionEx( ).
-    //
-    
-    ULONG32 MajorVersion;
-    ULONG32 MinorVersion;
-    ULONG32 BuildNumber;
-    ULONG32 PlatformId;
-
-    //
-    // RVA to a CSDVersion string in the string table.
-    //
-    
-    RVA CSDVersionRva;
-
-    union {
-        ULONG32 Reserved1;
-        struct {
-            USHORT SuiteMask;
-            USHORT Reserved2;
-        };
-    };
-
-    CPU_INFORMATION Cpu;
-
-} MINIDUMP_SYSTEM_INFO, *PMINIDUMP_SYSTEM_INFO;
-
-
-//
-// The minidump thread contains standard thread
-// information plus an RVA to the memory for this 
-// thread and an RVA to the CONTEXT structure for
-// this thread.
-//
-
-
-//
-// ThreadId must be 4 bytes on all architectures.
-//
-#ifndef FEATURE_PAL
-static_assert (sizeof ( ((PPROCESS_INFORMATION)0)->dwThreadId ) == 4, "ThreadId must be 4 bytes on all architectures.");
-#else
-typedef int VS_FIXEDFILEINFO;
-#endif
-
-
-typedef struct _MINIDUMP_THREAD {
-    ULONG32 ThreadId;
-    ULONG32 SuspendCount;
-    ULONG32 PriorityClass;
-    ULONG32 Priority;
-    ULONG64 Teb;
-    MINIDUMP_MEMORY_DESCRIPTOR Stack;
-    MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
-} MINIDUMP_THREAD, *PMINIDUMP_THREAD;
-
-//
-// The thread list is a container of threads.
-//
-
-typedef struct _MINIDUMP_THREAD_LIST {
-    ULONG32 NumberOfThreads;
-    MINIDUMP_THREAD Threads [0];
-} MINIDUMP_THREAD_LIST, *PMINIDUMP_THREAD_LIST;
-
-
-typedef struct _MINIDUMP_THREAD_EX {
-    ULONG32 ThreadId;
-    ULONG32 SuspendCount;
-    ULONG32 PriorityClass;
-    ULONG32 Priority;
-    ULONG64 Teb;
-    MINIDUMP_MEMORY_DESCRIPTOR Stack;
-    MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
-    MINIDUMP_MEMORY_DESCRIPTOR BackingStore;
-} MINIDUMP_THREAD_EX, *PMINIDUMP_THREAD_EX;
-
-//
-// The thread list is a container of threads.
-//
-
-typedef struct _MINIDUMP_THREAD_EX_LIST {
-    ULONG32 NumberOfThreads;
-    MINIDUMP_THREAD_EX Threads [0];
-} MINIDUMP_THREAD_EX_LIST, *PMINIDUMP_THREAD_EX_LIST;
-
-
-//
-// The MINIDUMP_EXCEPTION is the same as EXCEPTION on Win64.
-//
-
-typedef struct _MINIDUMP_EXCEPTION  {
-    ULONG32 ExceptionCode;
-    ULONG32 ExceptionFlags;
-    ULONG64 ExceptionRecord;
-    ULONG64 ExceptionAddress;
-    ULONG32 NumberParameters;
-    ULONG32 __unusedAlignment;
-    ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ];
-} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION;
-
-
-//
-// The exception information stream contains the id of the thread that caused
-// the exception (ThreadId), the exception record for the exception
-// (ExceptionRecord) and an RVA to the thread context where the exception
-// occured.
-//
-
-typedef struct MINIDUMP_EXCEPTION_STREAM {
-    ULONG32 ThreadId;
-    ULONG32  __alignment;
-    MINIDUMP_EXCEPTION ExceptionRecord;
-    MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
-} MINIDUMP_EXCEPTION_STREAM, *PMINIDUMP_EXCEPTION_STREAM;
-
-
-//
-// The MINIDUMP_MODULE contains information about a
-// a specific module. It includes the CheckSum and
-// the TimeDateStamp for the module so the module
-// can be reloaded during the analysis phase.
-//
-
-typedef struct _MINIDUMP_MODULE {
-    ULONG64 BaseOfImage;
-    ULONG32 SizeOfImage;
-    ULONG32 CheckSum;
-    ULONG32 TimeDateStamp;
-    RVA ModuleNameRva;
-    VS_FIXEDFILEINFO VersionInfo;
-    MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
-    MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
-    ULONG64 Reserved0;                          // Reserved for future use.
-    ULONG64 Reserved1;                          // Reserved for future use.
-} MINIDUMP_MODULE, *PMINIDUMP_MODULE;   
-
-
-//
-// The minidump module list is a container for modules.
-//
-
-typedef struct _MINIDUMP_MODULE_LIST {
-    ULONG32 NumberOfModules;
-    MINIDUMP_MODULE Modules [ 0 ];
-} MINIDUMP_MODULE_LIST, *PMINIDUMP_MODULE_LIST;
-
-
-//
-// Memory Ranges
-//
-
-typedef struct _MINIDUMP_MEMORY_LIST {
-    ULONG32 NumberOfMemoryRanges;
-    MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0];
-} MINIDUMP_MEMORY_LIST, *PMINIDUMP_MEMORY_LIST;
-
-typedef struct _MINIDUMP_MEMORY64_LIST {
-    ULONG64 NumberOfMemoryRanges;
-    RVA64 BaseRva;
-    MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0];
-} MINIDUMP_MEMORY64_LIST, *PMINIDUMP_MEMORY64_LIST;
-
-
-//
-// Support for user supplied exception information.
-//
-
-typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
-    DWORD ThreadId;
-    PEXCEPTION_POINTERS ExceptionPointers;
-    BOOL ClientPointers;
-} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
-
-typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 {
-    DWORD ThreadId;
-    ULONG64 ExceptionRecord;
-    ULONG64 ContextRecord;
-    BOOL ClientPointers;
-} MINIDUMP_EXCEPTION_INFORMATION64, *PMINIDUMP_EXCEPTION_INFORMATION64;
-
-
-//
-// Support for capturing system handle state at the time of the dump.
-//
-
-// Per-handle object information varies according to
-// the OS, the OS version, the processor type and
-// so on.  The minidump gives a minidump identifier
-// to each possible data format for identification
-// purposes but does not control nor describe the actual data.
-typedef enum _MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE {
-    MiniHandleObjectInformationNone,
-    MiniThreadInformation1,
-    MiniMutantInformation1,
-    MiniMutantInformation2,
-    MiniProcessInformation1,
-    MiniProcessInformation2,
-    MiniHandleObjectInformationTypeMax
-} MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE;
-
-typedef struct _MINIDUMP_HANDLE_OBJECT_INFORMATION {
-    RVA NextInfoRva;
-    ULONG32 InfoType;
-    ULONG32 SizeOfInfo;
-    // Raw information follows.
-} MINIDUMP_HANDLE_OBJECT_INFORMATION;
-
-typedef struct _MINIDUMP_HANDLE_DESCRIPTOR {
-    ULONG64 Handle;
-    RVA TypeNameRva;
-    RVA ObjectNameRva;
-    ULONG32 Attributes;
-    ULONG32 GrantedAccess;
-    ULONG32 HandleCount;
-    ULONG32 PointerCount;
-} MINIDUMP_HANDLE_DESCRIPTOR, *PMINIDUMP_HANDLE_DESCRIPTOR;
-
-typedef struct _MINIDUMP_HANDLE_DESCRIPTOR_2 {
-    ULONG64 Handle;
-    RVA TypeNameRva;
-    RVA ObjectNameRva;
-    ULONG32 Attributes;
-    ULONG32 GrantedAccess;
-    ULONG32 HandleCount;
-    ULONG32 PointerCount;
-    RVA ObjectInfoRva;
-    ULONG32 Reserved0;
-} MINIDUMP_HANDLE_DESCRIPTOR_2, *PMINIDUMP_HANDLE_DESCRIPTOR_2;
-
-// The latest MINIDUMP_HANDLE_DESCRIPTOR definition.
-typedef MINIDUMP_HANDLE_DESCRIPTOR_2 MINIDUMP_HANDLE_DESCRIPTOR_N;
-typedef MINIDUMP_HANDLE_DESCRIPTOR_N *PMINIDUMP_HANDLE_DESCRIPTOR_N;
-
-typedef struct _MINIDUMP_HANDLE_DATA_STREAM {
-    ULONG32 SizeOfHeader;
-    ULONG32 SizeOfDescriptor;
-    ULONG32 NumberOfDescriptors;
-    ULONG32 Reserved;
-} MINIDUMP_HANDLE_DATA_STREAM, *PMINIDUMP_HANDLE_DATA_STREAM;
-
-// Some operating systems can track the last operations
-// performed on a handle.  For example, Application Verifier
-// can enable this for some versions of Windows.  The
-// handle operation list collects handle operations
-// known for the dump target.
-// Each entry is an AVRF_HANDLE_OPERATION.
-typedef struct _MINIDUMP_HANDLE_OPERATION_LIST {
-    ULONG32 SizeOfHeader;
-    ULONG32 SizeOfEntry;
-    ULONG32 NumberOfEntries;
-    ULONG32 Reserved;
-} MINIDUMP_HANDLE_OPERATION_LIST, *PMINIDUMP_HANDLE_OPERATION_LIST;
-
-
-//
-// Support for capturing dynamic function table state at the time of the dump.
-//
-
-typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR {
-    ULONG64 MinimumAddress;
-    ULONG64 MaximumAddress;
-    ULONG64 BaseAddress;
-    ULONG32 EntryCount;
-    ULONG32 SizeOfAlignPad;
-} MINIDUMP_FUNCTION_TABLE_DESCRIPTOR, *PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR;
-
-typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM {
-    ULONG32 SizeOfHeader;
-    ULONG32 SizeOfDescriptor;
-    ULONG32 SizeOfNativeDescriptor;
-    ULONG32 SizeOfFunctionEntry;
-    ULONG32 NumberOfDescriptors;
-    ULONG32 SizeOfAlignPad;
-} MINIDUMP_FUNCTION_TABLE_STREAM, *PMINIDUMP_FUNCTION_TABLE_STREAM;
-
-
-//
-// The MINIDUMP_UNLOADED_MODULE contains information about a
-// a specific module that was previously loaded but no
-// longer is.  This can help with diagnosing problems where
-// callers attempt to call code that is no longer loaded.
-//
-
-typedef struct _MINIDUMP_UNLOADED_MODULE {
-    ULONG64 BaseOfImage;
-    ULONG32 SizeOfImage;
-    ULONG32 CheckSum;
-    ULONG32 TimeDateStamp;
-    RVA ModuleNameRva;
-} MINIDUMP_UNLOADED_MODULE, *PMINIDUMP_UNLOADED_MODULE;
-
-
-//
-// The minidump unloaded module list is a container for unloaded modules.
-//
-
-typedef struct _MINIDUMP_UNLOADED_MODULE_LIST {
-    ULONG32 SizeOfHeader;
-    ULONG32 SizeOfEntry;
-    ULONG32 NumberOfEntries;
-} MINIDUMP_UNLOADED_MODULE_LIST, *PMINIDUMP_UNLOADED_MODULE_LIST;
-
-
-//
-// The miscellaneous information stream contains a variety
-// of small pieces of information.  A member is valid if
-// it's within the available size and its corresponding
-// bit is set.
-//
-
-#define MINIDUMP_MISC1_PROCESS_ID           0x00000001
-#define MINIDUMP_MISC1_PROCESS_TIMES        0x00000002
-#define MINIDUMP_MISC1_PROCESSOR_POWER_INFO 0x00000004
-
-typedef struct _MINIDUMP_MISC_INFO {
-    ULONG32 SizeOfInfo;
-    ULONG32 Flags1;
-    ULONG32 ProcessId;
-    ULONG32 ProcessCreateTime;
-    ULONG32 ProcessUserTime;
-    ULONG32 ProcessKernelTime;
-} MINIDUMP_MISC_INFO, *PMINIDUMP_MISC_INFO;
-
-typedef struct _MINIDUMP_MISC_INFO_2 {
-    ULONG32 SizeOfInfo;
-    ULONG32 Flags1;
-    ULONG32 ProcessId;
-    ULONG32 ProcessCreateTime;
-    ULONG32 ProcessUserTime;
-    ULONG32 ProcessKernelTime;
-    ULONG32 ProcessorMaxMhz;
-    ULONG32 ProcessorCurrentMhz;
-    ULONG32 ProcessorMhzLimit;
-    ULONG32 ProcessorMaxIdleState;
-    ULONG32 ProcessorCurrentIdleState;
-} MINIDUMP_MISC_INFO_2, *PMINIDUMP_MISC_INFO_2;
-
-// The latest MINIDUMP_MISC_INFO definition.
-typedef MINIDUMP_MISC_INFO_2 MINIDUMP_MISC_INFO_N;
-typedef MINIDUMP_MISC_INFO_N* PMINIDUMP_MISC_INFO_N;
-
-
-//
-// The memory information stream contains memory region
-// description information.  This stream corresponds to
-// what VirtualQuery would return for the process the
-// dump was created for.
-//
-
-typedef struct _MINIDUMP_MEMORY_INFO {
-    ULONG64 BaseAddress;
-    ULONG64 AllocationBase;
-    ULONG32 AllocationProtect;
-    ULONG32 __alignment1;
-    ULONG64 RegionSize;
-    ULONG32 State;
-    ULONG32 Protect;
-    ULONG32 Type;
-    ULONG32 __alignment2;
-} MINIDUMP_MEMORY_INFO, *PMINIDUMP_MEMORY_INFO;
-
-typedef struct _MINIDUMP_MEMORY_INFO_LIST {
-    ULONG SizeOfHeader;
-    ULONG SizeOfEntry;
-    ULONG64 NumberOfEntries;
-} MINIDUMP_MEMORY_INFO_LIST, *PMINIDUMP_MEMORY_INFO_LIST;
-
-    
-//
-// The memory information stream contains memory region
-// description information.  This stream corresponds to
-// what VirtualQuery would return for the process the
-// dump was created for.
-//
-
-// Thread dump writer status flags.
-#define MINIDUMP_THREAD_INFO_ERROR_THREAD    0x00000001
-#define MINIDUMP_THREAD_INFO_WRITING_THREAD  0x00000002
-#define MINIDUMP_THREAD_INFO_EXITED_THREAD   0x00000004
-#define MINIDUMP_THREAD_INFO_INVALID_INFO    0x00000008
-#define MINIDUMP_THREAD_INFO_INVALID_CONTEXT 0x00000010
-#define MINIDUMP_THREAD_INFO_INVALID_TEB     0x00000020
-
-typedef struct _MINIDUMP_THREAD_INFO {
-    ULONG32 ThreadId;
-    ULONG32 DumpFlags;
-    ULONG32 DumpError;
-    ULONG32 ExitStatus;
-    ULONG64 CreateTime;
-    ULONG64 ExitTime;
-    ULONG64 KernelTime;
-    ULONG64 UserTime;
-    ULONG64 StartAddress;
-    ULONG64 Affinity;
-} MINIDUMP_THREAD_INFO, *PMINIDUMP_THREAD_INFO;
-
-typedef struct _MINIDUMP_THREAD_INFO_LIST {
-    ULONG SizeOfHeader;
-    ULONG SizeOfEntry;
-    ULONG NumberOfEntries;
-} MINIDUMP_THREAD_INFO_LIST, *PMINIDUMP_THREAD_INFO_LIST;
-
-
-//
-// Support for arbitrary user-defined information.
-//
-
-typedef struct _MINIDUMP_USER_RECORD {
-    ULONG32 Type;
-    MINIDUMP_LOCATION_DESCRIPTOR Memory;
-} MINIDUMP_USER_RECORD, *PMINIDUMP_USER_RECORD;
-
-
-typedef struct _MINIDUMP_USER_STREAM {
-    ULONG32 Type;
-    ULONG BufferSize;
-    PVOID Buffer;
-
-} MINIDUMP_USER_STREAM, *PMINIDUMP_USER_STREAM;
-
-
-typedef struct _MINIDUMP_USER_STREAM_INFORMATION {
-    ULONG UserStreamCount;
-    PMINIDUMP_USER_STREAM UserStreamArray;
-} MINIDUMP_USER_STREAM_INFORMATION, *PMINIDUMP_USER_STREAM_INFORMATION;
-
-//
-// Callback support.
-//
-
-typedef enum _MINIDUMP_CALLBACK_TYPE {
-    ModuleCallback,
-    ThreadCallback,
-    ThreadExCallback,
-    IncludeThreadCallback,
-    IncludeModuleCallback,
-    MemoryCallback,
-    CancelCallback,
-    WriteKernelMinidumpCallback,
-    KernelMinidumpStatusCallback,
-    RemoveMemoryCallback,
-    IncludeVmRegionCallback,
-    IoStartCallback,
-    IoWriteAllCallback,
-    IoFinishCallback,
-    ReadMemoryFailureCallback,
-    SecondaryFlagsCallback,
-} MINIDUMP_CALLBACK_TYPE;
-
-
-typedef struct _MINIDUMP_THREAD_CALLBACK {
-    ULONG ThreadId;
-    HANDLE ThreadHandle;
-    CONTEXT Context;
-    ULONG SizeOfContext;
-    ULONG64 StackBase;
-    ULONG64 StackEnd;
-} MINIDUMP_THREAD_CALLBACK, *PMINIDUMP_THREAD_CALLBACK;
-
-
-typedef struct _MINIDUMP_THREAD_EX_CALLBACK {
-    ULONG ThreadId;
-    HANDLE ThreadHandle;
-    CONTEXT Context;
-    ULONG SizeOfContext;
-    ULONG64 StackBase;
-    ULONG64 StackEnd;
-    ULONG64 BackingStoreBase;
-    ULONG64 BackingStoreEnd;
-} MINIDUMP_THREAD_EX_CALLBACK, *PMINIDUMP_THREAD_EX_CALLBACK;
-
-
-typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK {
-    ULONG ThreadId;
-} MINIDUMP_INCLUDE_THREAD_CALLBACK, *PMINIDUMP_INCLUDE_THREAD_CALLBACK;
-
-
-typedef enum _THREAD_WRITE_FLAGS {
-    ThreadWriteThread            = 0x0001,
-    ThreadWriteStack             = 0x0002,
-    ThreadWriteContext           = 0x0004,
-    ThreadWriteBackingStore      = 0x0008,
-    ThreadWriteInstructionWindow = 0x0010,
-    ThreadWriteThreadData        = 0x0020,
-    ThreadWriteThreadInfo        = 0x0040,
-} THREAD_WRITE_FLAGS;
-
-typedef struct _MINIDUMP_MODULE_CALLBACK {
-    PWCHAR FullPath;
-    ULONG64 BaseOfImage;
-    ULONG SizeOfImage;
-    ULONG CheckSum;
-    ULONG TimeDateStamp;
-    VS_FIXEDFILEINFO VersionInfo;
-    PVOID CvRecord; 
-    ULONG SizeOfCvRecord;
-    PVOID MiscRecord;
-    ULONG SizeOfMiscRecord;
-} MINIDUMP_MODULE_CALLBACK, *PMINIDUMP_MODULE_CALLBACK;
-
-
-typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK {
-    ULONG64 BaseOfImage;
-} MINIDUMP_INCLUDE_MODULE_CALLBACK, *PMINIDUMP_INCLUDE_MODULE_CALLBACK;
-
-
-typedef enum _MODULE_WRITE_FLAGS {
-    ModuleWriteModule        = 0x0001,
-    ModuleWriteDataSeg       = 0x0002,
-    ModuleWriteMiscRecord    = 0x0004,
-    ModuleWriteCvRecord      = 0x0008,
-    ModuleReferencedByMemory = 0x0010,
-    ModuleWriteTlsData       = 0x0020,
-    ModuleWriteCodeSegs      = 0x0040,
-} MODULE_WRITE_FLAGS;
-
-
-typedef struct _MINIDUMP_IO_CALLBACK {
-    HANDLE Handle;
-    ULONG64 Offset;
-    PVOID Buffer;
-    ULONG BufferBytes;
-} MINIDUMP_IO_CALLBACK, *PMINIDUMP_IO_CALLBACK;
-
-
-typedef struct _MINIDUMP_READ_MEMORY_FAILURE_CALLBACK
-{
-    ULONG64 Offset;
-    ULONG Bytes;
-    HRESULT FailureStatus;
-} MINIDUMP_READ_MEMORY_FAILURE_CALLBACK,
-  *PMINIDUMP_READ_MEMORY_FAILURE_CALLBACK;
-
-
-typedef struct _MINIDUMP_CALLBACK_INPUT {
-    ULONG ProcessId;
-    HANDLE ProcessHandle;
-    ULONG CallbackType;
-    union {
-        HRESULT Status;
-        MINIDUMP_THREAD_CALLBACK Thread;
-        MINIDUMP_THREAD_EX_CALLBACK ThreadEx;
-        MINIDUMP_MODULE_CALLBACK Module;
-        MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
-        MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
-        MINIDUMP_IO_CALLBACK Io;
-        MINIDUMP_READ_MEMORY_FAILURE_CALLBACK ReadMemoryFailure;
-        ULONG SecondaryFlags;
-    };
-} MINIDUMP_CALLBACK_INPUT, *PMINIDUMP_CALLBACK_INPUT;
-
-typedef struct _MINIDUMP_CALLBACK_OUTPUT {
-    union {
-        ULONG ModuleWriteFlags;
-        ULONG ThreadWriteFlags;
-        ULONG SecondaryFlags;
-        struct {
-            ULONG64 MemoryBase;
-            ULONG MemorySize;
-        };
-        struct {
-            BOOL CheckCancel;
-            BOOL Cancel;
-        };
-        HANDLE Handle;
-        struct {
-            MINIDUMP_MEMORY_INFO VmRegion;
-            BOOL Continue;
-        };
-        HRESULT Status;
-    };
-} MINIDUMP_CALLBACK_OUTPUT, *PMINIDUMP_CALLBACK_OUTPUT;
-
-        
-//
-// A normal minidump contains just the information
-// necessary to capture stack traces for all of the
-// existing threads in a process.
-//
-// A minidump with data segments includes all of the data
-// sections from loaded modules in order to capture
-// global variable contents.  This can make the dump much
-// larger if many modules have global data.
-//
-// A minidump with full memory includes all of the accessible
-// memory in the process and can be very large.  A minidump
-// with full memory always has the raw memory data at the end
-// of the dump so that the initial structures in the dump can
-// be mapped directly without having to include the raw
-// memory information.
-//
-// Stack and backing store memory can be filtered to remove
-// data unnecessary for stack walking.  This can improve
-// compression of stacks and also deletes data that may
-// be private and should not be stored in a dump.
-// Memory can also be scanned to see what modules are
-// referenced by stack and backing store memory to allow
-// omission of other modules to reduce dump size.
-// In either of these modes the ModuleReferencedByMemory flag
-// is set for all modules referenced before the base
-// module callbacks occur.
-//
-// On some operating systems a list of modules that were
-// recently unloaded is kept in addition to the currently
-// loaded module list.  This information can be saved in
-// the dump if desired.
-//
-// Stack and backing store memory can be scanned for referenced
-// pages in order to pick up data referenced by locals or other
-// stack memory.  This can increase the size of a dump significantly.
-//
-// Module paths may contain undesired information such as user names
-// or other important directory names so they can be stripped.  This
-// option reduces the ability to locate the proper image later
-// and should only be used in certain situations.
-//
-// Complete operating system per-process and per-thread information can
-// be gathered and stored in the dump.
-//
-// The virtual address space can be scanned for various types
-// of memory to be included in the dump.
-//
-// Code which is concerned with potentially private information
-// getting into the minidump can set a flag that automatically
-// modifies all existing and future flags to avoid placing
-// unnecessary data in the dump.  Basic data, such as stack
-// information, will still be included but optional data, such
-// as indirect memory, will not.
-//
-// When doing a full memory dump it's possible to store all
-// of the enumerated memory region descriptive information
-// in a memory information stream.
-//
-// Additional thread information beyond the basic thread
-// structure can be collected if desired.
-//
-// A minidump with code segments includes all of the code
-// and code-related sections from loaded modules in order
-// to capture executable content.
-//
-// MiniDumpWithoutAuxiliaryState turns off any secondary,
-// auxiliary-supported memory gathering.
-//
-// MiniDumpWithFullAuxiliaryState asks any present auxiliary
-// data providers to include all of their state in the dump.
-// The exact set of what is provided depends on the auxiliary.
-// This can be quite large.
-//
-
-typedef enum _MINIDUMP_TYPE {
-    MiniDumpNormal                         = 0x00000000,
-    MiniDumpWithDataSegs                   = 0x00000001,
-    MiniDumpWithFullMemory                 = 0x00000002,
-    MiniDumpWithHandleData                 = 0x00000004,
-    MiniDumpFilterMemory                   = 0x00000008,
-    MiniDumpScanMemory                     = 0x00000010,
-    MiniDumpWithUnloadedModules            = 0x00000020,
-    MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
-    MiniDumpFilterModulePaths              = 0x00000080,
-    MiniDumpWithProcessThreadData          = 0x00000100,
-    MiniDumpWithPrivateReadWriteMemory     = 0x00000200,
-    MiniDumpWithoutOptionalData            = 0x00000400,
-    MiniDumpWithFullMemoryInfo             = 0x00000800,
-    MiniDumpWithThreadInfo                 = 0x00001000,
-    MiniDumpWithCodeSegs                   = 0x00002000,
-    MiniDumpWithoutAuxiliaryState          = 0x00004000,
-    MiniDumpWithFullAuxiliaryState         = 0x00008000,
-    
-    MiniDumpValidTypeFlags                 = 0x0000ffff,
-} MINIDUMP_TYPE;
-
-//
-// In addition to the primary flags provided to
-// MiniDumpWriteDump there are additional, less
-// frequently used options queried via the secondary
-// flags callback.
-//
-// MiniSecondaryWithoutPowerInfo suppresses the minidump
-// query that retrieves processor power information for
-// MINIDUMP_MISC_INFO.
-//
-    
-typedef enum _MINIDUMP_SECONDARY_FLAGS {
-    MiniSecondaryWithoutPowerInfo = 0x00000001,
-
-    MiniSecondaryValidFlags       = 0x00000001,
-} MINIDUMP_SECONDARY_FLAGS;
-
-
-//
-// The minidump callback should modify the FieldsToWrite parameter to reflect
-// what portions of the specified thread or module should be written to the
-// file.
-//
-
-typedef
-BOOL
-(WINAPI * MINIDUMP_CALLBACK_ROUTINE) (
-    IN PVOID CallbackParam,
-    IN CONST PMINIDUMP_CALLBACK_INPUT CallbackInput,
-    IN OUT PMINIDUMP_CALLBACK_OUTPUT CallbackOutput
-    );
-
-typedef struct _MINIDUMP_CALLBACK_INFORMATION {
-    MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
-    PVOID CallbackParam;
-} MINIDUMP_CALLBACK_INFORMATION, *PMINIDUMP_CALLBACK_INFORMATION;
-
-
-
-//++
-//
-// PVOID
-// RVA_TO_ADDR(
-//     PVOID Mapping,
-//     ULONG Rva
-//     )
-//
-// Routine Description:
-//
-//     Map an RVA that is contained within a mapped file to it's associated
-//     flat address.
-//
-// Arguments:
-//
-//     Mapping - Base address of mapped file containing the RVA.
-//
-//     Rva - An Rva to fixup.
-//
-// Return Values:
-//
-//     A pointer to the desired data.
-//
-//--
-
-#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva)))
-
-BOOL
-WINAPI
-MiniDumpWriteDump(
-    IN HANDLE hProcess,
-    IN DWORD ProcessId,
-    IN HANDLE hFile,
-    IN MINIDUMP_TYPE DumpType,
-    IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
-    IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
-    IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
-    );
-
-BOOL
-WINAPI
-MiniDumpReadDumpStream(
-    IN PVOID BaseOfDump,
-    IN ULONG StreamNumber,
-    OUT PMINIDUMP_DIRECTORY * Dir, OPTIONAL
-    OUT PVOID * StreamPointer, OPTIONAL
-    OUT ULONG * StreamSize OPTIONAL
-    );
-
-#if defined(_MSC_VER)
-#if _MSC_VER >= 800
-#if _MSC_VER >= 1200
-#pragma warning(pop)
-#else
-#pragma warning(default:4200)    /* Zero length array */
-#pragma warning(default:4201)    /* Nameless struct/union */
-#endif
-#endif
-#endif
-
-#include <poppack.h>
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif // _DBGHELP_
diff --git a/src/SOS/Strike/inc/wdbgexts.h b/src/SOS/Strike/inc/wdbgexts.h
deleted file mode 100644 (file)
index 5e0e8c3..0000000
+++ /dev/null
@@ -1,2807 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*++
-
-
-Module Name:
-
-    wdbgexts.h
-
-Abstract:
-
-    This file contains the necessary prototypes and data types for a user
-    to write a debugger extension DLL.  This header file is also included
-    by the NT debuggers (WINDBG & KD).
-
-    This header file must be included after "windows.h" and "dbghelp.h".
-
-    Please see the NT DDK documentation for specific information about
-    how to write your own debugger extension DLL.
-
-Environment:
-
-    Win32 only.
-
-Revision History:
-
---*/
-
-#ifndef _WDBGEXTS_
-#define _WDBGEXTS_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if _MSC_VER >= 1200
-#pragma warning(push)
-#endif
-#ifndef FEATURE_PAL
-#pragma warning(disable:4115 4201 4204 4214 4221)
-#endif
-
-// Maximum value of MAXIMUM_PROCESSORS for all platforms.
-#define CROSS_PLATFORM_MAXIMUM_PROCESSORS 256
-
-#if !defined(WDBGAPI)
-#define WDBGAPI __stdcall
-#endif
-
-#if !defined(WDBGAPIV)
-#define WDBGAPIV __cdecl
-#endif
-
-#ifndef _WINDEF_
-typedef CONST void *LPCVOID;
-#endif
-
-#ifndef _ULONGLONG_
-typedef unsigned __int64 ULONGLONG;
-typedef ULONGLONG *PULONGLONG;
-#endif
-
-#ifndef __field_ecount_opt
-// Should include SpecStrings.h to get proper definitions.
-#define __field_ecount_opt(x)
-#endif
-
-#define WDBGEXTS_MAXSIZE_T ((SIZE_T)~((SIZE_T)0))
-
-typedef
-VOID
-(WDBGAPIV*PWINDBG_OUTPUT_ROUTINE)(
-    PCSTR lpFormat,
-    ...
-    );
-
-typedef
-ULONG_PTR
-(WDBGAPI*PWINDBG_GET_EXPRESSION)(
-    PCSTR lpExpression
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_GET_EXPRESSION32)(
-    PCSTR lpExpression
-    );
-
-typedef
-ULONG64
-(WDBGAPI*PWINDBG_GET_EXPRESSION64)(
-    PCSTR lpExpression
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_GET_SYMBOL)(
-    PVOID      offset,
-    PCHAR      pchBuffer,
-    ULONG_PTR *pDisplacement
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_GET_SYMBOL32)(
-    ULONG      offset,
-    PCHAR      pchBuffer,
-    PULONG     pDisplacement
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_GET_SYMBOL64)(
-    ULONG64    offset,
-    PCHAR      pchBuffer,
-    PULONG64   pDisplacement
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_DISASM)(
-    ULONG_PTR *lpOffset,
-    PCSTR      lpBuffer,
-    ULONG      fShowEffectiveAddress
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_DISASM32)(
-    ULONG     *lpOffset,
-    PCSTR      lpBuffer,
-    ULONG      fShowEffectiveAddress
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_DISASM64)(
-    ULONG64   *lpOffset,
-    PCSTR      lpBuffer,
-    ULONG      fShowEffectiveAddress
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_CHECK_CONTROL_C)(
-    VOID
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_READ_PROCESS_MEMORY_ROUTINE)(
-    ULONG_PTR  offset,
-    PVOID      lpBuffer,
-    ULONG      cb,
-    PULONG     lpcbBytesRead
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_READ_PROCESS_MEMORY_ROUTINE32)(
-    ULONG      offset,
-    PVOID      lpBuffer,
-    ULONG      cb,
-    PULONG     lpcbBytesRead
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_READ_PROCESS_MEMORY_ROUTINE64)(
-    ULONG64    offset,
-    PVOID      lpBuffer,
-    ULONG      cb,
-    PULONG     lpcbBytesRead
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE)(
-    ULONG_PTR  offset,
-    LPCVOID    lpBuffer,
-    ULONG      cb,
-    PULONG     lpcbBytesWritten
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE32)(
-    ULONG      offset,
-    LPCVOID    lpBuffer,
-    ULONG      cb,
-    PULONG     lpcbBytesWritten
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE64)(
-    ULONG64    offset,
-    LPCVOID    lpBuffer,
-    ULONG      cb,
-    PULONG     lpcbBytesWritten
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_GET_THREAD_CONTEXT_ROUTINE)(
-    ULONG       Processor,
-    PCONTEXT    lpContext,
-    ULONG       cbSizeOfContext
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_SET_THREAD_CONTEXT_ROUTINE)(
-    ULONG       Processor,
-    PCONTEXT    lpContext,
-    ULONG       cbSizeOfContext
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_IOCTL_ROUTINE)(
-    USHORT   IoctlType,
-    PVOID    lpvData,
-    ULONG    cbSize
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_OLDKD_READ_PHYSICAL_MEMORY)(
-    ULONGLONG        address,
-    PVOID            buffer,
-    ULONG            count,
-    PULONG           bytesread
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_OLDKD_WRITE_PHYSICAL_MEMORY)(
-    ULONGLONG        address,
-    PVOID            buffer,
-    ULONG            length,
-    PULONG           byteswritten
-    );
-
-
-typedef struct _EXTSTACKTRACE {
-    ULONG       FramePointer;
-    ULONG       ProgramCounter;
-    ULONG       ReturnAddress;
-    ULONG       Args[4];
-} EXTSTACKTRACE, *PEXTSTACKTRACE;
-
-typedef struct _EXTSTACKTRACE32 {
-    ULONG       FramePointer;
-    ULONG       ProgramCounter;
-    ULONG       ReturnAddress;
-    ULONG       Args[4];
-} EXTSTACKTRACE32, *PEXTSTACKTRACE32;
-
-typedef struct _EXTSTACKTRACE64 {
-    ULONG64     FramePointer;
-    ULONG64     ProgramCounter;
-    ULONG64     ReturnAddress;
-    ULONG64     Args[4];
-} EXTSTACKTRACE64, *PEXTSTACKTRACE64;
-
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_STACKTRACE_ROUTINE)(
-    ULONG             FramePointer,
-    ULONG             StackPointer,
-    ULONG             ProgramCounter,
-    PEXTSTACKTRACE    StackFrames,
-    ULONG             Frames
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_STACKTRACE_ROUTINE32)(
-    ULONG             FramePointer,
-    ULONG             StackPointer,
-    ULONG             ProgramCounter,
-    PEXTSTACKTRACE32  StackFrames,
-    ULONG             Frames
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_STACKTRACE_ROUTINE64)(
-    ULONG64           FramePointer,
-    ULONG64           StackPointer,
-    ULONG64           ProgramCounter,
-    PEXTSTACKTRACE64  StackFrames,
-    ULONG             Frames
-    );
-
-typedef struct _WINDBG_EXTENSION_APIS {
-    ULONG                                  nSize;
-    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
-    PWINDBG_GET_EXPRESSION                 lpGetExpressionRoutine;
-    PWINDBG_GET_SYMBOL                     lpGetSymbolRoutine;
-    PWINDBG_DISASM                         lpDisasmRoutine;
-    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
-    PWINDBG_READ_PROCESS_MEMORY_ROUTINE    lpReadProcessMemoryRoutine;
-    PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE   lpWriteProcessMemoryRoutine;
-    PWINDBG_GET_THREAD_CONTEXT_ROUTINE     lpGetThreadContextRoutine;
-    PWINDBG_SET_THREAD_CONTEXT_ROUTINE     lpSetThreadContextRoutine;
-    PWINDBG_IOCTL_ROUTINE                  lpIoctlRoutine;
-    PWINDBG_STACKTRACE_ROUTINE             lpStackTraceRoutine;
-} WINDBG_EXTENSION_APIS, *PWINDBG_EXTENSION_APIS;
-
-typedef struct _WINDBG_EXTENSION_APIS32 {
-    ULONG                                  nSize;
-    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
-    PWINDBG_GET_EXPRESSION32               lpGetExpressionRoutine;
-    PWINDBG_GET_SYMBOL32                   lpGetSymbolRoutine;
-    PWINDBG_DISASM32                       lpDisasmRoutine;
-    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
-    PWINDBG_READ_PROCESS_MEMORY_ROUTINE32  lpReadProcessMemoryRoutine;
-    PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE32 lpWriteProcessMemoryRoutine;
-    PWINDBG_GET_THREAD_CONTEXT_ROUTINE     lpGetThreadContextRoutine;
-    PWINDBG_SET_THREAD_CONTEXT_ROUTINE     lpSetThreadContextRoutine;
-    PWINDBG_IOCTL_ROUTINE                  lpIoctlRoutine;
-    PWINDBG_STACKTRACE_ROUTINE32           lpStackTraceRoutine;
-} WINDBG_EXTENSION_APIS32, *PWINDBG_EXTENSION_APIS32;
-
-typedef struct _WINDBG_EXTENSION_APIS64 {
-    ULONG                                  nSize;
-    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
-    PWINDBG_GET_EXPRESSION64               lpGetExpressionRoutine;
-    PWINDBG_GET_SYMBOL64                   lpGetSymbolRoutine;
-    PWINDBG_DISASM64                       lpDisasmRoutine;
-    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
-    PWINDBG_READ_PROCESS_MEMORY_ROUTINE64  lpReadProcessMemoryRoutine;
-    PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE64 lpWriteProcessMemoryRoutine;
-    PWINDBG_GET_THREAD_CONTEXT_ROUTINE     lpGetThreadContextRoutine;
-    PWINDBG_SET_THREAD_CONTEXT_ROUTINE     lpSetThreadContextRoutine;
-    PWINDBG_IOCTL_ROUTINE                  lpIoctlRoutine;
-    PWINDBG_STACKTRACE_ROUTINE64           lpStackTraceRoutine;
-} WINDBG_EXTENSION_APIS64, *PWINDBG_EXTENSION_APIS64;
-
-
-typedef struct _WINDBG_OLD_EXTENSION_APIS {
-    ULONG                                  nSize;
-    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
-    PWINDBG_GET_EXPRESSION                 lpGetExpressionRoutine;
-    PWINDBG_GET_SYMBOL                     lpGetSymbolRoutine;
-    PWINDBG_DISASM                         lpDisasmRoutine;
-    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
-} WINDBG_OLD_EXTENSION_APIS, *PWINDBG_OLD_EXTENSION_APIS;
-
-typedef struct _WINDBG_OLDKD_EXTENSION_APIS {
-    ULONG                                  nSize;
-    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
-    PWINDBG_GET_EXPRESSION32               lpGetExpressionRoutine;
-    PWINDBG_GET_SYMBOL32                   lpGetSymbolRoutine;
-    PWINDBG_DISASM32                       lpDisasmRoutine;
-    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
-    PWINDBG_READ_PROCESS_MEMORY_ROUTINE32  lpReadVirtualMemRoutine;
-    PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE32 lpWriteVirtualMemRoutine;
-    PWINDBG_OLDKD_READ_PHYSICAL_MEMORY     lpReadPhysicalMemRoutine;
-    PWINDBG_OLDKD_WRITE_PHYSICAL_MEMORY    lpWritePhysicalMemRoutine;
-} WINDBG_OLDKD_EXTENSION_APIS, *PWINDBG_OLDKD_EXTENSION_APIS;
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_OLD_EXTENSION_ROUTINE)(
-    ULONG                   dwCurrentPc,
-    PWINDBG_EXTENSION_APIS  lpExtensionApis,
-    PCSTR                   lpArgumentString
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_EXTENSION_ROUTINE)(
-    HANDLE                  hCurrentProcess,
-    HANDLE                  hCurrentThread,
-    ULONG                   dwCurrentPc,
-    ULONG                   dwProcessor,
-    PCSTR                   lpArgumentString
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_EXTENSION_ROUTINE32)(
-    HANDLE                  hCurrentProcess,
-    HANDLE                  hCurrentThread,
-    ULONG                   dwCurrentPc,
-    ULONG                   dwProcessor,
-    PCSTR                   lpArgumentString
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_EXTENSION_ROUTINE64)(
-    HANDLE                  hCurrentProcess,
-    HANDLE                  hCurrentThread,
-    ULONG64                 dwCurrentPc,
-    ULONG                   dwProcessor,
-    PCSTR                   lpArgumentString
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_OLDKD_EXTENSION_ROUTINE)(
-    ULONG                        dwCurrentPc,
-    PWINDBG_OLDKD_EXTENSION_APIS lpExtensionApis,
-    PCSTR                        lpArgumentString
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_EXTENSION_DLL_INIT)(
-    PWINDBG_EXTENSION_APIS lpExtensionApis,
-    USHORT                 MajorVersion,
-    USHORT                 MinorVersion
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_EXTENSION_DLL_INIT32)(
-    PWINDBG_EXTENSION_APIS32 lpExtensionApis,
-    USHORT                   MajorVersion,
-    USHORT                   MinorVersion
-    );
-
-typedef
-VOID
-(WDBGAPI*PWINDBG_EXTENSION_DLL_INIT64)(
-    PWINDBG_EXTENSION_APIS64 lpExtensionApis,
-    USHORT                   MajorVersion,
-    USHORT                   MinorVersion
-    );
-
-typedef
-ULONG
-(WDBGAPI*PWINDBG_CHECK_VERSION)(
-    VOID
-    );
-
-#define EXT_API_VERSION_NUMBER   5
-#define EXT_API_VERSION_NUMBER32 5
-#define EXT_API_VERSION_NUMBER64 6
-
-typedef struct EXT_API_VERSION {
-    USHORT  MajorVersion;
-    USHORT  MinorVersion;
-    USHORT  Revision;
-    USHORT  Reserved;
-} EXT_API_VERSION, *LPEXT_API_VERSION;
-
-typedef
-LPEXT_API_VERSION
-(WDBGAPI*PWINDBG_EXTENSION_API_VERSION)(
-    VOID
-    );
-
-#define IG_KD_CONTEXT                  1
-#define IG_READ_CONTROL_SPACE          2
-#define IG_WRITE_CONTROL_SPACE         3
-#define IG_READ_IO_SPACE               4
-#define IG_WRITE_IO_SPACE              5
-#define IG_READ_PHYSICAL               6
-#define IG_WRITE_PHYSICAL              7
-#define IG_READ_IO_SPACE_EX            8
-#define IG_WRITE_IO_SPACE_EX           9
-#define IG_KSTACK_HELP                10   // obsolete
-#define IG_SET_THREAD                 11
-#define IG_READ_MSR                   12
-#define IG_WRITE_MSR                  13
-#define IG_GET_DEBUGGER_DATA          14
-#define IG_GET_KERNEL_VERSION         15
-#define IG_RELOAD_SYMBOLS             16
-#define IG_GET_SET_SYMPATH            17
-#define IG_GET_EXCEPTION_RECORD       18
-#define IG_IS_PTR64                   19
-#define IG_GET_BUS_DATA               20
-#define IG_SET_BUS_DATA               21
-#define IG_DUMP_SYMBOL_INFO           22
-#define IG_LOWMEM_CHECK               23
-#define IG_SEARCH_MEMORY              24
-#define IG_GET_CURRENT_THREAD         25
-#define IG_GET_CURRENT_PROCESS        26
-#define IG_GET_TYPE_SIZE              27
-#define IG_GET_CURRENT_PROCESS_HANDLE 28
-#define IG_GET_INPUT_LINE             29
-#define IG_GET_EXPRESSION_EX          30
-#define IG_TRANSLATE_VIRTUAL_TO_PHYSICAL 31
-#define IG_GET_CACHE_SIZE             32
-#define IG_READ_PHYSICAL_WITH_FLAGS   33
-#define IG_WRITE_PHYSICAL_WITH_FLAGS  34
-#define IG_POINTER_SEARCH_PHYSICAL    35
-#define IG_OBSOLETE_PLACEHOLDER_36    36
-#define IG_GET_THREAD_OS_INFO         37
-#define IG_GET_CLR_DATA_INTERFACE     38
-#define IG_MATCH_PATTERN_A            39
-#define IG_FIND_FILE                  40
-#define IG_TYPED_DATA_OBSOLETE        41
-#define IG_QUERY_TARGET_INTERFACE     42
-#define IG_TYPED_DATA                 43
-#define IG_DISASSEMBLE_BUFFER         44
-#define IG_GET_ANY_MODULE_IN_RANGE    45
-
-#define IG_GET_TEB_ADDRESS           128
-#define IG_GET_PEB_ADDRESS           129
-
-typedef struct _PROCESSORINFO {
-    USHORT      Processor;                // current processor
-    USHORT      NumberProcessors;         // total number of processors
-} PROCESSORINFO, *PPROCESSORINFO;
-
-typedef struct _READCONTROLSPACE {
-    USHORT      Processor;
-    ULONG       Address;
-    ULONG       BufLen;
-    UCHAR       Buf[1];
-} READCONTROLSPACE, *PREADCONTROLSPACE;
-
-typedef struct _READCONTROLSPACE32 {
-    USHORT      Processor;
-    ULONG       Address;
-    ULONG       BufLen;
-    UCHAR       Buf[1];
-} READCONTROLSPACE32, *PREADCONTROLSPACE32;
-
-typedef struct _READCONTROLSPACE64 {
-    USHORT      Processor;
-    ULONG64     Address;
-    ULONG       BufLen;
-    UCHAR       Buf[1];
-} READCONTROLSPACE64, *PREADCONTROLSPACE64;
-
-typedef struct _IOSPACE {
-    ULONG       Address;
-    ULONG       Length;                   // 1, 2, or 4 bytes
-    ULONG       Data;
-} IOSPACE, *PIOSPACE;
-
-typedef struct _IOSPACE32 {
-    ULONG       Address;
-    ULONG       Length;                   // 1, 2, or 4 bytes
-    ULONG       Data;
-} IOSPACE32, *PIOSPACE32;
-
-typedef struct _IOSPACE64 {
-    ULONG64     Address;
-    ULONG       Length;                   // 1, 2, or 4 bytes
-    ULONG       Data;
-} IOSPACE64, *PIOSPACE64;
-
-typedef struct _IOSPACE_EX {
-    ULONG       Address;
-    ULONG       Length;                   // 1, 2, or 4 bytes
-    ULONG       Data;
-    ULONG       InterfaceType;
-    ULONG       BusNumber;
-    ULONG       AddressSpace;
-} IOSPACE_EX, *PIOSPACE_EX;
-
-typedef struct _IOSPACE_EX32 {
-    ULONG       Address;
-    ULONG       Length;                   // 1, 2, or 4 bytes
-    ULONG       Data;
-    ULONG       InterfaceType;
-    ULONG       BusNumber;
-    ULONG       AddressSpace;
-} IOSPACE_EX32, *PIOSPACE_EX32;
-
-typedef struct _IOSPACE_EX64 {
-    ULONG64     Address;
-    ULONG       Length;                   // 1, 2, or 4 bytes
-    ULONG       Data;
-    ULONG       InterfaceType;
-    ULONG       BusNumber;
-    ULONG       AddressSpace;
-} IOSPACE_EX64, *PIOSPACE_EX64;
-
-typedef struct _GETSETBUSDATA {
-    ULONG       BusDataType;
-    ULONG       BusNumber;
-    ULONG       SlotNumber;
-    PVOID       Buffer;
-    ULONG       Offset;
-    ULONG       Length;
-} BUSDATA, *PBUSDATA;
-
-typedef struct _SEARCHMEMORY {
-    ULONG64 SearchAddress;
-    ULONG64 SearchLength;
-    ULONG64 FoundAddress;
-    ULONG   PatternLength;
-    PVOID   Pattern;
-} SEARCHMEMORY, *PSEARCHMEMORY;
-
-typedef struct _PHYSICAL {
-    ULONGLONG              Address;
-    ULONG                  BufLen;
-    UCHAR                  Buf[1];
-} PHYSICAL, *PPHYSICAL;
-
-#define PHYS_FLAG_DEFAULT        0
-#define PHYS_FLAG_CACHED         1
-#define PHYS_FLAG_UNCACHED       2
-#define PHYS_FLAG_WRITE_COMBINED 3
-
-typedef struct _PHYSICAL_WITH_FLAGS {
-    ULONGLONG              Address;
-    ULONG                  BufLen;
-    ULONG                  Flags;
-    UCHAR                  Buf[1];
-} PHYSICAL_WITH_FLAGS, *PPHYSICAL_WITH_FLAGS;
-
-typedef struct _READ_WRITE_MSR {
-    ULONG       Msr;
-    LONGLONG    Value;
-} READ_WRITE_MSR, *PREAD_WRITE_MSR;
-
-typedef struct _GET_SET_SYMPATH {
-    PCSTR       Args;       // args to !reload command
-    PSTR        Result;     // returns new path
-    int         Length;     // Length of result buffer
-} GET_SET_SYMPATH, *PGET_SET_SYMPATH;
-
-typedef struct _GET_TEB_ADDRESS {
-    ULONGLONG   Address;
-} GET_TEB_ADDRESS, *PGET_TEB_ADDRESS;
-
-typedef struct _GET_PEB_ADDRESS {
-    ULONG64     CurrentThread;
-    ULONGLONG   Address;
-} GET_PEB_ADDRESS, *PGET_PEB_ADDRESS;
-
-typedef struct _GET_CURRENT_THREAD_ADDRESS {
-    ULONG       Processor;
-    ULONG64     Address;
-} GET_CURRENT_THREAD_ADDRESS, *PGET_CURRENT_THREAD_ADDRESS;
-
-typedef struct _GET_CURRENT_PROCESS_ADDRESS {
-    ULONG       Processor;
-    ULONG64     CurrentThread;
-    ULONG64     Address;
-} GET_CURRENT_PROCESS_ADDRESS, *PGET_CURRENT_PROCESS_ADDRESS;
-
-typedef struct _GET_INPUT_LINE {
-    PCSTR       Prompt;
-    PSTR        Buffer;
-    ULONG       BufferSize;
-    ULONG       InputSize;
-} GET_INPUT_LINE, *PGET_INPUT_LINE;
-
-typedef struct _GET_EXPRESSION_EX {
-    PCSTR       Expression;
-    PCSTR       Remainder;
-    ULONG64     Value;
-} GET_EXPRESSION_EX, *PGET_EXPRESSION_EX;
-
-typedef struct _TRANSLATE_VIRTUAL_TO_PHYSICAL {
-    ULONG64     Virtual;
-    ULONG64     Physical;
-} TRANSLATE_VIRTUAL_TO_PHYSICAL, *PTRANSLATE_VIRTUAL_TO_PHYSICAL;
-
-#define PTR_SEARCH_PHYS_ALL_HITS         0x00000001
-#define PTR_SEARCH_PHYS_PTE              0x00000002
-#define PTR_SEARCH_PHYS_RANGE_CHECK_ONLY 0x00000004
-
-#define PTR_SEARCH_PHYS_SIZE_SHIFT 3
-#define PTR_SEARCH_PHYS_SIZE_MASK  (0xf << PTR_SEARCH_PHYS_SIZE_SHIFT)
-
-#define PTR_SEARCH_NO_SYMBOL_CHECK  0x80000000
-
-typedef struct _POINTER_SEARCH_PHYSICAL {
-    IN ULONG64 Offset;
-    IN ULONG64 Length;
-    IN ULONG64 PointerMin;
-    IN ULONG64 PointerMax;
-    IN ULONG Flags;
-    OUT PULONG64 MatchOffsets;
-    IN ULONG MatchOffsetsSize;
-    OUT ULONG MatchOffsetsCount;
-} POINTER_SEARCH_PHYSICAL, *PPOINTER_SEARCH_PHYSICAL;
-
-typedef struct _WDBGEXTS_THREAD_OS_INFO {
-    // System thread ID input.
-    ULONG ThreadId;
-
-    //
-    // Output information.
-    //
-
-    // Exit status is STILL_ACTIVE by default.
-    ULONG ExitStatus;
-    // Priority class is zero if not known.
-    ULONG PriorityClass;
-    // Priority defaults to normal.
-    ULONG Priority;
-    // Times can be zero if not known.
-    ULONG64 CreateTime;
-    ULONG64 ExitTime;
-    ULONG64 KernelTime;
-    ULONG64 UserTime;
-    // Start offset is zero if not known.
-    ULONG64 StartOffset;
-    // Affinity is zero if not known.
-    ULONG64 Affinity;
-} WDBGEXTS_THREAD_OS_INFO, *PWDBGEXTS_THREAD_OS_INFO;
-
-typedef struct _WDBGEXTS_CLR_DATA_INTERFACE {
-    // Interface requested.
-    const IID* Iid;
-    // Interface pointer return.
-    PVOID Iface;
-} WDBGEXTS_CLR_DATA_INTERFACE, *PWDBGEXTS_CLR_DATA_INTERFACE;
-
-typedef struct _EXT_MATCH_PATTERN_A {
-    IN PCSTR Str;
-    IN PCSTR Pattern;
-    IN ULONG CaseSensitive;
-} EXT_MATCH_PATTERN_A, *PEXT_MATCH_PATTERN_A;
-
-#define EXT_FIND_FILE_ALLOW_GIVEN_PATH 0x00000001
-
-typedef struct _EXT_FIND_FILE {
-    IN PCWSTR FileName;
-    IN ULONG64 IndexedSize;
-    IN ULONG ImageTimeDateStamp;
-    // Pass zero to ignore.
-    IN ULONG ImageCheckSum;
-    IN OPTIONAL PVOID ExtraInfo;
-    IN ULONG ExtraInfoSize;
-    IN ULONG Flags;
-    // Free with UnmapViewOfFile.
-    OUT PVOID FileMapping;
-    OUT ULONG64 FileMappingSize;
-    // Free with CloseHandle.
-    OUT HANDLE FileHandle;
-    // Must be at least MAX_PATH characters if set.
-    OUT OPTIONAL PWSTR FoundFileName;
-    OUT ULONG FoundFileNameChars;
-} EXT_FIND_FILE, *PEXT_FIND_FILE;
-
-#define DEBUG_TYPED_DATA_IS_IN_MEMORY            0x00000001
-#define DEBUG_TYPED_DATA_PHYSICAL_DEFAULT        0x00000002
-#define DEBUG_TYPED_DATA_PHYSICAL_CACHED         0x00000004
-#define DEBUG_TYPED_DATA_PHYSICAL_UNCACHED       0x00000006
-#define DEBUG_TYPED_DATA_PHYSICAL_WRITE_COMBINED 0x00000008
-
-// Mask for all physical flags.
-#define DEBUG_TYPED_DATA_PHYSICAL_MEMORY 0x0000000e
-
-typedef struct _DEBUG_TYPED_DATA
-{
-    ULONG64 ModBase;
-    ULONG64 Offset;
-    ULONG64 EngineHandle;
-    ULONG64 Data;
-    ULONG Size;
-    ULONG Flags;
-    ULONG TypeId;
-    ULONG BaseTypeId;
-    ULONG Tag;
-    ULONG Register;
-    ULONG64 Internal[9];
-} DEBUG_TYPED_DATA, *PDEBUG_TYPED_DATA;
-
-typedef enum _EXT_TDOP {
-    EXT_TDOP_COPY,
-    EXT_TDOP_RELEASE,
-    EXT_TDOP_SET_FROM_EXPR,
-    EXT_TDOP_SET_FROM_U64_EXPR,
-    EXT_TDOP_GET_FIELD,
-    EXT_TDOP_EVALUATE,
-    EXT_TDOP_GET_TYPE_NAME,
-    EXT_TDOP_OUTPUT_TYPE_NAME,
-    EXT_TDOP_OUTPUT_SIMPLE_VALUE,
-    EXT_TDOP_OUTPUT_FULL_VALUE,
-    EXT_TDOP_HAS_FIELD,
-    EXT_TDOP_GET_FIELD_OFFSET,
-    EXT_TDOP_GET_ARRAY_ELEMENT,
-    EXT_TDOP_GET_DEREFERENCE,
-    EXT_TDOP_GET_TYPE_SIZE,
-    EXT_TDOP_OUTPUT_TYPE_DEFINITION,
-    EXT_TDOP_GET_POINTER_TO,
-    EXT_TDOP_SET_FROM_TYPE_ID_AND_U64,
-    EXT_TDOP_SET_PTR_FROM_TYPE_ID_AND_U64,
-
-    EXT_TDOP_COUNT
-} EXT_TDOP;
-
-// EXT_TDF physical flags must match DEBUG_TYPED.
-#define EXT_TDF_PHYSICAL_DEFAULT        0x00000002
-#define EXT_TDF_PHYSICAL_CACHED         0x00000004
-#define EXT_TDF_PHYSICAL_UNCACHED       0x00000006
-#define EXT_TDF_PHYSICAL_WRITE_COMBINED 0x00000008
-#define EXT_TDF_PHYSICAL_MEMORY         0x0000000e
-
-// NOTE: Every DEBUG_TYPED_DATA should be released
-// via EXT_TDOP_RELEASE when it is no longer needed.
-typedef struct _EXT_TYPED_DATA {
-    IN EXT_TDOP Operation;
-    IN ULONG Flags;
-    IN DEBUG_TYPED_DATA InData;
-    OUT DEBUG_TYPED_DATA OutData;
-    IN ULONG InStrIndex;
-    IN ULONG In32;
-    OUT ULONG Out32;
-    IN ULONG64 In64;
-    OUT ULONG64 Out64;
-    OUT ULONG StrBufferIndex;
-    IN ULONG StrBufferChars;
-    OUT ULONG StrCharsNeeded;
-    IN OUT ULONG DataBufferIndex;
-    IN ULONG DataBufferBytes;
-    OUT ULONG DataBytesNeeded;
-    OUT HRESULT Status;
-    // Must be zeroed.
-    ULONG64 Reserved[8];
-} EXT_TYPED_DATA, *PEXT_TYPED_DATA;
-
-typedef struct _WDBGEXTS_QUERY_INTERFACE {
-    // Interface requested.
-    const IID* Iid;
-    // Interface pointer return.
-    PVOID Iface;
-} WDBGEXTS_QUERY_INTERFACE, *PWDBGEXTS_QUERY_INTERFACE;
-
-#define WDBGEXTS_ADDRESS_DEFAULT   0x00000000
-#define WDBGEXTS_ADDRESS_SEG16     0x00000001
-#define WDBGEXTS_ADDRESS_SEG32     0x00000002
-#define WDBGEXTS_ADDRESS_RESERVED0 0x80000000
-    
-typedef struct _WDBGEXTS_DISASSEMBLE_BUFFER {
-    IN ULONG64 InOffset;
-    OUT ULONG64 OutOffset;
-    // AddrFlags are from above.
-    IN ULONG AddrFlags;
-    // FormatFlags are from dbgeng's DEBUG_DISASM_*.
-    IN ULONG FormatFlags;
-    IN ULONG DataBufferBytes;
-    IN ULONG DisasmBufferChars;
-    IN OPTIONAL PVOID DataBuffer;
-    OUT PWSTR DisasmBuffer;
-    IN ULONG64 Reserved0[3];
-} WDBGEXTS_DISASSEMBLE_BUFFER, *PWDBGEXTS_DISASSEMBLE_BUFFER;
-
-typedef struct _WDBGEXTS_MODULE_IN_RANGE {
-    IN ULONG64 Start;
-    // Inclusive ending offset.
-    IN ULONG64 End;
-    OUT ULONG64 FoundModBase;
-    OUT ULONG FoundModSize;
-} WDBGEXTS_MODULE_IN_RANGE, *PWDBGEXTS_MODULE_IN_RANGE;
-    
-//
-// If DBGKD_VERS_FLAG_DATA is set in Flags, info should be retrieved from
-// the KDDEBUGGER_DATA block rather than from the DBGKD_GET_VERSION
-// packet.  The data will remain in the version packet for a while to
-// reduce compatibility problems.
-//
-
-#define DBGKD_VERS_FLAG_MP         0x0001   // kernel is MP built
-#define DBGKD_VERS_FLAG_DATA       0x0002   // DebuggerDataList is valid
-#define DBGKD_VERS_FLAG_PTR64      0x0004   // native pointers are 64 bits
-#define DBGKD_VERS_FLAG_NOMM       0x0008   // No MM - don't decode PTEs
-#define DBGKD_VERS_FLAG_HSS        0x0010   // hardware stepping support
-#define DBGKD_VERS_FLAG_PARTITIONS 0x0020   // multiple OS partitions exist
-
-#define KDBG_TAG    'GBDK'
-
-//
-// KD version MajorVersion high-byte identifiers.
-//
-
-typedef enum _DBGKD_MAJOR_TYPES
-{
-    DBGKD_MAJOR_NT,
-    DBGKD_MAJOR_XBOX,
-    DBGKD_MAJOR_BIG,
-    DBGKD_MAJOR_EXDI,
-    DBGKD_MAJOR_NTBD,
-    DBGKD_MAJOR_EFI,
-    DBGKD_MAJOR_TNT,
-    DBGKD_MAJOR_SINGULARITY,
-    DBGKD_MAJOR_HYPERVISOR,
-    DBGKD_MAJOR_COUNT
-} DBGKD_MAJOR_TYPES;
-
-#define DBGKD_MAJOR_TYPE(MajorVersion) \
-    ((DBGKD_MAJOR_TYPES)((MajorVersion) >> 8))
-
-
-// **********************************************************************
-// DO NOT CHANGE THESE 32 BIT STRUCTURES!
-// ONLY MAKE CHAGES TO THE 64 BIT VERSION BELOW!!
-// **********************************************************************
-
-//
-// The following structure has changed in more than pointer size.
-//
-// This is the version packet for pre-NT5 Beta 2 systems.
-// For now, it is also still used on x86
-//
-typedef struct _DBGKD_GET_VERSION32 {
-    USHORT  MajorVersion;
-    USHORT  MinorVersion;
-    USHORT  ProtocolVersion;
-    USHORT  Flags;
-    ULONG   KernBase;
-    ULONG   PsLoadedModuleList;
-
-    USHORT  MachineType;
-
-    //
-    // help for walking stacks with user callbacks:
-    //
-
-    //
-    // The address of the thread structure is provided in the
-    // WAIT_STATE_CHANGE packet.  This is the offset from the base of
-    // the thread structure to the pointer to the kernel stack frame
-    // for the currently active usermode callback.
-    //
-
-    USHORT  ThCallbackStack;            // offset in thread data
-
-    //
-    // these values are offsets into that frame:
-    //
-
-    USHORT  NextCallback;               // saved pointer to next callback frame
-    USHORT  FramePointer;               // saved frame pointer
-
-    //
-    // Address of the kernel callout routine.
-    //
-
-    ULONG   KiCallUserMode;             // kernel routine
-
-    //
-    // Address of the usermode entry point for callbacks.
-    //
-
-    ULONG   KeUserCallbackDispatcher;   // address in ntdll
-
-    //
-    // DbgBreakPointWithStatus is a function which takes a ULONG argument
-    // and hits a breakpoint.  This field contains the address of the
-    // breakpoint instruction.  When the debugger sees a breakpoint
-    // at this address, it may retrieve the argument from the first
-    // argument register, or on x86 the eax register.
-    //
-
-    ULONG   BreakpointWithStatus;       // address of breakpoint
-
-    //
-    // Components may register a debug data block for use by
-    // debugger extensions.  This is the address of the list head.
-    //
-
-    ULONG   DebuggerDataList;
-
-} DBGKD_GET_VERSION32, *PDBGKD_GET_VERSION32;
-
-
-//
-// This is the debugger data packet for pre NT5 Beta 2 systems.
-// For now, it is still used on x86
-//
-
-typedef struct _DBGKD_DEBUG_DATA_HEADER32 {
-
-    LIST_ENTRY32 List;
-    ULONG           OwnerTag;
-    ULONG           Size;
-
-} DBGKD_DEBUG_DATA_HEADER32, *PDBGKD_DEBUG_DATA_HEADER32;
-
-typedef struct _KDDEBUGGER_DATA32 {
-
-    DBGKD_DEBUG_DATA_HEADER32 Header;
-    ULONG   KernBase;
-    ULONG   BreakpointWithStatus;       // address of breakpoint
-    ULONG   SavedContext;
-    USHORT  ThCallbackStack;            // offset in thread data
-    USHORT  NextCallback;               // saved pointer to next callback frame
-    USHORT  FramePointer;               // saved frame pointer
-    USHORT  PaeEnabled:1;
-    ULONG   KiCallUserMode;             // kernel routine
-    ULONG   KeUserCallbackDispatcher;   // address in ntdll
-
-    ULONG   PsLoadedModuleList;
-    ULONG   PsActiveProcessHead;
-    ULONG   PspCidTable;
-
-    ULONG   ExpSystemResourcesList;
-    ULONG   ExpPagedPoolDescriptor;
-    ULONG   ExpNumberOfPagedPools;
-
-    ULONG   KeTimeIncrement;
-    ULONG   KeBugCheckCallbackListHead;
-    ULONG   KiBugcheckData;
-
-    ULONG   IopErrorLogListHead;
-
-    ULONG   ObpRootDirectoryObject;
-    ULONG   ObpTypeObjectType;
-
-    ULONG   MmSystemCacheStart;
-    ULONG   MmSystemCacheEnd;
-    ULONG   MmSystemCacheWs;
-
-    ULONG   MmPfnDatabase;
-    ULONG   MmSystemPtesStart;
-    ULONG   MmSystemPtesEnd;
-    ULONG   MmSubsectionBase;
-    ULONG   MmNumberOfPagingFiles;
-
-    ULONG   MmLowestPhysicalPage;
-    ULONG   MmHighestPhysicalPage;
-    ULONG   MmNumberOfPhysicalPages;
-
-    ULONG   MmMaximumNonPagedPoolInBytes;
-    ULONG   MmNonPagedSystemStart;
-    ULONG   MmNonPagedPoolStart;
-    ULONG   MmNonPagedPoolEnd;
-
-    ULONG   MmPagedPoolStart;
-    ULONG   MmPagedPoolEnd;
-    ULONG   MmPagedPoolInformation;
-    ULONG   MmPageSize;
-
-    ULONG   MmSizeOfPagedPoolInBytes;
-
-    ULONG   MmTotalCommitLimit;
-    ULONG   MmTotalCommittedPages;
-    ULONG   MmSharedCommit;
-    ULONG   MmDriverCommit;
-    ULONG   MmProcessCommit;
-    ULONG   MmPagedPoolCommit;
-    ULONG   MmExtendedCommit;
-
-    ULONG   MmZeroedPageListHead;
-    ULONG   MmFreePageListHead;
-    ULONG   MmStandbyPageListHead;
-    ULONG   MmModifiedPageListHead;
-    ULONG   MmModifiedNoWritePageListHead;
-    ULONG   MmAvailablePages;
-    ULONG   MmResidentAvailablePages;
-
-    ULONG   PoolTrackTable;
-    ULONG   NonPagedPoolDescriptor;
-
-    ULONG   MmHighestUserAddress;
-    ULONG   MmSystemRangeStart;
-    ULONG   MmUserProbeAddress;
-
-    ULONG   KdPrintCircularBuffer;
-    ULONG   KdPrintCircularBufferEnd;
-    ULONG   KdPrintWritePointer;
-    ULONG   KdPrintRolloverCount;
-
-    ULONG   MmLoadedUserImageList;
-
-} KDDEBUGGER_DATA32, *PKDDEBUGGER_DATA32;
-
-// **********************************************************************
-//
-// DO NOT CHANGE KDDEBUGGER_DATA32!!
-// ONLY MAKE CHANGES TO KDDEBUGGER_DATA64!!!
-//
-// **********************************************************************
-
-
-enum
-{
-    DBGKD_SIMULATION_NONE,
-    DBGKD_SIMULATION_EXDI
-};
-
-#define KD_SECONDARY_VERSION_DEFAULT 0
-
-#define KD_SECONDARY_VERSION_AMD64_OBSOLETE_CONTEXT_1 0
-#define KD_SECONDARY_VERSION_AMD64_OBSOLETE_CONTEXT_2 1
-#define KD_SECONDARY_VERSION_AMD64_CONTEXT            2
-
-#ifdef _AMD64_
-#define CURRENT_KD_SECONDARY_VERSION \
-    KD_SECONDARY_VERSION_AMD64_CONTEXT
-#else
-#define CURRENT_KD_SECONDARY_VERSION KD_SECONDARY_VERSION_DEFAULT
-#endif
-
-typedef struct _DBGKD_GET_VERSION64 {
-    USHORT  MajorVersion;
-    USHORT  MinorVersion;
-    UCHAR   ProtocolVersion;
-    UCHAR   KdSecondaryVersion; // Cannot be 'A' for compat with dump header
-    USHORT  Flags;
-    USHORT  MachineType;
-
-    //
-    // Protocol command support descriptions.
-    // These allow the debugger to automatically
-    // adapt to different levels of command support
-    // in different kernels.
-    //
-
-    // One beyond highest packet type understood, zero based.
-    UCHAR   MaxPacketType;
-    // One beyond highest state change understood, zero based.
-    UCHAR   MaxStateChange;
-    // One beyond highest state manipulate message understood, zero based.
-    UCHAR   MaxManipulate;
-
-    // Kind of execution environment the kernel is running in,
-    // such as a real machine or a simulator.  Written back
-    // by the simulation if one exists.
-    UCHAR   Simulation;
-
-    USHORT  Unused[1];
-
-    ULONG64 KernBase;
-    ULONG64 PsLoadedModuleList;
-
-    //
-    // Components may register a debug data block for use by
-    // debugger extensions.  This is the address of the list head.
-    //
-    // There will always be an entry for the debugger.
-    //
-
-    ULONG64 DebuggerDataList;
-
-} DBGKD_GET_VERSION64, *PDBGKD_GET_VERSION64;
-
-
-//
-// This structure is used by the debugger for all targets
-// It is the same size as DBGKD_DATA_HEADER on all systems
-//
-typedef struct _DBGKD_DEBUG_DATA_HEADER64 {
-
-    //
-    // Link to other blocks
-    //
-
-    LIST_ENTRY64 List;
-
-    //
-    // This is a unique tag to identify the owner of the block.
-    // If your component only uses one pool tag, use it for this, too.
-    //
-
-    ULONG           OwnerTag;
-
-    //
-    // This must be initialized to the size of the data block,
-    // including this structure.
-    //
-
-    ULONG           Size;
-
-} DBGKD_DEBUG_DATA_HEADER64, *PDBGKD_DEBUG_DATA_HEADER64;
-
-
-//
-// This structure is the same size on all systems.  The only field
-// which must be translated by the debugger is Header.List.
-//
-
-//
-// DO NOT ADD OR REMOVE FIELDS FROM THE MIDDLE OF THIS STRUCTURE!!!
-//
-// If you remove a field, replace it with an "unused" placeholder.
-// Do not reuse fields until there has been enough time for old debuggers
-// and extensions to age out.
-//
-typedef struct _KDDEBUGGER_DATA64 {
-
-    DBGKD_DEBUG_DATA_HEADER64 Header;
-
-    //
-    // Base address of kernel image
-    //
-
-    ULONG64   KernBase;
-
-    //
-    // DbgBreakPointWithStatus is a function which takes an argument
-    // and hits a breakpoint.  This field contains the address of the
-    // breakpoint instruction.  When the debugger sees a breakpoint
-    // at this address, it may retrieve the argument from the first
-    // argument register, or on x86 the eax register.
-    //
-
-    ULONG64   BreakpointWithStatus;       // address of breakpoint
-
-    //
-    // Address of the saved context record during a bugcheck
-    //
-    // N.B. This is an automatic in KeBugcheckEx's frame, and
-    // is only valid after a bugcheck.
-    //
-
-    ULONG64   SavedContext;
-
-    //
-    // help for walking stacks with user callbacks:
-    //
-
-    //
-    // The address of the thread structure is provided in the
-    // WAIT_STATE_CHANGE packet.  This is the offset from the base of
-    // the thread structure to the pointer to the kernel stack frame
-    // for the currently active usermode callback.
-    //
-
-    USHORT  ThCallbackStack;            // offset in thread data
-
-    //
-    // these values are offsets into that frame:
-    //
-
-    USHORT  NextCallback;               // saved pointer to next callback frame
-    USHORT  FramePointer;               // saved frame pointer
-
-    //
-    // pad to a quad boundary
-    //
-    USHORT  PaeEnabled:1;
-
-    //
-    // Address of the kernel callout routine.
-    //
-
-    ULONG64   KiCallUserMode;             // kernel routine
-
-    //
-    // Address of the usermode entry point for callbacks.
-    //
-
-    ULONG64   KeUserCallbackDispatcher;   // address in ntdll
-
-
-    //
-    // Addresses of various kernel data structures and lists
-    // that are of interest to the kernel debugger.
-    //
-
-    ULONG64   PsLoadedModuleList;
-    ULONG64   PsActiveProcessHead;
-    ULONG64   PspCidTable;
-
-    ULONG64   ExpSystemResourcesList;
-    ULONG64   ExpPagedPoolDescriptor;
-    ULONG64   ExpNumberOfPagedPools;
-
-    ULONG64   KeTimeIncrement;
-    ULONG64   KeBugCheckCallbackListHead;
-    ULONG64   KiBugcheckData;
-
-    ULONG64   IopErrorLogListHead;
-
-    ULONG64   ObpRootDirectoryObject;
-    ULONG64   ObpTypeObjectType;
-
-    ULONG64   MmSystemCacheStart;
-    ULONG64   MmSystemCacheEnd;
-    ULONG64   MmSystemCacheWs;
-
-    ULONG64   MmPfnDatabase;
-    ULONG64   MmSystemPtesStart;
-    ULONG64   MmSystemPtesEnd;
-    ULONG64   MmSubsectionBase;
-    ULONG64   MmNumberOfPagingFiles;
-
-    ULONG64   MmLowestPhysicalPage;
-    ULONG64   MmHighestPhysicalPage;
-    ULONG64   MmNumberOfPhysicalPages;
-
-    ULONG64   MmMaximumNonPagedPoolInBytes;
-    ULONG64   MmNonPagedSystemStart;
-    ULONG64   MmNonPagedPoolStart;
-    ULONG64   MmNonPagedPoolEnd;
-
-    ULONG64   MmPagedPoolStart;
-    ULONG64   MmPagedPoolEnd;
-    ULONG64   MmPagedPoolInformation;
-    ULONG64   MmPageSize;
-
-    ULONG64   MmSizeOfPagedPoolInBytes;
-
-    ULONG64   MmTotalCommitLimit;
-    ULONG64   MmTotalCommittedPages;
-    ULONG64   MmSharedCommit;
-    ULONG64   MmDriverCommit;
-    ULONG64   MmProcessCommit;
-    ULONG64   MmPagedPoolCommit;
-    ULONG64   MmExtendedCommit;
-
-    ULONG64   MmZeroedPageListHead;
-    ULONG64   MmFreePageListHead;
-    ULONG64   MmStandbyPageListHead;
-    ULONG64   MmModifiedPageListHead;
-    ULONG64   MmModifiedNoWritePageListHead;
-    ULONG64   MmAvailablePages;
-    ULONG64   MmResidentAvailablePages;
-
-    ULONG64   PoolTrackTable;
-    ULONG64   NonPagedPoolDescriptor;
-
-    ULONG64   MmHighestUserAddress;
-    ULONG64   MmSystemRangeStart;
-    ULONG64   MmUserProbeAddress;
-
-    ULONG64   KdPrintCircularBuffer;
-    ULONG64   KdPrintCircularBufferEnd;
-    ULONG64   KdPrintWritePointer;
-    ULONG64   KdPrintRolloverCount;
-
-    ULONG64   MmLoadedUserImageList;
-
-    // NT 5.1 Addition
-
-    ULONG64   NtBuildLab;
-    ULONG64   KiNormalSystemCall;
-
-    // NT 5.0 hotfix addition
-
-    ULONG64   KiProcessorBlock;
-    ULONG64   MmUnloadedDrivers;
-    ULONG64   MmLastUnloadedDriver;
-    ULONG64   MmTriageActionTaken;
-    ULONG64   MmSpecialPoolTag;
-    ULONG64   KernelVerifier;
-    ULONG64   MmVerifierData;
-    ULONG64   MmAllocatedNonPagedPool;
-    ULONG64   MmPeakCommitment;
-    ULONG64   MmTotalCommitLimitMaximum;
-    ULONG64   CmNtCSDVersion;
-
-    // NT 5.1 Addition
-
-    ULONG64   MmPhysicalMemoryBlock;
-    ULONG64   MmSessionBase;
-    ULONG64   MmSessionSize;
-    ULONG64   MmSystemParentTablePage;
-
-    // Server 2003 addition
-
-    ULONG64   MmVirtualTranslationBase;
-
-    USHORT    OffsetKThreadNextProcessor;
-    USHORT    OffsetKThreadTeb;
-    USHORT    OffsetKThreadKernelStack;
-    USHORT    OffsetKThreadInitialStack;
-
-    USHORT    OffsetKThreadApcProcess;
-    USHORT    OffsetKThreadState;
-    USHORT    OffsetKThreadBStore;
-    USHORT    OffsetKThreadBStoreLimit;
-
-    USHORT    SizeEProcess;
-    USHORT    OffsetEprocessPeb;
-    USHORT    OffsetEprocessParentCID;
-    USHORT    OffsetEprocessDirectoryTableBase;
-
-    USHORT    SizePrcb;
-    USHORT    OffsetPrcbDpcRoutine;
-    USHORT    OffsetPrcbCurrentThread;
-    USHORT    OffsetPrcbMhz;
-
-    USHORT    OffsetPrcbCpuType;
-    USHORT    OffsetPrcbVendorString;
-    USHORT    OffsetPrcbProcStateContext;
-    USHORT    OffsetPrcbNumber;
-
-    USHORT    SizeEThread;
-
-    ULONG64   KdPrintCircularBufferPtr;
-    ULONG64   KdPrintBufferSize;
-
-    ULONG64   KeLoaderBlock;
-
-    USHORT    SizePcr;
-    USHORT    OffsetPcrSelfPcr;
-    USHORT    OffsetPcrCurrentPrcb;
-    USHORT    OffsetPcrContainedPrcb;
-
-    USHORT    OffsetPcrInitialBStore;
-    USHORT    OffsetPcrBStoreLimit;
-    USHORT    OffsetPcrInitialStack;
-    USHORT    OffsetPcrStackLimit;
-
-    USHORT    OffsetPrcbPcrPage;
-    USHORT    OffsetPrcbProcStateSpecialReg;
-    USHORT    GdtR0Code;
-    USHORT    GdtR0Data;
-
-    USHORT    GdtR0Pcr;
-    USHORT    GdtR3Code;
-    USHORT    GdtR3Data;
-    USHORT    GdtR3Teb;
-
-    USHORT    GdtLdt;
-    USHORT    GdtTss;
-    USHORT    Gdt64R3CmCode;
-    USHORT    Gdt64R3CmTeb;
-
-    ULONG64   IopNumTriageDumpDataBlocks;
-    ULONG64   IopTriageDumpDataBlocks;
-
-    // Longhorn addition
-
-    ULONG64   VfCrashDataBlock;
-    ULONG64   MmBadPagesDetected;
-    ULONG64   MmZeroedPageSingleBitErrorsDetected;
-
-
-} KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64;
-
-
-
-/************************************
-
-   Type Dump Ioctl
-
-*************************************/
-
-
-//
-// Fields are not indented if this is set
-//
-#define DBG_DUMP_NO_INDENT                0x00000001
-//
-// Offsets are not printed if this is set
-//
-#define DBG_DUMP_NO_OFFSET                0x00000002
-//
-// Verbose output
-//
-#define DBG_DUMP_VERBOSE                  0x00000004
-//
-// Callback is done for each of fields
-//
-#define DBG_DUMP_CALL_FOR_EACH            0x00000008
-//
-// A list of type is dumped, listLink should have info about next element pointer
-//
-#define DBG_DUMP_LIST                     0x00000020
-//
-// Nothing is printed if this is set (only callbacks and data copies done)
-//
-#define DBG_DUMP_NO_PRINT                 0x00000040
-//
-// Ioctl returns the size as usual, but will not do field prints/callbacks if this is set
-//
-#define DBG_DUMP_GET_SIZE_ONLY            0x00000080
-//
-// Specifies how much deep into structs we can go
-//
-#define DBG_DUMP_RECUR_LEVEL(l)           ((l & 0xf) << 8)
-//
-// No newlines are printed after each field
-//
-#define DBG_DUMP_COMPACT_OUT              0x00002000
-//
-// An array of type is dumped, number of elements can be specified in listLink->size
-//
-#define DBG_DUMP_ARRAY                    0x00008000
-//
-// The specified addr value is actually the address of field listLink->fName
-//
-#define DBG_DUMP_ADDRESS_OF_FIELD         0x00010000
-
-//
-// The specified addr value is actually the adress at the end of type
-//
-#define DBG_DUMP_ADDRESS_AT_END           0x00020000
-
-//
-// This could be used to copy only the primitive types like ULONG, PVOID etc.
-//    - will not work with structures/unions
-//
-#define DBG_DUMP_COPY_TYPE_DATA           0x00040000
-//
-// Flag to allow read directly from physical memory
-//
-#define DBG_DUMP_READ_PHYSICAL            0x00080000
-//
-// This causes a function type to be dumped in format function(arg1, arg2, ...)
-//
-#define DBG_DUMP_FUNCTION_FORMAT          0x00100000
-//
-// This recurses on a struct but doesn't expand pointers
-//
-#define DBG_DUMP_BLOCK_RECURSE            0x00200000
-//
-// Match the type size to resolve ambiguity in case multiple matches with same name are available
-//
-#define DBG_DUMP_MATCH_SIZE               0x00400000
-
-//
-// Obsolete defs
-//
-#define DBG_RETURN_TYPE                   0
-#define DBG_RETURN_SUBTYPES               0
-#define DBG_RETURN_TYPE_VALUES            0
-
-//
-// Dump and callback optons for fields - Options used in FIELD_INFO.fOptions
-//
-
-//
-// Callback is done before printing the field if this is set
-//
-#define DBG_DUMP_FIELD_CALL_BEFORE_PRINT  0x00000001
-//
-// No callback is done
-//
-#define DBG_DUMP_FIELD_NO_CALLBACK_REQ    0x00000002
-//
-// Subfields of the fields are processesed
-//
-#define DBG_DUMP_FIELD_RECUR_ON_THIS      0x00000004
-//
-// fName must match completely for the field to be dumped instead just a prefix
-//  match by default
-//
-#define DBG_DUMP_FIELD_FULL_NAME          0x00000008
-//
-// This causes array elements of an array field to be printed
-//
-#define DBG_DUMP_FIELD_ARRAY              0x00000010
-//
-// The data of the field is copied into fieldCallBack
-//
-#define DBG_DUMP_FIELD_COPY_FIELD_DATA    0x00000020
-//
-// In callback or when Ioctl returns, the FIELD_INFO.address has the address of field.
-//  If no address is supplied for the type, it contains total offset of the field.
-//
-#define DBG_DUMP_FIELD_RETURN_ADDRESS     0x00001000
-//
-// Return the offset and size in bits instead of bytes is case of Bitfield
-//
-#define DBG_DUMP_FIELD_SIZE_IN_BITS       0x00002000
-//
-// Nothing is printed  for field if this is set (only callbacks and data copies done)
-//
-#define DBG_DUMP_FIELD_NO_PRINT           0x00004000
-//
-// If the field is a pointer, it is dumped as a string, ANSI, WCHAR, MULTI or GUID
-// depending on following options
-//
-#define DBG_DUMP_FIELD_DEFAULT_STRING     0x00010000
-#define DBG_DUMP_FIELD_WCHAR_STRING       0x00020000
-#define DBG_DUMP_FIELD_MULTI_STRING       0x00040000
-#define DBG_DUMP_FIELD_GUID_STRING        0x00080000
-
-
-//
-// Error status returned on TYPE DUMP Ioctl failure
-//
-#define MEMORY_READ_ERROR            0x01
-#define SYMBOL_TYPE_INDEX_NOT_FOUND  0x02
-#define SYMBOL_TYPE_INFO_NOT_FOUND   0x03
-#define FIELDS_DID_NOT_MATCH         0x04
-#define NULL_SYM_DUMP_PARAM          0x05
-#define NULL_FIELD_NAME              0x06
-#define INCORRECT_VERSION_INFO       0x07
-#define EXIT_ON_CONTROLC             0x08
-#define CANNOT_ALLOCATE_MEMORY       0x09
-#define INSUFFICIENT_SPACE_TO_COPY   0x0a
-#define ADDRESS_TYPE_INDEX_NOT_FOUND 0x0b
-
-
-//////////////////////////////////////////////////////////////////////////*/
-
-
-typedef
-ULONG
-(WDBGAPI*PSYM_DUMP_FIELD_CALLBACK)(
-    struct _FIELD_INFO *pField,
-    PVOID UserContext
-    );
-
-typedef struct _FIELD_INFO {
-   PUCHAR       fName;          // Name of the field
-   PUCHAR       printName;      // Name to be printed at dump
-   ULONG        size;           // Size of the field
-   ULONG        fOptions;       // Dump Options for the field
-   ULONG64      address;        // address of the field
-   union {
-       PVOID    fieldCallBack;  // Return info or callBack routine for the field
-       PVOID    pBuffer;        // the type data is copied into this
-   };
-   ULONG        TypeId;         // OUT Type index of the field
-   ULONG        FieldOffset;    // OUT Offset of field inside struct
-   ULONG        BufferSize;     // size of buffer used with DBG_DUMP_FIELD_COPY_FIELD_DATA
-   struct _BitField {
-       USHORT Position;         // OUT set to start position for bitfield
-       USHORT Size;             // OUT set to size for bitfields
-   } BitField;
-   ULONG        fPointer:2;     // OUT set to 1 for pointers, 3 for 64bit pointers
-   ULONG        fArray:1;       // OUT set to 1 for array types
-   ULONG        fStruct:1;      // OUT set to 1 for struct/class tyoes
-   ULONG        fConstant:1;    // OUT set to 1 for constants (enumerate as fields)
-   ULONG        fStatic:1;      // OUT set to 1 for statics (class/struct static members)
-   ULONG        Reserved:26;    // unused
-} FIELD_INFO, *PFIELD_INFO;
-
-typedef struct _SYM_DUMP_PARAM {
-   ULONG               size;          // size of this struct
-   PUCHAR              sName;         // type name
-   ULONG               Options;       // Dump options
-   ULONG64             addr;          // Address to take data for type
-   PFIELD_INFO         listLink;      // fName here would be used to do list dump
-   union {
-       PVOID           Context;       // Usercontext passed to CallbackRoutine
-       PVOID           pBuffer;       // the type data is copied into this
-   };
-   PSYM_DUMP_FIELD_CALLBACK CallbackRoutine;
-                                      // Routine called back
-   ULONG               nFields;       // # elements in Fields
-   __field_ecount_opt(nFields) PFIELD_INFO         Fields;        // Used to return information about field
-   ULONG64             ModBase;       // OUT Module base address containing type
-   ULONG               TypeId;        // OUT Type index of the symbol
-   ULONG               TypeSize;      // OUT Size of type
-   ULONG               BufferSize;    // IN size of buffer (used with DBG_DUMP_COPY_TYPE_DATA)
-   ULONG               fPointer:2;    // OUT set to 1 for pointers, 3 for 64bit pointers
-   ULONG               fArray:1;      // OUT set to 1 for array types
-   ULONG               fStruct:1;     // OUT set to 1 for struct/class tyoes
-   ULONG               fConstant:1;   // OUT set to 1 for constant types (unused)
-   ULONG               Reserved:27;   // unused
-} SYM_DUMP_PARAM, *PSYM_DUMP_PARAM;
-
-#ifdef __cplusplus
-#define CPPMOD extern "C"
-#else
-#define CPPMOD
-#endif
-
-
-#ifndef NOEXTAPI
-
-#if   defined(KDEXT_64BIT)
-#define WINDBG_EXTENSION_APIS WINDBG_EXTENSION_APIS64
-#define PWINDBG_EXTENSION_APIS PWINDBG_EXTENSION_APIS64
-#define PWINDBG_EXTENSION_ROUTINE PWINDBG_EXTENSION_ROUTINE64
-#define DECLARE_API(s) DECLARE_API64(s)
-#elif defined(KDEXT_32BIT)
-#define WINDBG_EXTENSION_APIS WINDBG_EXTENSION_APIS32
-#define PWINDBG_EXTENSION_APIS PWINDBG_EXTENSION_APIS32
-#define PWINDBG_EXTENSION_ROUTINE PWINDBG_EXTENSION_ROUTINE32
-#define DECLARE_API(s) DECLARE_API32(s)
-#else
-#define DECLARE_API(s)                             \
-    CPPMOD VOID                                    \
-    s(                                             \
-        HANDLE                 hCurrentProcess,    \
-        HANDLE                 hCurrentThread,     \
-        ULONG                  dwCurrentPc,        \
-        ULONG                  dwProcessor,        \
-        PCSTR                  args                \
-     )
-#endif
-
-#define DECLARE_API32(s)                           \
-    CPPMOD VOID                                    \
-    s(                                             \
-        HANDLE                 hCurrentProcess,    \
-        HANDLE                 hCurrentThread,     \
-        ULONG                  dwCurrentPc,        \
-        ULONG                  dwProcessor,        \
-        PCSTR                  args                \
-     )
-
-#define DECLARE_API64(s)                           \
-    CPPMOD VOID                                    \
-    s(                                             \
-        HANDLE                 hCurrentProcess,    \
-        HANDLE                 hCurrentThread,     \
-        ULONG64                dwCurrentPc,        \
-        ULONG                  dwProcessor,        \
-        PCSTR                  args                \
-     )
-
-
-extern WINDBG_EXTENSION_APIS   ExtensionApis;
-
-
-#define dprintf          (ExtensionApis.lpOutputRoutine)
-#define GetExpression    (ExtensionApis.lpGetExpressionRoutine)
-#define CheckControlC    (ExtensionApis.lpCheckControlCRoutine)
-#define GetContext       (ExtensionApis.lpGetThreadContextRoutine)
-#define SetContext       (ExtensionApis.lpSetThreadContextRoutine)
-#define Ioctl            (ExtensionApis.lpIoctlRoutine)
-#define Disasm           (ExtensionApis.lpDisasmRoutine)
-#define GetSymbol        (ExtensionApis.lpGetSymbolRoutine)
-#define ReadMemory       (ExtensionApis.lpReadProcessMemoryRoutine)
-#define WriteMemory      (ExtensionApis.lpWriteProcessMemoryRoutine)
-#define StackTrace       (ExtensionApis.lpStackTraceRoutine)
-
-
-#define GetKdContext(ppi) \
-    Ioctl( IG_KD_CONTEXT, (PVOID)ppi, sizeof(*ppi) )
-
-
-//
-// BOOL
-// GetDebuggerData(
-//     ULONG Tag,
-//     PVOID Buf,
-//     ULONG Size
-//     )
-//
-
-#define GetDebuggerData(TAG, BUF, SIZE)                             \
-      ( (((PDBGKD_DEBUG_DATA_HEADER64)(BUF))->OwnerTag = (TAG)),      \
-        (((PDBGKD_DEBUG_DATA_HEADER64)(BUF))->Size = (SIZE)),         \
-        Ioctl( IG_GET_DEBUGGER_DATA, (PVOID)(BUF), (SIZE) ) )
-
-// Check if LocalAlloc is prototyped
-//#ifdef _WINBASE_
-
-#ifndef FEATURE_PAL
-__inline VOID
-ReadPhysical(
-    ULONG64             address,
-    PVOID               buf,
-    ULONG               size,
-    PULONG              sizer
-    )
-{
-    PPHYSICAL phy = NULL;
-    *sizer = 0;
-    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*phy)) {
-        phy = (PPHYSICAL)LocalAlloc(LPTR,  sizeof(*phy) + size );
-    }
-    if (phy) {
-        ZeroMemory( phy->Buf, size );
-        phy->Address = address;
-        phy->BufLen = size;
-        Ioctl( IG_READ_PHYSICAL, (PVOID)phy, sizeof(*phy) + size );
-        *sizer = phy->BufLen;
-        CopyMemory( buf, phy->Buf, *sizer );
-        LocalFree( phy );
-    }
-}
-
-__inline VOID
-WritePhysical(
-    ULONG64             address,
-    PVOID               buf,
-    ULONG               size,
-    PULONG              sizew
-    )
-{
-    PPHYSICAL phy = NULL;
-    *sizew = 0;
-    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*phy)) {
-        phy = (PPHYSICAL)LocalAlloc(LPTR, sizeof(*phy) + size );
-    }
-    if (phy) {
-        ZeroMemory( phy->Buf, size );
-        phy->Address = address;
-        phy->BufLen = size;
-        CopyMemory( phy->Buf, buf, size );
-        Ioctl( IG_WRITE_PHYSICAL, (PVOID)phy, sizeof(*phy) + size );
-        *sizew = phy->BufLen;
-        LocalFree( phy );
-    }
-}
-
-__inline VOID
-ReadPhysicalWithFlags(
-    ULONG64             address,
-    PVOID               buf,
-    ULONG               size,
-    ULONG               flags,
-    PULONG              sizer
-    )
-{
-    PPHYSICAL_WITH_FLAGS phy = NULL;
-    *sizer = 0;
-    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*phy)) {
-        phy = (PPHYSICAL_WITH_FLAGS)LocalAlloc(LPTR,  sizeof(*phy) + size );
-    }
-    if (phy) {
-        ZeroMemory( phy->Buf, size );
-        phy->Address = address;
-        phy->BufLen = size;
-        phy->Flags = flags;
-        Ioctl( IG_READ_PHYSICAL_WITH_FLAGS, (PVOID)phy, sizeof(*phy) + size );
-        *sizer = phy->BufLen;
-        CopyMemory( buf, phy->Buf, *sizer );
-        LocalFree( phy );
-    }
-}
-
-__inline VOID
-WritePhysicalWithFlags(
-    ULONG64             address,
-    PVOID               buf,
-    ULONG               size,
-    ULONG               flags,
-    PULONG              sizew
-    )
-{
-    PPHYSICAL_WITH_FLAGS phy = NULL;
-    *sizew = 0;
-    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*phy)) {
-        phy = (PPHYSICAL_WITH_FLAGS)LocalAlloc(LPTR, sizeof(*phy) + size );
-    }
-    if (phy) {
-        ZeroMemory( phy->Buf, size );
-        phy->Address = address;
-        phy->BufLen = size;
-        phy->Flags = flags;
-        CopyMemory( phy->Buf, buf, size );
-        Ioctl( IG_WRITE_PHYSICAL_WITH_FLAGS, (PVOID)phy, sizeof(*phy) + size );
-        *sizew = phy->BufLen;
-        LocalFree( phy );
-    }
-}
-
-__inline VOID
-ReadMsr(
-    ULONG       MsrReg,
-    ULONGLONG   *MsrValue
-    )
-{
-    READ_WRITE_MSR msr;
-
-    msr.Msr = MsrReg;
-    Ioctl( IG_READ_MSR, (PVOID)&msr, sizeof(msr) );
-
-    *MsrValue = msr.Value;
-}
-
-__inline VOID
-WriteMsr(
-    ULONG       MsrReg,
-    ULONGLONG   MsrValue
-    )
-{
-    READ_WRITE_MSR msr;
-
-    msr.Msr = MsrReg;
-    msr.Value = MsrValue;
-    Ioctl( IG_WRITE_MSR, (PVOID)&msr, sizeof(msr) );
-}
-
-__inline VOID
-SetThreadForOperation(
-    ULONG_PTR * Thread
-    )
-{
-    Ioctl(IG_SET_THREAD, (PVOID)Thread, sizeof(PULONG));
-}
-
-__inline VOID
-SetThreadForOperation32(
-    ULONG Thread
-    )
-{
-    Ioctl(IG_SET_THREAD, (PVOID)LongToPtr(Thread), sizeof(ULONG));
-}
-
-__inline VOID
-SetThreadForOperation64(
-    PULONG64 Thread
-    )
-{
-    Ioctl(IG_SET_THREAD, (PVOID)Thread, sizeof(ULONG64));
-}
-
-
-__inline VOID
-ReadControlSpace(
-    USHORT  processor,
-    ULONG   address,
-    PVOID   buf,
-    ULONG   size
-    )
-{
-    PREADCONTROLSPACE prc = NULL;
-    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*prc)) {
-        prc = (PREADCONTROLSPACE)LocalAlloc(LPTR, sizeof(*prc) + size );
-    }
-    if (prc) {
-        ZeroMemory( prc->Buf, size );
-        prc->Processor = processor;
-        prc->Address = address;
-        prc->BufLen = size;
-        Ioctl( IG_READ_CONTROL_SPACE, (PVOID)prc, sizeof(*prc) + size );
-        CopyMemory( buf, prc->Buf, size );
-        LocalFree( prc );
-    }
-}
-
-__inline VOID
-ReadControlSpace32(
-    USHORT  processor,
-    ULONG   address,
-    PVOID   buf,
-    ULONG   size
-    )
-{
-    PREADCONTROLSPACE32 prc = NULL;
-    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*prc)) {
-        prc = (PREADCONTROLSPACE32)LocalAlloc(LPTR, sizeof(*prc) + size );
-    }
-    if (prc) {
-        ZeroMemory( prc->Buf, size );
-        prc->Processor = processor;
-        prc->Address = address;
-        prc->BufLen = size;
-        Ioctl( IG_READ_CONTROL_SPACE, (PVOID)prc, sizeof(*prc) + size );
-        CopyMemory( buf, prc->Buf, size );
-        LocalFree( prc );
-    }
-}
-
-#define ReadTypedControlSpace32( _Proc, _Addr, _Buf )  \
-     ReadControlSpace64( (USHORT)(_Proc), (ULONG)(_Addr), (PVOID)&(_Buf), (ULONG)sizeof(_Buf) )
-
-__inline VOID
-ReadControlSpace64(
-    USHORT  processor,
-    ULONG64 address,
-    PVOID   buf,
-    ULONG   size
-    )
-{
-    PREADCONTROLSPACE64 prc = NULL;
-    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*prc)) {
-        prc = (PREADCONTROLSPACE64)LocalAlloc(LPTR, sizeof(*prc) + size );
-    }
-    if (prc) {
-        ZeroMemory( prc->Buf, size );
-        prc->Processor = processor;
-        prc->Address = address;
-        prc->BufLen = size;
-        Ioctl( IG_READ_CONTROL_SPACE, (PVOID)prc, sizeof(*prc) + size );
-        CopyMemory( buf, prc->Buf, size );
-        LocalFree( prc );
-    }
-}
-
-#define ReadTypedControlSpace64( _Proc, _Addr, _Buf )  \
-     ReadControlSpace64( (USHORT)(_Proc), (ULONG64)(_Addr), (PVOID)&(_Buf), (ULONG)sizeof(_Buf) )
-
-__inline VOID
-WriteControlSpace(
-    USHORT  processor,
-    ULONG   address,
-    PVOID   buf,
-    ULONG   size
-    )
-{
-    PREADCONTROLSPACE64 prc = NULL;
-    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*prc)) {
-        prc = (PREADCONTROLSPACE64)LocalAlloc(LPTR, sizeof(*prc) + size );
-    }
-    if (prc) {
-        ZeroMemory( prc->Buf, size );
-        prc->Processor = processor;
-        prc->Address = address;
-        prc->BufLen = size;
-        CopyMemory( prc->Buf, buf, size );
-        Ioctl( IG_WRITE_CONTROL_SPACE, (PVOID)prc, sizeof(*prc) + size );
-        LocalFree( prc );
-    }
-}
-
-// #endif //  _WINBASE_
-
-__inline VOID
-ReadIoSpace(
-    ULONG   address,
-    PULONG  data,
-    PULONG  size
-    )
-{
-    IOSPACE is;
-    is.Address = address;
-    is.Length = *size;
-    Ioctl( IG_READ_IO_SPACE, (PVOID)&is, sizeof(is) );
-    memcpy(data, &is.Data, is.Length);
-    *size = is.Length;
-}
-
-__inline VOID
-ReadIoSpace32(
-    ULONG   address,
-    PULONG  data,
-    PULONG  size
-    )
-{
-    IOSPACE32 is;
-    is.Address = address;
-    is.Length = *size;
-    Ioctl( IG_READ_IO_SPACE, (PVOID)&is, sizeof(is) );
-    memcpy(data, &is.Data, is.Length);
-    *size = is.Length;
-}
-
-__inline VOID
-ReadIoSpace64(
-    ULONG64 address,
-    PULONG  data,
-    PULONG  size
-    )
-{
-    IOSPACE64 is;
-    is.Address = address;
-    is.Length = *size;
-    Ioctl( IG_READ_IO_SPACE, (PVOID)&is, sizeof(is) );
-    memcpy(data, &is.Data, is.Length);
-    *size = is.Length;
-}
-
-__inline VOID
-WriteIoSpace(
-    ULONG   address,
-    ULONG   data,
-    PULONG  size
-    )
-{
-    IOSPACE is;
-    is.Address = (ULONG)address;
-    is.Length = *size;
-    is.Data = data;
-    Ioctl( IG_WRITE_IO_SPACE, (PVOID)&is, sizeof(is) );
-    *size = is.Length;
-}
-
-__inline VOID
-WriteIoSpace32(
-    ULONG   address,
-    ULONG   data,
-    PULONG  size
-    )
-{
-    IOSPACE32 is;
-    is.Address = address;
-    is.Length = *size;
-    is.Data = data;
-    Ioctl( IG_WRITE_IO_SPACE, (PVOID)&is, sizeof(is) );
-    *size = is.Length;
-}
-
-__inline VOID
-WriteIoSpace64(
-    ULONG64 address,
-    ULONG   data,
-    PULONG  size
-    )
-{
-    IOSPACE64 is;
-    is.Address = address;
-    is.Length = *size;
-    is.Data = data;
-    Ioctl( IG_WRITE_IO_SPACE, (PVOID)&is, sizeof(is) );
-    *size = is.Length;
-}
-
-__inline VOID
-ReadIoSpaceEx(
-    ULONG   address,
-    PULONG  data,
-    PULONG  size,
-    ULONG   interfacetype,
-    ULONG   busnumber,
-    ULONG   addressspace
-    )
-{
-    IOSPACE_EX is;
-    is.Address = (ULONG)address;
-    is.Length = *size;
-    is.Data = 0;
-    is.InterfaceType = interfacetype;
-    is.BusNumber = busnumber;
-    is.AddressSpace = addressspace;
-    Ioctl( IG_READ_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
-    *data = is.Data;
-    *size = is.Length;
-}
-
-__inline VOID
-ReadIoSpaceEx32(
-    ULONG   address,
-    PULONG  data,
-    PULONG  size,
-    ULONG   interfacetype,
-    ULONG   busnumber,
-    ULONG   addressspace
-    )
-{
-    IOSPACE_EX32 is;
-    is.Address = address;
-    is.Length = *size;
-    is.Data = 0;
-    is.InterfaceType = interfacetype;
-    is.BusNumber = busnumber;
-    is.AddressSpace = addressspace;
-    Ioctl( IG_READ_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
-    *data = is.Data;
-    *size = is.Length;
-}
-
-__inline VOID
-ReadIoSpaceEx64(
-    ULONG64 address,
-    PULONG  data,
-    PULONG  size,
-    ULONG   interfacetype,
-    ULONG   busnumber,
-    ULONG   addressspace
-    )
-{
-    IOSPACE_EX64 is;
-    is.Address = address;
-    is.Length = *size;
-    is.Data = 0;
-    is.InterfaceType = interfacetype;
-    is.BusNumber = busnumber;
-    is.AddressSpace = addressspace;
-    Ioctl( IG_READ_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
-    *data = is.Data;
-    *size = is.Length;
-}
-
-__inline VOID
-WriteIoSpaceEx(
-    ULONG   address,
-    ULONG   data,
-    PULONG  size,
-    ULONG   interfacetype,
-    ULONG   busnumber,
-    ULONG   addressspace
-    )
-{
-    IOSPACE_EX is;
-    is.Address = (ULONG)address;
-    is.Length = *size;
-    is.Data = data;
-    is.InterfaceType = interfacetype;
-    is.BusNumber = busnumber;
-    is.AddressSpace = addressspace;
-    Ioctl( IG_WRITE_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
-    *size = is.Length;
-}
-
-__inline VOID
-WriteIoSpaceEx32(
-    ULONG   address,
-    ULONG   data,
-    PULONG  size,
-    ULONG   interfacetype,
-    ULONG   busnumber,
-    ULONG   addressspace
-    )
-{
-    IOSPACE_EX32 is;
-    is.Address = address;
-    is.Length = *size;
-    is.Data = data;
-    is.InterfaceType = interfacetype;
-    is.BusNumber = busnumber;
-    is.AddressSpace = addressspace;
-    Ioctl( IG_WRITE_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
-    *size = is.Length;
-}
-
-__inline VOID
-WriteIoSpaceEx64(
-    ULONG64 address,
-    ULONG   data,
-    PULONG  size,
-    ULONG   interfacetype,
-    ULONG   busnumber,
-    ULONG   addressspace
-    )
-{
-    IOSPACE_EX64 is;
-    is.Address = address;
-    is.Length = *size;
-    is.Data = data;
-    is.InterfaceType = interfacetype;
-    is.BusNumber = busnumber;
-    is.AddressSpace = addressspace;
-    Ioctl( IG_WRITE_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
-    *size = is.Length;
-}
-
-__inline VOID
-ReloadSymbols(
-    IN PSTR Arg OPTIONAL
-    )
-/*++
-
-Routine Description:
-
-    Calls the debugger to reload symbols.
-
-Arguments:
-
-    Args - Supplies the tail of a !reload command string.
-
-        !reload [flags] [module[=address]]
-        flags:   /n  do not load from usermode list
-                 /u  unload symbols, no reload
-                 /v  verbose
-
-        A value of NULL is equivalent to an empty string
-
-Return Value:
-
-    None
-
---*/
-{
-    Ioctl(IG_RELOAD_SYMBOLS, (PVOID)Arg, Arg?((ULONG)strlen(Arg)+1):0);
-}
-
-__inline VOID
-GetSetSympath(
-    IN PSTR Arg,
-    OUT PSTR Result OPTIONAL,
-    IN int Length
-    )
-/*++
-
-Routine Description:
-
-    Calls the debugger to set or retrieve symbol search path.
-
-Arguments:
-
-    Arg - Supplies new search path.  If Arg is NULL or string is empty,
-            the search path is not changed and the current setting is
-            returned in Result.  When the symbol search path is changed,
-            a call to ReloadSymbols is made implicitly.
-
-    Result - OPTIONAL Returns the symbol search path setting.
-
-    Length - Supplies the size of the buffer supplied by Result.
-
-Return Value:
-
-    None
-
---*/
-{
-    GET_SET_SYMPATH gss;
-    gss.Args = Arg;
-    gss.Result = Result;
-    gss.Length = Length;
-    Ioctl(IG_GET_SET_SYMPATH, (PVOID)&gss, sizeof(gss));
-}
-
-#if   defined(KDEXT_64BIT)
-
-__inline
-ULONG
-IsPtr64(
-    void
-    )
-{
-    ULONG flag;
-    ULONG dw;
-
-    if (Ioctl(IG_IS_PTR64, &dw, sizeof(dw))) {
-        flag = ((dw != 0) ? 1 : 0);
-    } else {
-        flag = 0;
-    }
-    return flag;
-}
-
-__inline
-ULONG
-ReadListEntry(
-    ULONG64 Address,
-    PLIST_ENTRY64 List
-    )
-{
-    ULONG cb;
-    if (IsPtr64()) {
-        return (ReadMemory(Address, (PVOID)List, sizeof(*List), &cb) &&
-                cb == sizeof(*List));
-    } else {
-        LIST_ENTRY32 List32;
-        ULONG Status;
-        Status = ReadMemory(Address,
-                            (PVOID)&List32,
-                            sizeof(List32),
-                            &cb);
-        if (Status && cb == sizeof(List32)) {
-            List->Flink = (ULONG64)(LONG64)(LONG)List32.Flink;
-            List->Blink = (ULONG64)(LONG64)(LONG)List32.Blink;
-            return 1;
-        }
-        return 0;
-    }
-}
-
-__inline
-ULONG
-ReadPointer(
-    ULONG64 Address,
-    PULONG64 Pointer
-    )
-{
-    ULONG cb;
-    if (IsPtr64()) {
-        return (ReadMemory(Address, (PVOID)Pointer, sizeof(*Pointer), &cb) &&
-                cb == sizeof(*Pointer));
-    } else {
-        ULONG Pointer32;
-        ULONG Status;
-        Status = ReadMemory(Address,
-                            (PVOID)&Pointer32,
-                            sizeof(Pointer32),
-                            &cb);
-        if (Status && cb == sizeof(Pointer32)) {
-            *Pointer = (ULONG64)(LONG64)(LONG)Pointer32;
-            return 1;
-        }
-        return 0;
-    }
-}
-
-__inline
-ULONG
-WritePointer(
-    ULONG64 Address,
-    ULONG64 Pointer
-    )
-{
-    ULONG cb;
-    if (IsPtr64()) {
-        return (WriteMemory(Address, &Pointer, sizeof(Pointer), &cb) &&
-                cb == sizeof(Pointer));
-    } else {
-        ULONG Pointer32 = (ULONG)Pointer;
-        ULONG Status;
-        Status = WriteMemory(Address,
-                             &Pointer32,
-                             sizeof(Pointer32),
-                             &cb);
-        return (Status && cb == sizeof(Pointer32)) ? 1 : 0;
-    }
-}
-
-/**
-   This does Ioctl call for type info and returns size of the type on success.
-
- **/
-__inline
-ULONG
-GetTypeSize (
-   IN LPCSTR    Type
-   )
-{
-#ifndef FEATURE_PAL
-   SYM_DUMP_PARAM Sym = {
-      sizeof (SYM_DUMP_PARAM), (PUCHAR)Type, DBG_DUMP_NO_PRINT | DBG_DUMP_GET_SIZE_ONLY, 0,
-      NULL, NULL, NULL, 0, NULL
-   };
-
-   return Ioctl( IG_GET_TYPE_SIZE, &Sym, Sym.size );
-#else
-    return (ULONG)~0;
-#endif
-}
-
-/**
-    GetFieldData
-
-   Copies the value of the specified field into pOutValue assuming TypeAddress
-   points to start of the type in debugee.
-
-   If the Field is NULL and the size of Type is <= 8 Whole type value is read into
-   pOutValue. This is to allow to read in primitive types suchas ULONG, PVOID etc.
-
-   If address is zero this considers Type a global variable.
-
-   It raises an exception if OutSize is less than size to be copied.
-
-   Returns 0 on success, errorvalue (defined with SYM_DUMP_PARAM) otherwise.
-
- **/
-__inline
-ULONG
-GetFieldData (
-    IN  ULONG64 TypeAddress,
-    IN  LPCSTR  Type,
-    IN  LPCSTR  Field,
-    IN  ULONG   OutSize,
-    OUT PVOID   pOutValue
-   )
-{
-#ifndef FEATURE_PAL
-   FIELD_INFO flds = {(PUCHAR)Field, NULL, 0, DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_COPY_FIELD_DATA | DBG_DUMP_FIELD_RETURN_ADDRESS, 0, pOutValue};
-   SYM_DUMP_PARAM Sym = {
-      sizeof (SYM_DUMP_PARAM), (PUCHAR)Type, DBG_DUMP_NO_PRINT, TypeAddress,
-      NULL, NULL, NULL, 1, &flds
-   };
-   ULONG RetVal;
-
-   if (!Field) {
-       Sym.nFields =0; Sym.Options |= DBG_DUMP_COPY_TYPE_DATA;
-       Sym.Context = pOutValue;
-   }
-
-   ZeroMemory(pOutValue, OutSize);
-   RetVal = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
-
-   if (OutSize < ((Field == NULL) ? 8 : flds.size)) {
-       // Fail
-       dprintf("Not enough space to read %s-%s\n", Type, Field);
-       RaiseException((DWORD)EXCEPTION_ACCESS_VIOLATION, 0, 0, NULL);
-       return 0;
-   }
-   return RetVal;
-#else
-    return (ULONG)~0;
-#endif
-}
-
-//
-// Typecast the buffer where value is to be read
-//
-#define GetFieldValue(Addr, Type, Field, OutValue)         \
-     GetFieldData(Addr, Type, Field, sizeof(OutValue), (PVOID) &(OutValue))
-
-//
-// Used to read in value of a short (<= 8 bytes) fields
-//
-__inline
-ULONG64
-GetShortField (
-    IN  ULONG64 TypeAddress,
-    IN  LPCSTR  Name,
-    IN  USHORT  StoreAddress
-   )
-{
-#ifndef FEATURE_PAL
-    static ULONG64 SavedAddress;
-    static PUCHAR  SavedName;
-    static ULONG   ReadPhysical;
-    FIELD_INFO flds = {(PUCHAR) Name, NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL};
-    SYM_DUMP_PARAM Sym = {
-       sizeof (SYM_DUMP_PARAM), SavedName, DBG_DUMP_NO_PRINT | ((StoreAddress & 2) ? DBG_DUMP_READ_PHYSICAL : 0),
-       SavedAddress, NULL, NULL, NULL, 1, &flds
-    };
-
-
-    if (StoreAddress) {
-        Sym.sName = (PUCHAR) Name;
-        Sym.nFields = 0;
-        SavedName = (PUCHAR) Name;
-        Sym.addr = SavedAddress = TypeAddress;
-        ReadPhysical = (StoreAddress & 2);
-        return SavedAddress ? Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size ) : MEMORY_READ_ERROR; // zero on success
-    } else {
-        Sym.Options |= ReadPhysical ? DBG_DUMP_READ_PHYSICAL : 0;
-    }
-
-    if (!Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size )) {
-        return flds.address;
-    }
-    return 0;
-#else
-    return (ULONG64)~0;
-#endif
-}
-
-//
-// Stores the address and type name for future reads
-//
-#define InitTypeRead(Addr, Type)  GetShortField(Addr, #Type, 1)
-#define InitTypeStrRead(Addr, TypeStr)  GetShortField(Addr, TypeStr, 1)
-
-//
-// Stores the address and type name for future reads
-//
-#define InitTypeReadPhysical(Addr, Type)  GetShortField(Addr, #Type, 3)
-#define InitTypeStrReadPhysical(Addr, TypeStr)  GetShortField(Addr, TypeStr, 3)
-
-//
-// Returns the field's value as ULONG64 if size of field is <= sizeof (ULONG64)
-//
-#define ReadField(Field)          GetShortField(0, #Field, 0)
-#define ReadFieldStr(FieldStr)          GetShortField(0, FieldStr, 0)
-
-//
-// Read in a pointer value
-//
-__inline
-ULONG
-ReadPtr(
-    ULONG64 Addr,
-    PULONG64 pPointer
-    )
-{
-    return !ReadPointer(Addr, pPointer);
-}
-
-/*
- * ListType
- *
- *  Routine ListType gives a callback on each element in the list of Type.
- *
- *   Type  :  Name of the type to be listed
- *
- *   NextPointer : Name of field which gives address of next element in list
- *
- *   Context, CallbackRoutine :
- *            Context and the callback routine. The address field in PFIELD_INFO
- *            parameter of callback contains the address of next Type element in list.
- *
- *   Address, ListByFieldAddress :
- *      if ListByFieldAddress is 0, Adress is the address of first element of Type List.
- *
- *   Lists by LIST_ENTRY are also handled implicitly (by Ioctl). If the NextPointer
- *   is a pointer to LIST_ENTRY type, the type address is properly calculated by
- *   subtracting the offsets.
- *
- *      If ListByFieldAddress is 1, the Address is considered to be the address of field
- *   "NextPointer" of the first Type element and first element address is derived
- *   from it.
- *
- */
-
-__inline
-ULONG
-ListType (
-    IN LPCSTR  Type,
-    IN ULONG64 Address,
-    IN USHORT  ListByFieldAddress,
-    IN LPCSTR  NextPointer,
-    IN PVOID   Context,
-    IN PSYM_DUMP_FIELD_CALLBACK CallbackRoutine
-    )
-{
-#ifndef FEATURE_PAL
-    FIELD_INFO flds = {(PUCHAR)NextPointer, NULL, 0, 0, 0, NULL};
-    SYM_DUMP_PARAM Sym = {
-       sizeof (SYM_DUMP_PARAM), (PUCHAR) Type, DBG_DUMP_NO_PRINT | DBG_DUMP_LIST, Address,
-       &flds, Context, CallbackRoutine, 0, NULL
-    };
-
-    if (ListByFieldAddress==1) {
-        //
-        // Address is the address of "NextPointer"
-        //
-        Sym.Options |= DBG_DUMP_ADDRESS_OF_FIELD;
-    }
-
-    return Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
-#else
-    return (ULONG)~0;
-#endif
-}
-
-
-/**
-
-   Routine to get offset of a "Field" of "Type" on a debugee machine. This uses
-   Ioctl call for type info.
-   Returns 0 on success, Ioctl error value otherwise.
-
- **/
-
-__inline
-ULONG
-GetFieldOffset (
-   IN LPCSTR     Type,
-   IN LPCSTR     Field,
-   OUT PULONG   pOffset
-   )
-{
-#ifndef FEATURE_PAL
-   FIELD_INFO flds = {
-       (PUCHAR)Field,
-       (PUCHAR)"",
-       0,
-       DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_RETURN_ADDRESS,
-       0,
-       NULL};
-
-   SYM_DUMP_PARAM Sym = {
-      sizeof (SYM_DUMP_PARAM),
-      (PUCHAR)Type,
-      DBG_DUMP_NO_PRINT,
-      0,
-      NULL,
-      NULL,
-      NULL,
-      1,
-      &flds
-   };
-
-   ULONG Err;
-
-   Sym.nFields = 1;
-   Err = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
-   *pOffset = (ULONG) (flds.address - Sym.addr);
-   return Err;
-#else
-   return (ULONG)~0;
-#endif
-}
-
-
-#endif // defined(KDEXT_64BIT)
-
-__inline VOID
- GetCurrentProcessHandle(
-    PHANDLE hp
-    )
-{
-    Ioctl(IG_GET_CURRENT_PROCESS_HANDLE, hp, sizeof(HANDLE));
-}
-
-__inline VOID
- GetTebAddress(
-    PULONGLONG Address
-    )
-{
-    GET_TEB_ADDRESS gpt;
-    gpt.Address = 0;
-    Ioctl(IG_GET_TEB_ADDRESS, (PVOID)&gpt, sizeof(gpt));
-    *Address = gpt.Address;
-}
-
-__inline VOID
- GetPebAddress(
-    ULONG64 CurrentThread,
-    PULONGLONG Address
-    )
-{
-    GET_PEB_ADDRESS gpt;
-    gpt.CurrentThread = CurrentThread;
-    gpt.Address = 0;
-    Ioctl(IG_GET_PEB_ADDRESS, (PVOID)&gpt, sizeof(gpt));
-    *Address = gpt.Address;
-}
-
-__inline VOID
- GetCurrentThreadAddr(
-    DWORD    Processor,
-    PULONG64  Address
-    )
-{
-    GET_CURRENT_THREAD_ADDRESS ct;
-    ct.Processor = Processor;
-    Ioctl(IG_GET_CURRENT_THREAD, (PVOID)&ct, sizeof(ct));
-    *Address = ct.Address;
-}
-
-__inline VOID
- GetCurrentProcessAddr(
-    DWORD    Processor,
-    ULONG64  CurrentThread,
-    PULONG64 Address
-    )
-{
-    GET_CURRENT_PROCESS_ADDRESS cp;
-    cp.Processor = Processor;
-    cp.CurrentThread = CurrentThread;
-    Ioctl(IG_GET_CURRENT_PROCESS, (PVOID)&cp, sizeof(cp));
-    *Address = cp.Address;
-}
-
-__inline VOID
-SearchMemory(
-    ULONG64  SearchAddress,
-    ULONG64  SearchLength,
-    ULONG    PatternLength,
-    PVOID    Pattern,
-    PULONG64 FoundAddress
-    )
-{
-    SEARCHMEMORY sm;
-    sm.SearchAddress = SearchAddress;
-    sm.SearchLength  = SearchLength;
-    sm.FoundAddress  = 0;
-    sm.PatternLength = PatternLength;
-    sm.Pattern       = Pattern;
-    Ioctl(IG_SEARCH_MEMORY, (PVOID)&sm, sizeof(sm));
-    *FoundAddress = sm.FoundAddress;
-}
-
-__inline ULONG
-GetInputLine(
-    PCSTR Prompt,
-    PSTR Buffer,
-    ULONG BufferSize
-    )
-{
-    GET_INPUT_LINE InLine;
-    InLine.Prompt = Prompt;
-    InLine.Buffer = Buffer;
-    InLine.BufferSize = BufferSize;
-    if (Ioctl(IG_GET_INPUT_LINE, (PVOID)&InLine, sizeof(InLine)))
-    {
-        return InLine.InputSize;
-    }
-    else
-    {
-        return 0;
-    }
-}
-
-__inline BOOL
-GetExpressionEx(
-    PCSTR Expression,
-    ULONG64* Value,
-    PCSTR* Remainder
-    )
-{
-    GET_EXPRESSION_EX Expr;
-    Expr.Expression = Expression;
-    if (Ioctl(IG_GET_EXPRESSION_EX, (PVOID)&Expr, sizeof(Expr)))
-    {
-        *Value = Expr.Value;
-
-        if (Remainder != NULL)
-        {
-            *Remainder = Expr.Remainder;
-        }
-
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-__inline BOOL
-TranslateVirtualToPhysical(
-    ULONG64 Virtual,
-    ULONG64* Physical
-    )
-{
-    TRANSLATE_VIRTUAL_TO_PHYSICAL VToP;
-    VToP.Virtual = Virtual;
-    if (Ioctl(IG_TRANSLATE_VIRTUAL_TO_PHYSICAL, (PVOID)&VToP, sizeof(VToP)))
-    {
-        *Physical = VToP.Physical;
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-__inline BOOL
-GetDebuggerCacheSize(
-    OUT PULONG64 CacheSize
-    )
-{
-    return Ioctl(IG_GET_CACHE_SIZE, (PVOID) CacheSize, sizeof(ULONG64));
-}
-
-__inline BOOL
-ExtMatchPatternA(
-    IN PCSTR Str,
-    IN PCSTR Pattern,
-    IN BOOL CaseSensitive
-    )
-{
-    EXT_MATCH_PATTERN_A Args;
-
-    Args.Str = Str;
-    Args.Pattern = Pattern;
-    Args.CaseSensitive = CaseSensitive;
-    return Ioctl(IG_MATCH_PATTERN_A, (PVOID)&Args, sizeof(Args));
-}
-
-#endif // FEATURE_PAL
-
-#endif
-
-#ifndef FEATURE_PAL
-#pragma warning(default:4115 4201 4204 4214 4221)
-#endif
-#if _MSC_VER >= 1200
-#pragma warning(pop)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _WDBGEXTS_
diff --git a/src/SOS/Strike/platform/cordebugdatatarget.h b/src/SOS/Strike/platform/cordebugdatatarget.h
new file mode 100644 (file)
index 0000000..27a7b0e
--- /dev/null
@@ -0,0 +1,259 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifndef __cordebugdatatarget_h__
+#define __cordebugdatatarget_h__
+
+/**********************************************************************\
+* Data target for the debugged process. Provided to OpenVirtualProcess 
+* in order to get an ICorDebugProcess back.
+\**********************************************************************/
+class CorDebugDataTarget : public ICorDebugMutableDataTarget, public ICorDebugMetaDataLocator, public ICorDebugDataTarget4
+{
+public:
+    CorDebugDataTarget() : m_ref(0)
+    {
+    }
+
+    virtual ~CorDebugDataTarget() {}
+
+    virtual HRESULT STDMETHODCALLTYPE QueryInterface(
+        REFIID InterfaceId,
+        PVOID* pInterface)
+    {
+        if (InterfaceId == IID_IUnknown)
+        {
+            *pInterface = static_cast<IUnknown *>(static_cast<ICorDebugDataTarget *>(this));
+        }
+        else if (InterfaceId == IID_ICorDebugDataTarget)
+        {
+            *pInterface = static_cast<ICorDebugDataTarget *>(this);
+        }
+        else if (InterfaceId == IID_ICorDebugMutableDataTarget)
+        {
+            *pInterface = static_cast<ICorDebugMutableDataTarget *>(this);
+        }
+        else if (InterfaceId == IID_ICorDebugMetaDataLocator)
+        {
+            *pInterface = static_cast<ICorDebugMetaDataLocator *>(this);
+        }
+        else if (InterfaceId == IID_ICorDebugDataTarget4)
+        {
+            *pInterface = static_cast<ICorDebugDataTarget4 *>(this);
+        }
+        else
+        {
+            *pInterface = NULL;
+            return E_NOINTERFACE;
+        }
+
+        AddRef();
+        return S_OK;
+    }
+    
+    virtual ULONG STDMETHODCALLTYPE AddRef()
+    {
+        return InterlockedIncrement(&m_ref);    
+    }
+
+    virtual ULONG STDMETHODCALLTYPE Release()
+    {
+        LONG ref = InterlockedDecrement(&m_ref);
+        if (ref == 0)
+        {
+            delete this;
+        }
+        return ref;
+    }
+
+    //
+    // ICorDebugDataTarget.
+    //
+
+    virtual HRESULT STDMETHODCALLTYPE GetPlatform(CorDebugPlatform * pPlatform)
+    {
+        ULONG platformKind = g_targetMachine->GetPlatform();
+        if (IsWindowsTarget())
+        {
+            if (platformKind == IMAGE_FILE_MACHINE_I386)
+                *pPlatform = CORDB_PLATFORM_WINDOWS_X86;
+            else if (platformKind == IMAGE_FILE_MACHINE_AMD64)
+                *pPlatform = CORDB_PLATFORM_WINDOWS_AMD64;
+            else if (platformKind == IMAGE_FILE_MACHINE_ARMNT)
+                *pPlatform = CORDB_PLATFORM_WINDOWS_ARM;
+            else if (platformKind == IMAGE_FILE_MACHINE_ARM64)
+                *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64;
+            else
+                return E_FAIL;
+        }
+        else
+        {
+            if (platformKind == IMAGE_FILE_MACHINE_I386)
+                *pPlatform = CORDB_PLATFORM_POSIX_X86;
+            else if (platformKind == IMAGE_FILE_MACHINE_AMD64)
+                *pPlatform = CORDB_PLATFORM_POSIX_AMD64;
+            else if (platformKind == IMAGE_FILE_MACHINE_ARMNT)
+                *pPlatform = CORDB_PLATFORM_POSIX_ARM;
+            else if (platformKind == IMAGE_FILE_MACHINE_ARM64)
+                *pPlatform = CORDB_PLATFORM_POSIX_ARM64;
+            else
+                return E_FAIL;
+        }
+    
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE ReadVirtual( 
+        CORDB_ADDRESS address,
+        BYTE * pBuffer,
+        ULONG32 request,
+        ULONG32 * pcbRead)
+    {
+        if (g_ExtData == NULL)
+        {
+            return E_UNEXPECTED;
+        }
+#ifdef FEATURE_PAL
+        if (g_sos != nullptr)
+        {
+            // LLDB synthesizes memory (returns 0's) for missing pages (in this case the missing metadata  pages) 
+            // in core dumps. This functions creates a list of the metadata regions and caches the metadata if 
+            // available from the local or downloaded assembly. If the read would be in the metadata of a loaded 
+            // assembly, the metadata from the this cache will be returned.
+            HRESULT hr = GetMetadataMemory(address, request, pBuffer);
+            if (SUCCEEDED(hr)) {
+                if (pcbRead != nullptr) {
+                    *pcbRead = request;
+                }
+                return hr;
+            }
+        }
+#endif
+        HRESULT hr = g_ExtData->ReadVirtual(address, pBuffer, request, (PULONG) pcbRead);
+        if (FAILED(hr)) 
+        {
+            ExtDbgOut("CorDebugDataTarget::ReadVirtual FAILED %08x address %p size %08x\n", hr, address, request);
+        }
+        return hr;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetThreadContext(
+        DWORD dwThreadOSID,
+        ULONG32 contextFlags,
+        ULONG32 contextSize,
+        BYTE * context)
+    {
+        HRESULT hr;
+#ifdef FEATURE_PAL
+        if (g_ExtServices == NULL)
+        {
+            return E_UNEXPECTED;
+        }
+        hr = g_ExtServices->GetThreadContextBySystemId(dwThreadOSID, contextFlags, contextSize, context);
+#else
+        ULONG ulThreadIDOrig;
+        ULONG ulThreadIDRequested;
+
+        hr = g_ExtSystem->GetCurrentThreadId(&ulThreadIDOrig);
+        if (FAILED(hr))
+        {
+            return hr;
+        }
+
+        hr = g_ExtSystem->GetThreadIdBySystemId(dwThreadOSID, &ulThreadIDRequested);
+        if (FAILED(hr))
+        {
+            return hr;
+        }
+
+        hr = g_ExtSystem->SetCurrentThreadId(ulThreadIDRequested);
+        if (FAILED(hr))
+        {
+            return hr;
+        }
+
+        // Prepare context structure
+        ZeroMemory(context, contextSize);
+        g_targetMachine->SetContextFlags(context, contextFlags);
+
+        // Ok, do it!
+        hr = g_ExtAdvanced->GetThreadContext((LPVOID) context, contextSize);
+
+        // This is cleanup; failure here doesn't mean GetThreadContext should fail
+        // (that's determined by hr).
+        g_ExtSystem->SetCurrentThreadId(ulThreadIDOrig);
+#endif // FEATURE_PAL
+
+        // GetThreadContext clears ContextFlags or sets them incorrectly and DBI needs it set to know what registers to copy
+        g_targetMachine->SetContextFlags(context, contextFlags);
+
+        return hr;
+    }
+
+    //
+    // ICorDebugMutableDataTarget.
+    //
+
+    virtual HRESULT STDMETHODCALLTYPE WriteVirtual(CORDB_ADDRESS address,
+                                                   const BYTE * pBuffer,
+                                                   ULONG32 bytesRequested)
+    {
+        if (g_ExtData == NULL)
+        {
+            return E_UNEXPECTED;
+        }
+        return g_ExtData->WriteVirtual(address, (PVOID)pBuffer, bytesRequested, NULL);
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE SetThreadContext(DWORD dwThreadID,
+                                                       ULONG32 contextSize,
+                                                       const BYTE * pContext)
+    {
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE ContinueStatusChanged(DWORD dwThreadId,
+                                                            CORDB_CONTINUE_STATUS continueStatus)
+    {
+        return E_NOTIMPL;
+    }
+
+    //
+    // ICorDebugMetaDataLocator.
+    //
+
+    virtual HRESULT STDMETHODCALLTYPE GetMetaData(
+        /* [in] */ LPCWSTR wszImagePath,
+        /* [in] */ DWORD dwImageTimeStamp,
+        /* [in] */ DWORD dwImageSize,
+        /* [in] */ ULONG32 cchPathBuffer,
+        /* [annotation][out] */ 
+        _Out_ ULONG32 *pcchPathBuffer,
+        /* [annotation][length_is][size_is][out] */ 
+        _Out_writes_to_(cchPathBuffer, *pcchPathBuffer) WCHAR wszPathBuffer[])
+    {
+        return ::GetICorDebugMetadataLocator(wszImagePath, dwImageTimeStamp, dwImageSize, cchPathBuffer, pcchPathBuffer, wszPathBuffer);
+    }
+
+    //
+    // ICorDebugDataTarget4
+    //
+    virtual HRESULT STDMETHODCALLTYPE VirtualUnwind(DWORD threadId, ULONG32 contextSize, PBYTE context)
+    {
+#ifdef FEATURE_PAL
+        if (g_ExtServices == NULL)
+        {
+            return E_UNEXPECTED;
+        }
+        return g_ExtServices->VirtualUnwind(threadId, contextSize, context);
+#else 
+        return E_NOTIMPL;
+#endif
+    }
+
+protected:
+    LONG m_ref;
+};
+
+#endif // __cordebugdatatarget_h__
diff --git a/src/SOS/Strike/platform/cordebuglibraryprovider.h b/src/SOS/Strike/platform/cordebuglibraryprovider.h
new file mode 100644 (file)
index 0000000..f5eac41
--- /dev/null
@@ -0,0 +1,170 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifndef __cordebuglibraryprovider_h__
+#define __cordebuglibraryprovider_h__
+
+#ifndef FEATURE_PAL
+extern HMODULE LoadLibraryAndCheck(PCWSTR filename, DWORD timestamp, DWORD filesize);
+#endif
+
+/**********************************************************************\
+ * Provides a way for the public CLR debugging interface to find the 
+ * appropriate mscordbi.dll, DAC, etc.
+\**********************************************************************/
+class CorDebugLibraryProvider : public ICLRDebuggingLibraryProvider, ICLRDebuggingLibraryProvider2
+{
+public:
+    CorDebugLibraryProvider(Runtime* pRuntime) :
+        m_ref(0),
+        m_pRuntime(pRuntime)
+    {
+    }
+
+    virtual ~CorDebugLibraryProvider() {}
+
+    virtual HRESULT STDMETHODCALLTYPE QueryInterface(
+        REFIID InterfaceId,
+        PVOID* pInterface)
+    {
+        if (InterfaceId == IID_IUnknown)
+        {
+            *pInterface = static_cast<IUnknown *>(static_cast<ICLRDebuggingLibraryProvider*>(this));
+        }
+#ifndef FEATURE_PAL
+        else if (InterfaceId == IID_ICLRDebuggingLibraryProvider)
+        {
+            *pInterface = static_cast<ICLRDebuggingLibraryProvider *>(this);
+        }
+#endif
+        else if (InterfaceId == IID_ICLRDebuggingLibraryProvider2)
+        {
+            *pInterface = static_cast<ICLRDebuggingLibraryProvider2 *>(this);
+        }
+        else
+        {
+            *pInterface = NULL;
+            return E_NOINTERFACE;
+        }
+
+        AddRef();
+        return S_OK;
+    }
+    
+    virtual ULONG STDMETHODCALLTYPE AddRef()
+    {
+        return InterlockedIncrement(&m_ref);    
+    }
+
+    virtual ULONG STDMETHODCALLTYPE Release()
+    {
+        LONG ref = InterlockedDecrement(&m_ref);
+        if (ref == 0)
+        {
+            delete this;
+        }
+        return ref;
+    }
+
+    HRESULT ProvideLibraryInternal(
+        const WCHAR* pwszFileName,
+        DWORD dwTimestamp,
+        DWORD dwSizeOfImage,
+        HMODULE* phModule,
+        LPWSTR* ppResolvedModulePath)
+    {
+        const char* filePath = nullptr;
+
+        if (_wcsncmp(pwszFileName, m_pRuntime->GetDacDllNameW(), _wcslen(m_pRuntime->GetDacDllNameW())) == 0)
+        {
+            filePath = m_pRuntime->GetDacFilePath();
+        }
+        else if (_wcsncmp(pwszFileName, NET_DBI_DLL_NAME_W, _wcslen(NET_DBI_DLL_NAME_W)) == 0)
+        {
+            filePath = m_pRuntime->GetDbiFilePath();
+        }
+
+        ArrayHolder<WCHAR> modulePath = new WCHAR[MAX_LONGPATH + 1];
+        if (filePath != nullptr)
+        {
+            int length = MultiByteToWideChar(CP_ACP, 0, filePath, -1, modulePath, MAX_LONGPATH);
+            if (0 >= length)
+            {
+                ExtErr("MultiByteToWideChar(filePath) failed. Last error = 0x%x\n", GetLastError());
+                return HRESULT_FROM_WIN32(GetLastError());
+            }
+        }
+        else
+        {
+            LPCSTR runtimeDirectory = m_pRuntime->GetRuntimeDirectory();
+            if (runtimeDirectory == nullptr)
+            {
+                ExtErr("Runtime not loaded\n");
+                return E_FAIL;
+            }
+            int length = MultiByteToWideChar(CP_ACP, 0, runtimeDirectory, -1, modulePath, MAX_LONGPATH);
+            if (0 >= length)
+            {
+                ExtErr("MultiByteToWideChar(runtimeDirectory) failed. Last error = 0x%x\n", GetLastError());
+                return HRESULT_FROM_WIN32(GetLastError());
+            }
+            wcscat_s(modulePath, MAX_LONGPATH, pwszFileName);
+        }
+
+        ExtOut("Loaded %S\n", modulePath.GetPtr());
+
+#ifndef FEATURE_PAL
+        if (phModule != NULL)
+        {
+            *phModule = LoadLibraryAndCheck(modulePath.GetPtr(), dwTimestamp, dwSizeOfImage);
+        }
+#endif
+        if (ppResolvedModulePath != NULL)
+        {
+            *ppResolvedModulePath = modulePath.Detach();
+        }
+        return S_OK;
+    }
+
+    // Called by the shim to locate and load dac and dbi
+    // Parameters:
+    //    pwszFileName - the name of the file to load
+    //    dwTimestamp - the expected timestamp of the file
+    //    dwSizeOfImage - the expected SizeOfImage (a PE header data value)
+    //    phModule - a handle to loaded module
+    //
+    // Return Value
+    //    S_OK if the file was loaded, or any error if not
+    virtual HRESULT STDMETHODCALLTYPE ProvideLibrary(
+        const WCHAR * pwszFileName,
+        DWORD dwTimestamp,
+        DWORD dwSizeOfImage,
+        HMODULE* phModule)
+    {
+        if ((phModule == NULL) || (pwszFileName == NULL))
+        {
+            return E_INVALIDARG;
+        }
+        return ProvideLibraryInternal(pwszFileName, dwTimestamp, dwSizeOfImage, phModule, NULL);
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE ProvideLibrary2(
+        const WCHAR* pwszFileName,
+        DWORD dwTimestamp,
+        DWORD dwSizeOfImage,
+        LPWSTR* ppResolvedModulePath)
+    {
+        if ((pwszFileName == NULL) || (ppResolvedModulePath == NULL))
+        {
+            return E_INVALIDARG;
+        }
+        return ProvideLibraryInternal(pwszFileName, dwTimestamp, dwSizeOfImage, NULL, ppResolvedModulePath);
+    }
+
+protected:
+    LONG m_ref;
+    Runtime* m_pRuntime;
+};
+
+#endif // __cordebuglibraryprovider_h__
diff --git a/src/SOS/Strike/platform/datatarget.cpp b/src/SOS/Strike/platform/datatarget.cpp
new file mode 100644 (file)
index 0000000..7e21a89
--- /dev/null
@@ -0,0 +1,388 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "sos.h"
+#include "datatarget.h"
+#include "corhdr.h"
+#include "cor.h"
+#include "dacprivate.h"
+#include "sospriv.h"
+#include "corerror.h"
+
+#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
+
+DataTarget::DataTarget(ULONG64 baseAddress) :
+    m_ref(0),
+    m_baseAddress(baseAddress)
+{
+}
+
+STDMETHODIMP
+DataTarget::QueryInterface(
+    THIS_
+    ___in REFIID InterfaceId,
+    ___out PVOID* Interface
+    )
+{
+    if (InterfaceId == IID_IUnknown ||
+        InterfaceId == IID_ICLRDataTarget)
+    {
+        *Interface = (ICLRDataTarget*)this;
+        AddRef();
+        return S_OK;
+    }
+    else if (InterfaceId == IID_ICLRDataTarget2)
+    {
+        *Interface = (ICLRDataTarget2*)this;
+        AddRef();
+        return S_OK;
+    }
+    else if (InterfaceId == IID_ICorDebugDataTarget4)
+    {
+        *Interface = (ICorDebugDataTarget4*)this;
+        AddRef();
+        return S_OK;
+    }
+    else if (InterfaceId == IID_ICLRMetadataLocator)
+    {
+        *Interface = (ICLRMetadataLocator*)this;
+        AddRef();
+        return S_OK;
+    }
+    else if (InterfaceId == IID_ICLRRuntimeLocator)
+    {
+        *Interface = (ICLRRuntimeLocator*)this;
+        AddRef();
+        return S_OK;
+    }
+    else
+    {
+        *Interface = NULL;
+        return E_NOINTERFACE;
+    }
+}
+
+STDMETHODIMP_(ULONG)
+DataTarget::AddRef(
+    THIS
+    )
+{
+    LONG ref = InterlockedIncrement(&m_ref);    
+    return ref;
+}
+
+STDMETHODIMP_(ULONG)
+DataTarget::Release(
+    THIS
+    )
+{
+    LONG ref = InterlockedDecrement(&m_ref);
+    if (ref == 0)
+    {
+        delete this;
+    }
+    return ref;
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::GetMachineType(
+    /* [out] */ ULONG32 *machine)
+{
+    if (g_ExtControl == NULL)
+    {
+        return E_UNEXPECTED;
+    }
+    return g_ExtControl->GetExecutingProcessorType((PULONG)machine);
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::GetPointerSize(
+    /* [out] */ ULONG32 *size)
+{
+#if defined(SOS_TARGET_AMD64) || defined(SOS_TARGET_ARM64) || defined(SOS_TARGET_MIPS64)
+    *size = 8;
+#elif defined(SOS_TARGET_ARM) || defined(SOS_TARGET_X86)
+    *size = 4;
+#else
+  #error Unsupported architecture
+#endif
+
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::GetImageBase(
+    /* [string][in] */ LPCWSTR name,
+    /* [out] */ CLRDATA_ADDRESS *base)
+{
+    if (g_ExtSymbols == NULL)
+    {
+        return E_UNEXPECTED;
+    }
+    CHAR lpstr[MAX_LONGPATH];
+    int name_length = WideCharToMultiByte(CP_ACP, 0, name, -1, lpstr, MAX_LONGPATH, NULL, NULL);
+    if (name_length == 0)
+    {
+        return E_FAIL;
+    }
+#ifndef FEATURE_PAL
+    // Remove the extension on Windows/dbgeng.
+    CHAR *lp = strrchr(lpstr, '.');
+    if (lp != nullptr)
+    {
+        *lp = '\0';
+    }
+#endif
+    return g_ExtSymbols->GetModuleByModuleName(lpstr, 0, NULL, base);
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::ReadVirtual(
+    /* [in] */ CLRDATA_ADDRESS address,
+    /* [length_is][size_is][out] */ PBYTE buffer,
+    /* [in] */ ULONG32 request,
+    /* [optional][out] */ ULONG32 *done)
+{
+    if (g_ExtData == NULL)
+    {
+        return E_UNEXPECTED;
+    }
+#ifdef FEATURE_PAL
+    if (g_sos != nullptr)
+    {
+        // LLDB synthesizes memory (returns 0's) for missing pages (in this case the missing metadata  pages) 
+        // in core dumps. This functions creates a list of the metadata regions and caches the metadata if 
+        // available from the local or downloaded assembly. If the read would be in the metadata of a loaded 
+        // assembly, the metadata from the this cache will be returned.
+        HRESULT hr = GetMetadataMemory(address, request, buffer);
+        if (SUCCEEDED(hr)) {
+            if (done != nullptr) {
+                *done = request;
+            }
+            return hr;
+        }
+    }
+#endif
+    HRESULT hr = g_ExtData->ReadVirtual(address, (PVOID)buffer, request, (PULONG)done);
+    if (FAILED(hr)) 
+    {
+        ExtDbgOut("DataTarget::ReadVirtual FAILED %08x address %08llx size %08x\n", hr, address, request);
+    }
+    return hr;
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::WriteVirtual(
+    /* [in] */ CLRDATA_ADDRESS address,
+    /* [size_is][in] */ PBYTE buffer,
+    /* [in] */ ULONG32 request,
+    /* [optional][out] */ ULONG32 *done)
+{
+    if (g_ExtData == NULL)
+    {
+        return E_UNEXPECTED;
+    }
+    return g_ExtData->WriteVirtual(address, (PVOID)buffer, request, (PULONG)done);
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::GetTLSValue(
+    /* [in] */ ULONG32 threadID,
+    /* [in] */ ULONG32 index,
+    /* [out] */ CLRDATA_ADDRESS* value)
+{
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::SetTLSValue(
+    /* [in] */ ULONG32 threadID,
+    /* [in] */ ULONG32 index,
+    /* [in] */ CLRDATA_ADDRESS value)
+{
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::GetCurrentThreadID(
+    /* [out] */ ULONG32 *threadID)
+{
+    if (g_ExtSystem == NULL)
+    {
+        return E_UNEXPECTED;
+    }
+    return g_ExtSystem->GetCurrentThreadSystemId((PULONG)threadID);
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::GetThreadContext(
+    /* [in] */ ULONG32 threadID,
+    /* [in] */ ULONG32 contextFlags,
+    /* [in] */ ULONG32 contextSize,
+    /* [out, size_is(contextSize)] */ PBYTE context)
+{
+    HRESULT hr;
+#ifdef FEATURE_PAL
+    if (g_ExtServices == NULL)
+    {
+        return E_UNEXPECTED;
+    }
+    hr = g_ExtServices->GetThreadContextBySystemId(threadID, contextFlags, contextSize, context);
+#else
+    if (g_ExtSystem == NULL || g_ExtAdvanced == NULL)
+    {
+        return E_UNEXPECTED;
+    }
+    ULONG ulThreadIDOrig;
+    ULONG ulThreadIDRequested;
+
+    hr = g_ExtSystem->GetCurrentThreadId(&ulThreadIDOrig);
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+
+    hr = g_ExtSystem->GetThreadIdBySystemId(threadID, &ulThreadIDRequested);
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+
+    hr = g_ExtSystem->SetCurrentThreadId(ulThreadIDRequested);
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+
+    // Prepare context structure
+    ZeroMemory(context, contextSize);
+    g_targetMachine->SetContextFlags(context, contextFlags);
+
+    // Ok, do it!
+    hr = g_ExtAdvanced->GetThreadContext((LPVOID) context, contextSize);
+
+    // This is cleanup; failure here doesn't mean GetThreadContext should fail
+    // (that's determined by hr).
+    g_ExtSystem->SetCurrentThreadId(ulThreadIDOrig);
+#endif
+
+    // GetThreadContext clears ContextFlags or sets them incorrectly and DBI needs it set to know what registers to copy
+    g_targetMachine->SetContextFlags(context, contextFlags);
+
+    return hr;
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::SetThreadContext(
+    /* [in] */ ULONG32 threadID,
+    /* [in] */ ULONG32 contextSize,
+    /* [out, size_is(contextSize)] */ PBYTE context)
+{
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::Request(
+    /* [in] */ ULONG32 reqCode,
+    /* [in] */ ULONG32 inBufferSize,
+    /* [size_is][in] */ BYTE *inBuffer,
+    /* [in] */ ULONG32 outBufferSize,
+    /* [size_is][out] */ BYTE *outBuffer)
+{
+    return E_NOTIMPL;
+}
+
+// ICLRDataTarget2
+
+HRESULT STDMETHODCALLTYPE 
+DataTarget::AllocVirtual(
+    /* [in] */ CLRDATA_ADDRESS addr,
+    /* [in] */ ULONG32 size,
+    /* [in] */ ULONG32 typeFlags,
+    /* [in] */ ULONG32 protectFlags,
+    /* [out] */ CLRDATA_ADDRESS* virt)
+{
+#ifdef FEATURE_PAL
+    return E_NOTIMPL;
+#else
+    ULONG64 hProcess;
+    HRESULT hr = g_ExtSystem->GetCurrentProcessHandle(&hProcess);
+    if (FAILED(hr)) {
+        return hr;
+    }
+    LPVOID allocation = ::VirtualAllocEx((HANDLE)hProcess, (LPVOID)addr, size, typeFlags, protectFlags);
+    if (allocation == NULL) {
+        return HRESULT_FROM_WIN32(::GetLastError());
+    }
+    *virt = (CLRDATA_ADDRESS)allocation;
+    return S_OK;
+#endif
+}
+        
+HRESULT STDMETHODCALLTYPE 
+DataTarget::FreeVirtual(
+    /* [in] */ CLRDATA_ADDRESS addr,
+    /* [in] */ ULONG32 size,
+    /* [in] */ ULONG32 typeFlags)
+{
+#ifdef FEATURE_PAL
+    return E_NOTIMPL;
+#else
+    ULONG64 hProcess;
+    HRESULT hr = g_ExtSystem->GetCurrentProcessHandle(&hProcess);
+    if (FAILED(hr)) {
+        return hr;
+    }
+    ::VirtualFreeEx((HANDLE)hProcess, (LPVOID)addr, size, typeFlags);
+    return S_OK;
+#endif
+}
+
+// ICorDebugDataTarget4
+
+HRESULT STDMETHODCALLTYPE 
+DataTarget::VirtualUnwind(
+    /* [in] */ DWORD threadId,
+    /* [in] */ ULONG32 contextSize,
+    /* [in, out, size_is(contextSize)] */ PBYTE context)
+{
+#ifdef FEATURE_PAL
+    if (g_ExtServices == NULL)
+    {
+        return E_UNEXPECTED;
+    }
+    return g_ExtServices->VirtualUnwind(threadId, contextSize, context);
+#else
+    return E_NOTIMPL;
+#endif
+}
+
+// ICLRMetadataLocator
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::GetMetadata(
+    /* [in] */ LPCWSTR imagePath,
+    /* [in] */ ULONG32 imageTimestamp,
+    /* [in] */ ULONG32 imageSize,
+    /* [in] */ GUID* mvid,
+    /* [in] */ ULONG32 mdRva,
+    /* [in] */ ULONG32 flags,
+    /* [in] */ ULONG32 bufferSize,
+    /* [out, size_is(bufferSize), length_is(*dataSize)] */
+    BYTE* buffer,
+    /* [out] */ ULONG32* dataSize)
+{
+    return ::GetMetadataLocator(imagePath, imageTimestamp, imageSize, mvid, mdRva, flags, bufferSize, buffer, dataSize);
+}
+
+// ICLRRuntimeLocator
+
+HRESULT STDMETHODCALLTYPE 
+DataTarget::GetRuntimeBase(
+    /* [out] */ CLRDATA_ADDRESS* baseAddress)
+{
+    *baseAddress = m_baseAddress;
+    return S_OK;
+}
+
diff --git a/src/SOS/Strike/platform/datatarget.h b/src/SOS/Strike/platform/datatarget.h
new file mode 100644 (file)
index 0000000..69ffb94
--- /dev/null
@@ -0,0 +1,124 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+class DataTarget : public ICLRDataTarget2, ICorDebugDataTarget4, ICLRMetadataLocator, ICLRRuntimeLocator
+{
+private:
+    LONG m_ref;                         // Reference count.
+    ULONG64 m_baseAddress;              // Runtime base address
+
+public:
+    DataTarget(ULONG64 baseAddress);
+    virtual ~DataTarget() {}
+    
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        ___in REFIID InterfaceId,
+        ___out PVOID* Interface
+        );
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        );
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        );
+
+    //
+    // ICLRDataTarget.
+    //
+    
+    virtual HRESULT STDMETHODCALLTYPE GetMachineType( 
+        /* [out] */ ULONG32 *machine);
+
+    virtual HRESULT STDMETHODCALLTYPE GetPointerSize( 
+        /* [out] */ ULONG32 *size);
+
+    virtual HRESULT STDMETHODCALLTYPE GetImageBase( 
+        /* [string][in] */ LPCWSTR name,
+        /* [out] */ CLRDATA_ADDRESS *base);
+
+    virtual HRESULT STDMETHODCALLTYPE ReadVirtual( 
+        /* [in] */ CLRDATA_ADDRESS address,
+        /* [length_is][size_is][out] */ PBYTE buffer,
+        /* [in] */ ULONG32 request,
+        /* [optional][out] */ ULONG32 *done);
+
+    virtual HRESULT STDMETHODCALLTYPE WriteVirtual( 
+        /* [in] */ CLRDATA_ADDRESS address,
+        /* [size_is][in] */ PBYTE buffer,
+        /* [in] */ ULONG32 request,
+        /* [optional][out] */ ULONG32 *done);
+
+    virtual HRESULT STDMETHODCALLTYPE GetTLSValue(
+        /* [in] */ ULONG32 threadID,
+        /* [in] */ ULONG32 index,
+        /* [out] */ CLRDATA_ADDRESS* value);
+
+    virtual HRESULT STDMETHODCALLTYPE SetTLSValue(
+        /* [in] */ ULONG32 threadID,
+        /* [in] */ ULONG32 index,
+        /* [in] */ CLRDATA_ADDRESS value);
+
+    virtual HRESULT STDMETHODCALLTYPE GetCurrentThreadID(
+        /* [out] */ ULONG32* threadID);
+
+    virtual HRESULT STDMETHODCALLTYPE GetThreadContext(
+        /* [in] */ ULONG32 threadID,
+        /* [in] */ ULONG32 contextFlags,
+        /* [in] */ ULONG32 contextSize,
+        /* [out, size_is(contextSize)] */ PBYTE context);
+
+    virtual HRESULT STDMETHODCALLTYPE SetThreadContext(
+        /* [in] */ ULONG32 threadID,
+        /* [in] */ ULONG32 contextSize,
+        /* [in, size_is(contextSize)] */ PBYTE context);
+
+    virtual HRESULT STDMETHODCALLTYPE Request( 
+        /* [in] */ ULONG32 reqCode,
+        /* [in] */ ULONG32 inBufferSize,
+        /* [size_is][in] */ BYTE *inBuffer,
+        /* [in] */ ULONG32 outBufferSize,
+        /* [size_is][out] */ BYTE *outBuffer);
+
+    // ICLRDataTarget2
+
+    virtual HRESULT STDMETHODCALLTYPE AllocVirtual( 
+            /* [in] */ CLRDATA_ADDRESS addr,
+            /* [in] */ ULONG32 size,
+            /* [in] */ ULONG32 typeFlags,
+            /* [in] */ ULONG32 protectFlags,
+            /* [out] */ CLRDATA_ADDRESS *virt);
+        
+    virtual HRESULT STDMETHODCALLTYPE FreeVirtual( 
+            /* [in] */ CLRDATA_ADDRESS addr,
+            /* [in] */ ULONG32 size,
+            /* [in] */ ULONG32 typeFlags);
+
+    // ICorDebugDataTarget4
+
+    virtual HRESULT STDMETHODCALLTYPE VirtualUnwind(
+        /* [in] */ DWORD threadId,
+        /* [in] */ ULONG32 contextSize,
+        /* [in, out, size_is(contextSize)] */ PBYTE context);
+
+    // ICLRMetadataLocator
+
+    virtual HRESULT STDMETHODCALLTYPE GetMetadata(
+        /* [in] */ LPCWSTR imagePath,
+        /* [in] */ ULONG32 imageTimestamp,
+        /* [in] */ ULONG32 imageSize,
+        /* [in] */ GUID* mvid,
+        /* [in] */ ULONG32 mdRva,
+        /* [in] */ ULONG32 flags,
+        /* [in] */ ULONG32 bufferSize,
+        /* [out, size_is(bufferSize), length_is(*dataSize)] */
+        BYTE* buffer,
+        /* [out] */ ULONG32* dataSize);
+
+    // ICLRRuntimeLocator
+
+    virtual HRESULT STDMETHODCALLTYPE GetRuntimeBase(
+        /* [out] */ CLRDATA_ADDRESS* baseAddress);
+};
\ No newline at end of file
diff --git a/src/SOS/Strike/platform/hostimpl.cpp b/src/SOS/Strike/platform/hostimpl.cpp
new file mode 100644 (file)
index 0000000..989f59d
--- /dev/null
@@ -0,0 +1,105 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "strike.h"
+#include "util.h"
+#include "targetimpl.h"
+#include "hostimpl.h"
+
+Host* Host::s_host = nullptr;
+
+//----------------------------------------------------------------------------
+// Host
+//----------------------------------------------------------------------------
+
+Host::Host() :
+    m_ref(1)
+{ 
+}
+
+Host::~Host()
+{
+    s_host = nullptr;
+}
+
+/// <summary>
+/// Creates a local service provider instance or returns the existing one 
+/// </summary>
+/// <returns></returns>
+IHost* Host::GetInstance()
+{
+    if (s_host == nullptr) 
+    {
+        s_host = new Host();
+    }
+    s_host->AddRef();
+    return s_host;
+}
+
+//----------------------------------------------------------------------------
+// IUnknown
+//----------------------------------------------------------------------------
+
+HRESULT Host::QueryInterface(
+    REFIID InterfaceId,
+    PVOID* Interface
+    )
+{
+    if (InterfaceId == __uuidof(IUnknown) ||
+        InterfaceId == __uuidof(IHost))
+    {
+        *Interface = (IHost*)this;
+        AddRef();
+        return S_OK;
+    }
+    else
+    {
+        *Interface = NULL;
+        return E_NOINTERFACE;
+    }
+}
+
+ULONG Host::AddRef()
+{
+    LONG ref = InterlockedIncrement(&m_ref);    
+    return ref;
+}
+
+ULONG Host::Release()
+{
+    LONG ref = InterlockedDecrement(&m_ref);
+    if (ref == 0)
+    {
+        delete this;
+    }
+    return ref;
+}
+
+//----------------------------------------------------------------------------
+// IHost
+//----------------------------------------------------------------------------
+
+IHost::HostType Host::GetHostType()
+{
+#ifdef FEATURE_PAL
+    return HostType::Lldb;
+#else
+    return HostType::DbgEng;
+#endif
+}
+
+HRESULT Host::GetService(REFIID serviceId, PVOID* ppService)
+{
+    return E_NOINTERFACE;
+}
+
+HRESULT Host::GetCurrentTarget(ITarget** ppTarget)
+{
+    if (ppTarget == nullptr)
+    {
+        return E_INVALIDARG;
+    }
+    *ppTarget = Target::GetInstance();
+    return S_OK;
+}
diff --git a/src/SOS/Strike/platform/hostimpl.h b/src/SOS/Strike/platform/hostimpl.h
new file mode 100644 (file)
index 0000000..eb62299
--- /dev/null
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#pragma once
+
+#include "host.h"
+
+//----------------------------------------------------------------------------
+// Local implementation of IHost
+//----------------------------------------------------------------------------
+class Host : public IHost
+{
+private:
+    LONG m_ref;
+
+    static Host* s_host;
+
+    Host();
+    virtual ~Host();
+
+public:
+    static IHost* GetInstance();
+
+    //----------------------------------------------------------------------------
+    // IUnknown
+    //----------------------------------------------------------------------------
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(
+        REFIID InterfaceId,
+        PVOID* Interface);
+
+    ULONG STDMETHODCALLTYPE AddRef();
+
+    ULONG STDMETHODCALLTYPE Release();
+
+    //----------------------------------------------------------------------------
+    // IHost
+    //----------------------------------------------------------------------------
+
+    IHost::HostType STDMETHODCALLTYPE GetHostType();
+
+    HRESULT STDMETHODCALLTYPE GetService(REFIID serviceId, PVOID* ppService);
+
+    HRESULT STDMETHODCALLTYPE GetCurrentTarget(ITarget** ppTarget);
+};
diff --git a/src/SOS/Strike/platform/runtimeimpl.cpp b/src/SOS/Strike/platform/runtimeimpl.cpp
new file mode 100644 (file)
index 0000000..926807b
--- /dev/null
@@ -0,0 +1,706 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "strike.h"
+#include "util.h"
+#include <string>
+#include <corhdr.h>
+#include <cor.h>
+#include <clrdata.h>
+#include <dbghelp.h>
+#include <cordebug.h>
+#include <xcordebug.h>
+#include <mscoree.h>
+#include <psapi.h>
+#include <clrinternal.h>
+#include <metahost.h>
+#include "debugshim.h"
+#include "runtimeimpl.h"
+#include "datatarget.h"
+#include "cordebugdatatarget.h"
+#include "cordebuglibraryprovider.h"
+#include "runtimeinfo.h"
+
+#ifdef FEATURE_PAL
+#include <sys/stat.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#endif // !FEATURE_PAL
+
+// Current runtime instance
+IRuntime* g_pRuntime = nullptr;
+
+#if !defined(__APPLE__)
+
+extern bool TryGetSymbol(uint64_t baseAddress, const char* symbolName, uint64_t* symbolAddress);
+
+bool ElfReaderReadMemory(void* address, void* buffer, size_t size)
+{
+    ULONG read = 0;
+    return SUCCEEDED(g_ExtData->ReadVirtual((ULONG64)address, buffer, (ULONG)size, &read));
+}
+
+/**********************************************************************\
+ * Search all the modules in the process for the single-file host
+\**********************************************************************/
+static HRESULT GetSingleFileInfo(PULONG pModuleIndex, PULONG64 pModuleAddress, RuntimeInfo** ppRuntimeInfo)
+{
+    _ASSERTE(pModuleIndex != nullptr);
+    _ASSERTE(pModuleAddress != nullptr);
+
+    ULONG loaded, unloaded;
+    HRESULT hr = g_ExtSymbols->GetNumberModules(&loaded, &unloaded);
+    if (FAILED(hr)) {
+        return hr;
+    }
+
+    for (ULONG index = 0; index < loaded; index++)
+    {
+        ULONG64 baseAddress;
+        hr = g_ExtSymbols->GetModuleByIndex(index, &baseAddress);
+        if (FAILED(hr)) {
+            return hr;
+        }
+        ULONG64 symbolAddress;
+        if (TryGetSymbol(baseAddress, "DotNetRuntimeInfo", &symbolAddress))
+        {
+            ULONG read = 0;
+            ArrayHolder<BYTE> buffer = new BYTE[sizeof(RuntimeInfo)];
+            hr = g_ExtData->ReadVirtual(symbolAddress, buffer, sizeof(RuntimeInfo), &read);
+            if (FAILED(hr)) {
+                return hr;
+            }
+            if (strcmp(((RuntimeInfo*)buffer.GetPtr())->Signature, "DotNetRuntimeInfo") != 0) {
+                break;
+            }
+            *pModuleIndex = index;
+            *pModuleAddress = baseAddress;
+            *ppRuntimeInfo = (RuntimeInfo*)buffer.Detach();
+            return S_OK;
+        }
+    }
+
+    return E_FAIL;
+}
+
+#endif // !defined(__APPLE__)
+
+/**********************************************************************\
+ * Creates a desktop or .NET Core instance of the runtime class
+\**********************************************************************/
+HRESULT Runtime::CreateInstance(ITarget* target, RuntimeConfiguration configuration, Runtime **ppRuntime)
+{
+    PCSTR runtimeModuleName = ::GetRuntimeModuleName(configuration);
+    ULONG moduleIndex = 0;
+    ULONG64 moduleAddress = 0;
+    ULONG64 moduleSize = 0;
+    RuntimeInfo* runtimeInfo = nullptr;
+    HRESULT hr = S_OK;
+
+    if (*ppRuntime == nullptr)
+    {
+        // Check if the normal runtime module (coreclr.dll, libcoreclr.so, etc.) is loaded
+        hr = g_ExtSymbols->GetModuleByModuleName(runtimeModuleName, 0, &moduleIndex, &moduleAddress);
+#if !defined(__APPLE__)
+        if (FAILED(hr))
+        {
+            // If the standard runtime module isn't loaded, try looking for a single-file program
+            if (configuration == IRuntime::UnixCore)
+            {
+                hr = GetSingleFileInfo(&moduleIndex, &moduleAddress, &runtimeInfo);
+            }
+        }
+#endif // !defined(__APPLE__)
+
+        // If the previous operations were successful, get the size of the runtime module
+        if (SUCCEEDED(hr))
+        {
+#ifdef FEATURE_PAL
+            hr = g_ExtServices2->GetModuleInfo(moduleIndex, nullptr, &moduleSize, nullptr, nullptr);
+#else
+            _ASSERTE(moduleAddress != 0);
+            DEBUG_MODULE_PARAMETERS params;
+            hr = g_ExtSymbols->GetModuleParameters(1, &moduleAddress, 0, &params);
+            if (SUCCEEDED(hr))
+            {
+                moduleSize = params.Size;
+            }
+#endif
+        }
+
+        // If the previous operations were successful, create the Runtime instance
+        if (SUCCEEDED(hr))
+        {
+            if (moduleSize > 0) 
+            {
+                *ppRuntime = new Runtime(target, configuration, moduleIndex, moduleAddress, moduleSize, runtimeInfo);
+            }
+            else 
+            {
+                ExtOut("Runtime (%s) module size == 0\n", runtimeModuleName);
+                hr = E_INVALIDARG;
+            }
+        }
+    }
+    return hr;
+}
+
+/**********************************************************************\
+ * Constructor
+\**********************************************************************/
+Runtime::Runtime(ITarget* target, RuntimeConfiguration configuration, ULONG index, ULONG64 address, ULONG64 size, RuntimeInfo* runtimeInfo) :
+    m_ref(1),
+    m_target(target),
+    m_configuration(configuration),
+    m_index(index),
+    m_address(address),
+    m_size(size),
+    m_name(nullptr),
+    m_runtimeInfo(runtimeInfo),
+    m_runtimeDirectory(nullptr),
+    m_dacFilePath(nullptr),
+    m_dbiFilePath(nullptr),
+    m_clrDataProcess(nullptr),
+    m_pCorDebugProcess(nullptr)
+{
+    _ASSERTE(index != -1);
+    _ASSERTE(address != 0);
+    _ASSERTE(size != 0);
+
+    ArrayHolder<char> szModuleName = new char[MAX_LONGPATH + 1];
+    HRESULT hr = g_ExtSymbols->GetModuleNames(index, 0, szModuleName, MAX_LONGPATH, NULL, NULL, 0, NULL, NULL, 0, NULL);
+    if (SUCCEEDED(hr))
+    {
+        m_name = szModuleName.Detach();
+    }
+}
+
+/**********************************************************************\
+ * Destroys the runtime instance
+\**********************************************************************/
+Runtime::~Runtime()
+{
+    if (m_name != nullptr)
+    {
+        delete [] m_name;
+        m_name = nullptr;
+    }
+    if (m_runtimeDirectory != nullptr)
+    {
+        free((void*)m_runtimeDirectory);
+        m_runtimeDirectory = nullptr;
+    }
+    if (m_dacFilePath != nullptr)
+    {
+        free((void*)m_dacFilePath);
+        m_dacFilePath = nullptr;
+    }
+    if (m_dbiFilePath != nullptr)
+    {
+        free((void*)m_dbiFilePath);
+        m_dbiFilePath = nullptr;
+    }
+    if (m_pCorDebugProcess != NULL)
+    {
+        m_pCorDebugProcess->Detach();
+        m_pCorDebugProcess->Release();
+        m_pCorDebugProcess = nullptr;
+    }
+    if (m_clrDataProcess != nullptr)
+    {
+        m_clrDataProcess->Release();
+        m_clrDataProcess = nullptr;
+    }
+}
+
+/**********************************************************************\
+ * Returns the DAC module path to the rest of SOS.
+\**********************************************************************/
+LPCSTR Runtime::GetDacFilePath()
+{
+    // If the DAC path hasn't been set by the symbol download support, use the one in the runtime directory.
+    if (m_dacFilePath == nullptr)
+    {
+        LPCSTR directory = GetRuntimeDirectory();
+        if (directory != nullptr)
+        {
+            std::string dacModulePath(directory);
+            dacModulePath.append(DIRECTORY_SEPARATOR_STR_A);
+            dacModulePath.append(GetDacDllName());
+#ifdef FEATURE_PAL
+            // If DAC file exists in the runtime directory
+            if (access(dacModulePath.c_str(), F_OK) == 0)
+#endif
+            {
+#if defined(__linux__)
+                // We are creating a symlink to the DAC in a temp directory
+                // where libcoreclrtraceptprovider.so doesn't exist so it 
+                // doesn't get loaded by the DAC causing a LTTng-UST exception.
+                //
+                // Issue #https://github.com/dotnet/coreclr/issues/20205
+                LPCSTR tmpPath = m_target->GetTempDirectory();
+                if (tmpPath != nullptr) 
+                {
+                    std::string dacSymLink(tmpPath);
+                    dacSymLink.append(NETCORE_DAC_DLL_NAME_A);
+
+                    // Check if the DAC file already exists in the temp directory because
+                    // of a "loadsymbols" command which downloads everything.
+                    if (access(dacSymLink.c_str(), F_OK) == 0)
+                    {
+                        dacModulePath.assign(dacSymLink);
+                    }
+                    else
+                    {
+                        int error = symlink(dacModulePath.c_str(), dacSymLink.c_str());
+                        if (error == 0)
+                        {
+                            dacModulePath.assign(dacSymLink);
+                        }
+                        else
+                        {
+                            ExtErr("symlink(%s, %s) FAILED %s\n", dacModulePath.c_str(), dacSymLink.c_str(), strerror(errno));
+                        }
+                    }
+                }
+#endif
+                m_dacFilePath = _strdup(dacModulePath.c_str());
+            }
+        }
+
+        if (m_dacFilePath == nullptr)
+        {
+            // Attempt to only load the DAC/DBI modules
+            LoadRuntimeModules();
+        }
+    }
+    return m_dacFilePath;
+}
+
+/**********************************************************************\
+ * Returns the DBI module path to the rest of SOS
+\**********************************************************************/
+LPCSTR Runtime::GetDbiFilePath()
+{
+    if (m_dbiFilePath == nullptr)
+    {
+        LPCSTR directory = GetRuntimeDirectory();
+        if (directory != nullptr)
+        {
+            std::string dbiModulePath(directory);
+            dbiModulePath.append(DIRECTORY_SEPARATOR_STR_A);
+            dbiModulePath.append(NET_DBI_DLL_NAME_A);
+#ifdef FEATURE_PAL
+            // If DBI file exists in the runtime directory
+            if (access(dbiModulePath.c_str(), F_OK) == 0)
+#endif
+            {
+                m_dbiFilePath = _strdup(dbiModulePath.c_str());
+            }
+        }
+
+        if (m_dbiFilePath == nullptr)
+        {
+            // Attempt to only load the DAC/DBI modules
+            LoadRuntimeModules();
+        }
+    }
+    return m_dbiFilePath;
+}
+
+/**********************************************************************\
+ * Flushes DAC caches
+\**********************************************************************/
+void Runtime::Flush()
+{
+    if (m_clrDataProcess != nullptr)
+    {
+        m_clrDataProcess->Flush();
+    }
+}
+
+//----------------------------------------------------------------------------
+// IUnknown
+//----------------------------------------------------------------------------
+
+HRESULT Runtime::QueryInterface(
+    REFIID InterfaceId,
+    PVOID* Interface
+    )
+{
+    if (InterfaceId == __uuidof(IUnknown) ||
+        InterfaceId == __uuidof(IRuntime))
+    {
+        *Interface = (IRuntime*)this;
+        AddRef();
+        return S_OK;
+    }
+    else
+    {
+        *Interface = NULL;
+        return E_NOINTERFACE;
+    }
+}
+
+ULONG Runtime::AddRef()
+{
+    LONG ref = InterlockedIncrement(&m_ref);    
+    return ref;
+}
+
+ULONG Runtime::Release()
+{
+    LONG ref = InterlockedDecrement(&m_ref);
+    if (ref == 0)
+    {
+        delete this;
+    }
+    return ref;
+}
+
+//----------------------------------------------------------------------------
+// IRuntime
+//----------------------------------------------------------------------------
+
+/**********************************************************************\
+ * Returns the runtime directory of the target
+\**********************************************************************/
+LPCSTR Runtime::GetRuntimeDirectory()
+{
+    if (m_runtimeDirectory == nullptr)
+    {
+        LPCSTR runtimeDirectory = m_target->GetRuntimeDirectory();
+        if (runtimeDirectory != nullptr)
+        {
+            m_runtimeDirectory = _strdup(runtimeDirectory);
+        }
+        else 
+        {
+            if (GetFileAttributesA(m_name) == INVALID_FILE_ATTRIBUTES)
+            {
+                ExtDbgOut("Error: Runtime module %s doesn't exist %08x\n", m_name, HRESULT_FROM_WIN32(GetLastError()));
+                return nullptr;
+            }
+            // Parse off the file name
+            char* runtimeDirectory = _strdup(m_name);
+            char* lastSlash = strrchr(runtimeDirectory, GetTargetDirectorySeparatorW());
+            if (lastSlash != nullptr)
+            {
+                *lastSlash = '\0';
+            }
+            m_runtimeDirectory = runtimeDirectory;
+        }
+    }
+    return m_runtimeDirectory;
+}
+
+/**********************************************************************\
+ * Creates an instance of the DAC clr data process
+\**********************************************************************/
+HRESULT Runtime::GetClrDataProcess(IXCLRDataProcess** ppClrDataProcess)
+{
+    if (m_clrDataProcess == nullptr)
+    {
+        *ppClrDataProcess = nullptr;
+
+        LPCSTR dacFilePath = GetDacFilePath();
+        if (dacFilePath == nullptr)
+        {
+            return CORDBG_E_NO_IMAGE_AVAILABLE;
+        }
+        HMODULE hdac = LoadLibraryA(dacFilePath);
+        if (hdac == NULL)
+        {
+            ExtDbgOut("LoadLibrary(%s) FAILED %08x\n", dacFilePath, HRESULT_FROM_WIN32(GetLastError()));
+            return CORDBG_E_MISSING_DEBUGGER_EXPORTS;
+        }
+        PFN_CLRDataCreateInstance pfnCLRDataCreateInstance = (PFN_CLRDataCreateInstance)GetProcAddress(hdac, "CLRDataCreateInstance");
+        if (pfnCLRDataCreateInstance == nullptr)
+        {
+            FreeLibrary(hdac);
+            return CORDBG_E_MISSING_DEBUGGER_EXPORTS;
+        }
+        ICLRDataTarget *target = new DataTarget(GetModuleAddress());
+        HRESULT hr = pfnCLRDataCreateInstance(__uuidof(IXCLRDataProcess), target, (void**)&m_clrDataProcess);
+        if (FAILED(hr))
+        {
+            m_clrDataProcess = nullptr;
+            return hr;
+        }
+        ULONG32 flags = 0;
+        m_clrDataProcess->GetOtherNotificationFlags(&flags);
+        flags |= (CLRDATA_NOTIFY_ON_MODULE_LOAD | CLRDATA_NOTIFY_ON_MODULE_UNLOAD | CLRDATA_NOTIFY_ON_EXCEPTION);
+        m_clrDataProcess->SetOtherNotificationFlags(flags);
+    }
+    *ppClrDataProcess = m_clrDataProcess;
+    return S_OK;
+}
+
+/**********************************************************************\
+ * Loads and initializes the public ICorDebug interfaces. This should be 
+ * called at least once per debugger stop state to ensure that the 
+ * interface is available and that it doesn't hold stale data. Calling
+ * it more than once isn't an error, but does have perf overhead from 
+ * needlessly flushing memory caches.
+\**********************************************************************/
+HRESULT Runtime::GetCorDebugInterface(ICorDebugProcess** ppCorDebugProcess)
+{
+    HMODULE hModule = NULL;
+    HRESULT hr;
+    ToRelease<ICLRDebugging> pClrDebugging;
+
+    // We may already have an ICorDebug instance we can use
+    if (m_pCorDebugProcess != nullptr)
+    {
+        // ICorDebugProcess4 is currently considered a private experimental interface on ICorDebug, it might go away so
+        // we need to be sure to handle its absence gracefully
+        ToRelease<ICorDebugProcess4> pProcess4 = NULL;
+        if (SUCCEEDED(m_pCorDebugProcess->QueryInterface(__uuidof(ICorDebugProcess4), (void**)&pProcess4)))
+        {
+            // FLUSH_ALL is more expensive than PROCESS_RUNNING, but this allows us to be safe even if things
+            // like IDNA are in use where we might be looking at non-sequential snapshots of process state
+            if (SUCCEEDED(pProcess4->ProcessStateChanged(FLUSH_ALL)))
+            {
+                // We already have an ICorDebug instance loaded and flushed, nothing more to do
+                *ppCorDebugProcess = m_pCorDebugProcess;
+                return S_OK;
+            }
+        }
+
+        // This is a very heavy handed way of reseting
+        m_pCorDebugProcess->Detach();
+        m_pCorDebugProcess->Release();
+        m_pCorDebugProcess = nullptr;
+    }
+
+    // SOS now has a statically linked version of the loader code that is normally found in mscoree/mscoreei.dll
+    // Its not much code and takes a big step towards 0 install dependencies
+    // Need to pick the appropriate SKU of CLR to detect
+#if defined(FEATURE_CORESYSTEM)
+    GUID skuId = CLR_ID_ONECORE_CLR;
+#else
+    GUID skuId = CLR_ID_CORECLR;
+#endif
+#ifndef FEATURE_PAL
+    if (GetRuntimeConfiguration() == IRuntime::WindowsDesktop)
+    {
+        skuId = CLR_ID_V4_DESKTOP;
+    }
+#endif
+    CLRDebuggingImpl* pDebuggingImpl = new CLRDebuggingImpl(skuId, IsWindowsTarget());
+    hr = pDebuggingImpl->QueryInterface(IID_ICLRDebugging, (LPVOID *)&pClrDebugging);
+    if (FAILED(hr))
+    {
+        delete pDebuggingImpl;
+        return hr;
+    }
+
+    ToRelease<ICorDebugMutableDataTarget> pCorDebugDataTarget = new CorDebugDataTarget;
+    pCorDebugDataTarget->AddRef();
+
+    ToRelease<ICLRDebuggingLibraryProvider> pCorDebugLibraryProvider = new CorDebugLibraryProvider(this);
+    pCorDebugLibraryProvider->AddRef();
+
+    CLR_DEBUGGING_VERSION clrDebuggingVersionRequested = {0};
+    clrDebuggingVersionRequested.wMajor = 4;
+
+    CLR_DEBUGGING_VERSION clrDebuggingVersionActual = {0};
+
+    CLR_DEBUGGING_PROCESS_FLAGS clrDebuggingFlags = (CLR_DEBUGGING_PROCESS_FLAGS)0;
+
+    ToRelease<IUnknown> pUnkProcess;
+    hr = pClrDebugging->OpenVirtualProcess(
+        GetModuleAddress(),
+        pCorDebugDataTarget,
+        pCorDebugLibraryProvider,
+        &clrDebuggingVersionRequested,
+        IID_ICorDebugProcess,
+        &pUnkProcess,
+        &clrDebuggingVersionActual,
+        &clrDebuggingFlags);
+
+    if (FAILED(hr)) {
+        return hr;
+    }
+    hr = pUnkProcess->QueryInterface(IID_ICorDebugProcess, (PVOID*)&m_pCorDebugProcess);
+    if (FAILED(hr)) {
+        return hr;
+    }
+    *ppCorDebugProcess = m_pCorDebugProcess;
+    return hr;
+}
+
+/**********************************************************************\
+ * Gets the runtime version
+\**********************************************************************/
+HRESULT Runtime::GetEEVersion(VS_FIXEDFILEINFO* pFileInfo, char* fileVersionBuffer, int fileVersionBufferSizeInBytes)
+{
+    _ASSERTE(pFileInfo);
+    _ASSERTE(g_ExtSymbols2 != nullptr);
+
+#ifdef FEATURE_PAL
+    // Load the symbols for runtime. On Linux we are looking for the "sccsid" 
+    // global so "libcoreclr.so/.dylib" symbols need to be loaded.
+    LoadNativeSymbols(true);
+#endif
+
+    HRESULT hr = g_ExtSymbols2->GetModuleVersionInformation(
+        m_index, 0, "\\", pFileInfo, sizeof(VS_FIXEDFILEINFO), NULL);
+
+    // 0.0.0.0 is not a valid version. This is sometime returned by windbg for Linux core dumps
+    if (SUCCEEDED(hr) && (pFileInfo->dwFileVersionMS == (DWORD)-1 || (pFileInfo->dwFileVersionLS == 0 && pFileInfo->dwFileVersionMS == 0))) {
+        return E_FAIL;
+    }
+
+    // Attempt to get the FileVersion string that contains version and the "built by" and commit id info
+    if (fileVersionBuffer != nullptr)
+    {
+        if (fileVersionBufferSizeInBytes > 0) {
+            fileVersionBuffer[0] = '\0';
+        }
+        // We can assume the English/CP_UNICODE lang/code page for the runtime modules
+        g_ExtSymbols2->GetModuleVersionInformation(
+            m_index, 0, "\\StringFileInfo\\040904B0\\FileVersion", fileVersionBuffer, fileVersionBufferSizeInBytes, NULL);
+    }
+
+    return hr;
+}
+
+/**********************************************************************\
+ * Displays the runtime internal status
+\**********************************************************************/
+void Runtime::DisplayStatus()
+{
+    char current = g_pRuntime == this ? '*' : ' ';
+    ExtOut("%c%s runtime at %08llx size %08llx\n", current, GetRuntimeConfigurationName(GetRuntimeConfiguration()), m_address, m_size);
+    if (m_runtimeInfo != nullptr) {
+        ExtOut("    Single-file module path: %s\n", m_name);
+    }
+    else {
+        ExtOut("    Runtime module path: %s\n", m_name);
+    }
+    if (m_runtimeDirectory != nullptr) {
+        ExtOut("    Runtime directory: %s\n", m_runtimeDirectory);
+    }
+    if (m_dacFilePath != nullptr) {
+        ExtOut("    DAC file path: %s\n", m_dacFilePath);
+    }
+    if (m_dbiFilePath != nullptr) {
+        ExtOut("    DBI file path: %s\n", m_dbiFilePath);
+    }
+}
+
+extern bool g_symbolStoreInitialized;
+extern HRESULT InitializeSymbolStore();
+extern int ReadMemoryForSymbols(ULONG64 address, uint8_t* buffer, int cb);
+
+/**********************************************************************\
+ * Attempt to download the runtime modules (runtime, DAC and DBI)
+\**********************************************************************/
+void Runtime::LoadRuntimeModules()
+{
+    HRESULT hr = InitializeSymbolStore();
+    if (SUCCEEDED(hr) && g_symbolStoreInitialized)
+    {
+        if (m_runtimeInfo != nullptr)
+        {
+            _ASSERTE(g_SOSNetCoreCallbacks.LoadNativeSymbolsFromIndexDelegate != nullptr);
+            g_SOSNetCoreCallbacks.LoadNativeSymbolsFromIndexDelegate(
+                SymbolFileCallback,
+                this,
+                GetRuntimeConfiguration(),
+                GetRuntimeDllName(),
+                true,                                   // special keys (runtime, DAC and DBI)
+                m_runtimeInfo->RuntimeModuleIndex[0],   // size of module index
+                &m_runtimeInfo->RuntimeModuleIndex[1]); // beginning of index 
+        }
+        else
+        {
+            ArrayHolder<char> moduleFilePath = new char[MAX_LONGPATH + 1];
+            hr = g_ExtSymbols->GetModuleNames(m_index, 0, moduleFilePath, MAX_LONGPATH, NULL, NULL, 0, NULL, NULL, 0, NULL);
+            if (SUCCEEDED(hr))
+            {
+                _ASSERTE(g_SOSNetCoreCallbacks.LoadNativeSymbolsDelegate != nullptr);
+                g_SOSNetCoreCallbacks.LoadNativeSymbolsDelegate(
+                    SymbolFileCallback,
+                    this,
+                    GetRuntimeConfiguration(),
+                    moduleFilePath,
+                    m_address,
+                    (int)m_size,
+                    ReadMemoryForSymbols);
+            }
+        }
+    }
+}
+
+/**********************************************************************\
+ * Called by LoadRuntimeModules to set the DAC and DBI file paths
+\**********************************************************************/
+void Runtime::SymbolFileCallback(const char* moduleFileName, const char* symbolFilePath)
+{
+    if (strcmp(moduleFileName, GetRuntimeDllName()) == 0) {
+        return;
+    }
+    if (strcmp(moduleFileName, GetDacDllName()) == 0) {
+        SetDacFilePath(symbolFilePath);
+        return;
+    }
+    if (strcmp(moduleFileName, NET_DBI_DLL_NAME_A) == 0) {
+        SetDbiFilePath(symbolFilePath);
+        return;
+    }
+}
+
+#ifndef FEATURE_PAL
+
+/**********************************************************************\
+ * Internal function to load and check the version of the module
+\**********************************************************************/
+HMODULE LoadLibraryAndCheck(
+    PCWSTR filename,
+    DWORD timestamp,
+    DWORD filesize)
+{
+    HMODULE hModule = LoadLibraryExW(
+        filename,
+        NULL,                               //  __reserved
+        LOAD_WITH_ALTERED_SEARCH_PATH);     // Ensure we check the dir in wszFullPath first
+
+    if (hModule == NULL)
+    {
+        ExtOut("Unable to load '%S'. hr = 0x%x.\n", filename, HRESULT_FROM_WIN32(GetLastError()));
+        return NULL;
+    }
+    
+    // Did we load the right one?
+    MODULEINFO modInfo = {0};
+    if (!GetModuleInformation(
+        GetCurrentProcess(),
+        hModule,
+        &modInfo,
+        sizeof(modInfo)))
+    {
+        ExtOut("Failed to read module information for '%S'. hr = 0x%x.\n", filename, HRESULT_FROM_WIN32(GetLastError()));
+        FreeLibrary(hModule);
+        return NULL;
+    }
+
+    IMAGE_DOS_HEADER * pDOSHeader = (IMAGE_DOS_HEADER *) modInfo.lpBaseOfDll;
+    IMAGE_NT_HEADERS * pNTHeaders = (IMAGE_NT_HEADERS *) (((LPBYTE) modInfo.lpBaseOfDll) + pDOSHeader->e_lfanew);
+    DWORD dwSizeActual = pNTHeaders->OptionalHeader.SizeOfImage;
+    DWORD dwTimeStampActual = pNTHeaders->FileHeader.TimeDateStamp;
+    if ((dwSizeActual != filesize) || (dwTimeStampActual != timestamp))
+    {
+        ExtOut("Found '%S', but it does not match the CLR being debugged.\n", filename);
+        ExtOut("Size: Expected '0x%x', Actual '0x%x'\n", filesize, dwSizeActual);
+        ExtOut("Time stamp: Expected '0x%x', Actual '0x%x'\n", timestamp, dwTimeStampActual);
+        FreeLibrary(hModule);
+        return NULL;
+    }
+
+    return hModule;
+}
+
+#endif // FEATURE_PAL
diff --git a/src/SOS/Strike/platform/runtimeimpl.h b/src/SOS/Strike/platform/runtimeimpl.h
new file mode 100644 (file)
index 0000000..f73fffc
--- /dev/null
@@ -0,0 +1,225 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#pragma once
+
+#include "runtime.h"
+#include "runtimeinfo.h"
+
+#ifdef FEATURE_PAL
+
+#define NETCORE_DAC_MODULE_NAME_W       MAKEDLLNAME_W(W("mscordaccore"))
+#define NETCORE_DAC_MODULE_NAME_A       MAKEDLLNAME_A("mscordaccore")
+#define NETCORE_DAC_DLL_NAME_W          NETCORE_DAC_MODULE_NAME_W
+#define NETCORE_DAC_DLL_NAME_A          NETCORE_DAC_MODULE_NAME_A
+
+#define NET_DBI_MODULE_NAME_W           MAKEDLLNAME_W(W("mscordbi"))
+#define NET_DBI_MODULE_NAME_A           MAKEDLLNAME_A("mscordbi")
+#define NET_DBI_DLL_NAME_W              NET_DBI_MODULE_NAME_W       
+#define NET_DBI_DLL_NAME_A              NET_DBI_MODULE_NAME_A       
+
+#else
+
+#define NETCORE_DAC_MODULE_NAME_W       W("mscordaccore")
+#define NETCORE_DAC_MODULE_NAME_A       "mscordaccore"
+#define NETCORE_DAC_DLL_NAME_W          MAKEDLLNAME_W(NETCORE_DAC_MODULE_NAME_W)
+#define NETCORE_DAC_DLL_NAME_A          MAKEDLLNAME_A(NETCORE_DAC_MODULE_NAME_A)
+
+#define NET_DBI_MODULE_NAME_W           W("mscordbi")
+#define NET_DBI_MODULE_NAME_A           "mscordbi"
+#define NET_DBI_DLL_NAME_W              MAKEDLLNAME_W(W("mscordbi"))
+#define NET_DBI_DLL_NAME_A              MAKEDLLNAME_A("mscordbi")
+
+#endif // FEATURE_PAL
+
+#define DESKTOP_DAC_MODULE_NAME_W       W("mscordacwks")
+#define DESKTOP_DAC_MODULE_NAME_A       "mscordacwks"
+#define DESKTOP_DAC_DLL_NAME_W          MAKEDLLNAME_W(W("mscordacwks"))
+#define DESKTOP_DAC_DLL_NAME_A          MAKEDLLNAME_A("mscordacwks")
+
+extern IRuntime* g_pRuntime;
+
+// Returns the runtime configuration as a string
+inline static const char* GetRuntimeConfigurationName(IRuntime::RuntimeConfiguration config)
+{
+    static const char* name[IRuntime::ConfigurationEnd] = {
+        "Desktop .NET Framework",
+        ".NET Core (Windows)",
+        ".NET Core (Unix)",
+        ".NET Core (Mac)"
+    };
+    return (config < IRuntime::ConfigurationEnd) ? name[config] : nullptr;
+}
+
+// Returns the runtime module DLL name (clr.dll, coreclr.dll, libcoreclr.so, libcoreclr.dylib)
+inline static const char* GetRuntimeDllName(IRuntime::RuntimeConfiguration config)
+{
+    static const char* name[IRuntime::ConfigurationEnd] = {
+        "clr.dll",
+        "coreclr.dll",
+        "libcoreclr.so",
+        "libcoreclr.dylib"
+    };
+    return (config < IRuntime::ConfigurationEnd) ? name[config] : nullptr;
+}
+
+// Returns the runtime module name (clr, coreclr, libcoreclr.so, libcoreclr.dylib).
+inline static const char* GetRuntimeModuleName(IRuntime::RuntimeConfiguration config)
+{
+#ifdef FEATURE_PAL
+    return GetRuntimeDllName(config);
+#else
+    // On a windows host the module name does not include the extension.
+    static const char* name[IRuntime::ConfigurationEnd] = {
+        "clr",
+        "coreclr",
+        "libcoreclr",
+        "libcoreclr"
+    };
+    return (config < IRuntime::ConfigurationEnd) ? name[config] : nullptr;
+#endif
+}
+
+// Returns the runtime module name (clr, coreclr, libcoreclr.so, libcoreclr.dylib).
+inline const char* GetRuntimeModuleName()
+{
+    return GetRuntimeModuleName(g_pRuntime->GetRuntimeConfiguration());
+}
+
+// Returns the runtime module DLL name (clr.dll, coreclr.dll, libcoreclr.so, libcoreclr.dylib)
+inline const char* GetRuntimeDllName()
+{
+    return GetRuntimeDllName(g_pRuntime->GetRuntimeConfiguration());
+}
+
+// Returns the DAC module name (mscordacwks, mscordaccore, libmscordaccore.so, libmscordaccore.dylib) 
+inline const char* GetDacModuleName()
+{
+    return (g_pRuntime->GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_MODULE_NAME_A : NETCORE_DAC_MODULE_NAME_A;
+}
+
+// Returns the DAC module name (mscordacwks.dll, mscordaccore.dll, libmscordaccore.so, libmscordaccore.dylib) 
+inline const char* GetDacDllName()
+{
+    return (g_pRuntime->GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_DLL_NAME_A : NETCORE_DAC_DLL_NAME_A;
+}
+
+inline bool IsWindowsTarget()
+{
+    return GetTarget()->GetOperatingSystem() == ITarget::OperatingSystem::Windows;
+}
+
+/**********************************************************************\
+ * Local Runtime interface implementation
+\**********************************************************************/
+class Runtime : public IRuntime
+{
+private:
+    LONG m_ref;
+    ITarget* m_target;
+    RuntimeConfiguration m_configuration;
+    ULONG m_index;
+    ULONG64 m_address;
+    ULONG64 m_size;
+    const char* m_name;
+    RuntimeInfo* m_runtimeInfo;
+    LPCSTR m_runtimeDirectory;
+    LPCSTR m_dacFilePath;
+    LPCSTR m_dbiFilePath;
+    IXCLRDataProcess* m_clrDataProcess;
+    ICorDebugProcess* m_pCorDebugProcess;
+
+    Runtime::Runtime(ITarget* target, RuntimeConfiguration configuration, ULONG index, ULONG64 address, ULONG64 size, RuntimeInfo* runtimeInfo);
+
+    virtual Runtime::~Runtime();
+
+    void LoadRuntimeModules();
+
+    void SymbolFileCallback(const char* moduleFileName, const char* symbolFilePath);
+
+    static void SymbolFileCallback(void* param, const char* moduleFileName, const char* symbolFilePath)
+    {
+        ((Runtime*)param)->SymbolFileCallback(moduleFileName, symbolFilePath);
+    }
+
+    void SetDacFilePath(LPCSTR dacFilePath)
+    { 
+        if (m_dacFilePath == nullptr && dacFilePath != nullptr) {
+            m_dacFilePath = _strdup(dacFilePath);
+        }
+    }
+
+    void SetDbiFilePath(LPCSTR dbiFilePath) 
+    { 
+        if (m_dbiFilePath == nullptr && dbiFilePath != nullptr) {
+            m_dbiFilePath = _strdup(dbiFilePath);
+        }
+    }
+
+public:
+    static HRESULT CreateInstance(ITarget* target, RuntimeConfiguration configuration, Runtime** ppRuntime);
+
+    void Flush();
+
+    LPCSTR GetDacFilePath();
+
+    LPCSTR GetDbiFilePath();
+
+    void DisplayStatus();
+
+    //----------------------------------------------------------------------------
+    // IUnknown
+    //----------------------------------------------------------------------------
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(
+        REFIID InterfaceId,
+        PVOID* Interface);
+
+    ULONG STDMETHODCALLTYPE AddRef();
+
+    ULONG STDMETHODCALLTYPE Release();
+
+    //----------------------------------------------------------------------------
+    // IRuntime
+    //----------------------------------------------------------------------------
+
+    RuntimeConfiguration STDMETHODCALLTYPE GetRuntimeConfiguration() const { return m_configuration; }
+
+    ULONG64 STDMETHODCALLTYPE GetModuleAddress() const { return m_address; }
+
+    ULONG64 STDMETHODCALLTYPE GetModuleSize() const { return m_size; }
+
+    LPCSTR STDMETHODCALLTYPE GetRuntimeDirectory();
+
+    HRESULT STDMETHODCALLTYPE GetClrDataProcess(IXCLRDataProcess** ppClrDataProcess);
+
+    HRESULT STDMETHODCALLTYPE GetCorDebugInterface(ICorDebugProcess** ppCorDebugProcess);
+
+    HRESULT STDMETHODCALLTYPE GetEEVersion(VS_FIXEDFILEINFO* pFileInfo, char* fileVersionBuffer, int fileVersionBufferSizeInBytes);
+
+
+    // Returns the runtime module DLL name (clr.dll, coreclr.dll, libcoreclr.so, libcoreclr.dylib)
+    inline const char* GetRuntimeDllName() const
+    {
+        return ::GetRuntimeDllName(GetRuntimeConfiguration());
+    }
+
+    // Returns the DAC module name (mscordacwks.dll, mscordaccore.dll, libmscordaccore.so, libmscordaccore.dylib) 
+    inline const char* GetDacDllName() const
+    {
+        return (GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_DLL_NAME_A : NETCORE_DAC_DLL_NAME_A;
+    }
+
+    // Returns the DAC module name (mscordacwks, mscordaccore, libmscordaccore.so, libmscordaccore.dylib) 
+    inline const WCHAR* GetDacModuleNameW() const
+    {
+        return (GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_MODULE_NAME_W : NETCORE_DAC_MODULE_NAME_W;
+    }
+
+    // Returns the DAC module name (mscordacwks.dll, mscordaccore.dll, libmscordaccore.so, libmscordaccore.dylib) 
+    inline const WCHAR* GetDacDllNameW() const
+    {
+        return (GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_DLL_NAME_W : NETCORE_DAC_DLL_NAME_W;
+    }
+};
diff --git a/src/SOS/Strike/platform/targetimpl.cpp b/src/SOS/Strike/platform/targetimpl.cpp
new file mode 100644 (file)
index 0000000..bea30ed
--- /dev/null
@@ -0,0 +1,350 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "strike.h"
+#include "util.h"
+#include "targetimpl.h"
+#include "host.h"
+#include <string>
+
+Target* Target::s_target = nullptr;
+
+//----------------------------------------------------------------------------
+// Target
+//----------------------------------------------------------------------------
+
+Target::Target() :
+    m_ref(1),
+    m_tmpPath(nullptr),
+    m_runtimeModulePath(nullptr),
+#ifndef FEATURE_PAL
+    m_desktop(nullptr),
+#endif
+    m_netcore(nullptr)
+{ 
+}
+
+Target::~Target()
+{
+    Close();
+    if (m_runtimeModulePath != nullptr)
+    {
+        free((void*)m_runtimeModulePath);
+        m_runtimeModulePath = nullptr;
+    }
+    if (m_netcore != nullptr)
+    {
+        m_netcore->Release();
+        m_netcore = nullptr;
+    }
+#ifdef FEATURE_PAL
+    FlushMetadataRegions();
+#else
+    if (m_desktop != nullptr)
+    {
+        m_desktop->Release();
+        m_desktop = nullptr;
+    }
+#endif
+    g_pRuntime = nullptr;
+    s_target = nullptr;
+}
+
+/**********************************************************************\
+* Creates a local target instance or returns the existing one
+\**********************************************************************/
+ITarget* Target::GetInstance()
+{
+    if (s_target == nullptr) 
+    {
+        s_target = new Target();
+        OnUnloadTask::Register(CleanupTarget);
+    }
+    s_target->AddRef();
+    return s_target;
+}
+
+/**********************************************************************\
+ * Creates an instance of the runtime class. First it attempts to create
+ * the .NET Core instance and if that fails, it will try to create the
+ * desktop CLR instance.  If both runtimes exists in the process or dump
+ * this runtime only creates the .NET Core version and leaves creating
+ * the desktop instance on demand in SwitchRuntime.
+\**********************************************************************/
+HRESULT 
+Target::CreateInstance(IRuntime **ppRuntime)
+{
+    HRESULT hr = S_OK;
+    if (*ppRuntime == nullptr)
+    {
+        hr = Runtime::CreateInstance(this, IRuntime::Core, &m_netcore);
+#ifdef FEATURE_PAL
+        *ppRuntime = m_netcore;
+#else
+        ITarget::OperatingSystem os = this->GetOperatingSystem();
+        if (FAILED(hr))
+        {
+            if (os == ITarget::OperatingSystem::Linux || os == ITarget::OperatingSystem::OSX)
+            {
+                hr = Runtime::CreateInstance(this, IRuntime::UnixCore, &m_netcore);
+            }
+        }
+        if (FAILED(hr))
+        {
+            if (os == ITarget::OperatingSystem::Windows)
+            {
+                hr = Runtime::CreateInstance(this, IRuntime::WindowsDesktop, &m_desktop);
+            }
+        }
+        *ppRuntime = m_netcore != nullptr ? m_netcore : m_desktop;
+#endif
+    }
+    return hr;
+}
+
+/**********************************************************************\
+ * Switches between the .NET Core and desktop runtimes (if both 
+ * loaded). Creates the desktop CLR runtime instance on demand.
+\**********************************************************************/
+#ifndef FEATURE_PAL
+bool Target::SwitchRuntimeInstance(bool desktop)
+{
+    if (desktop) 
+    {
+        if (this->GetOperatingSystem() != ITarget::OperatingSystem::Windows) {
+            return false;
+        }
+        Runtime::CreateInstance(this, IRuntime::WindowsDesktop, &m_desktop);
+    }
+    IRuntime* runtime = desktop ? m_desktop : m_netcore;
+    if (runtime == nullptr) {
+        return false;
+    }
+    g_pRuntime = runtime;
+    return true;
+}
+#endif
+
+/**********************************************************************\
+ * Set the runtime directory path
+\**********************************************************************/
+void Target::SetRuntimeDirectoryInstance(LPCSTR runtimeModulePath)
+{
+    if (m_runtimeModulePath != nullptr) {
+        free((void*)m_runtimeModulePath);
+    }
+    m_runtimeModulePath = _strdup(runtimeModulePath);
+}
+
+/**********************************************************************\
+ * Display the internal target and runtime status
+\**********************************************************************/
+void Target::DisplayStatusInstance()
+{
+    static const char* osName[] = {
+        "Unknown",
+        "Windows",
+        "Linux",
+        "MacOS"
+    };
+    if (g_targetMachine != nullptr) {
+        ExtOut("Target OS: %s Platform: %04x Context size: %04x\n", osName[GetOperatingSystem()], g_targetMachine->GetPlatform(), g_targetMachine->GetContextSize());
+    }
+    if (m_tmpPath != nullptr) {
+        ExtOut("Temp path: %s\n", m_tmpPath);
+    }
+    if (m_runtimeModulePath != nullptr) {
+        ExtOut("Runtime module path: %s\n", m_runtimeModulePath);
+    }
+    if (m_netcore != nullptr) {
+        m_netcore->DisplayStatus();
+    }
+#ifndef FEATURE_PAL
+    if (m_desktop != nullptr) {
+        m_desktop->DisplayStatus();
+    }
+#endif
+}
+
+//----------------------------------------------------------------------------
+// IUnknown
+//----------------------------------------------------------------------------
+
+HRESULT Target::QueryInterface(
+    REFIID InterfaceId,
+    PVOID* Interface
+    )
+{
+    if (InterfaceId == __uuidof(IUnknown) ||
+        InterfaceId == __uuidof(ITarget))
+    {
+        *Interface = (ITarget*)this;
+        AddRef();
+        return S_OK;
+    }
+    else
+    {
+        *Interface = NULL;
+        return E_NOINTERFACE;
+    }
+}
+
+ULONG Target::AddRef()
+{
+    LONG ref = InterlockedIncrement(&m_ref);    
+    return ref;
+}
+
+ULONG Target::Release()
+{
+    LONG ref = InterlockedDecrement(&m_ref);
+    if (ref == 0)
+    {
+        delete this;
+    }
+    return ref;
+}
+
+//----------------------------------------------------------------------------
+// ITarget
+//----------------------------------------------------------------------------
+
+#define VER_PLATFORM_UNIX 10 
+
+ITarget::OperatingSystem Target::GetOperatingSystem()
+{
+#ifdef FEATURE_PAL
+#if defined(__APPLE__)
+    return OperatingSystem::OSX;
+#elif defined(__linux__)
+    return OperatingSystem::Linux;
+#else
+    return OperatingSystem::Unknown;
+#endif
+#else
+    ULONG platformId, major, minor, servicePack;
+    if (SUCCEEDED(g_ExtControl->GetSystemVersion(&platformId, &major, &minor, nullptr, 0, nullptr, &servicePack, nullptr, 0, nullptr)))
+    {
+        if (platformId == VER_PLATFORM_UNIX)
+        {
+            return OperatingSystem::Linux;
+        }
+    }
+    return OperatingSystem::Windows;
+#endif
+}
+
+LPCSTR Target::GetTempDirectory()
+{
+    if (m_tmpPath == nullptr)
+    {
+        char tmpPath[MAX_LONGPATH];
+        if (::GetTempPathA(MAX_LONGPATH, tmpPath) == 0)
+        {
+            // Use current directory if can't get temp path
+            strcpy_s(tmpPath, MAX_LONGPATH, ".");
+            strcat_s(tmpPath, MAX_LONGPATH, DIRECTORY_SEPARATOR_STR_A);
+        }
+        ULONG pid = 0;
+        if (g_ExtSystem->GetCurrentProcessSystemId(&pid) != 0)
+        {
+            // Use the SOS process id if can't get target's
+            pid = ::GetCurrentProcessId();
+        }
+        char pidstr[128];
+        sprintf_s(pidstr, _countof(pidstr), "sos%d", pid);
+        strcat_s(tmpPath, MAX_LONGPATH, pidstr);
+        strcat_s(tmpPath, MAX_LONGPATH, DIRECTORY_SEPARATOR_STR_A);
+
+        CreateDirectoryA(tmpPath, NULL);
+        m_tmpPath = _strdup(tmpPath);
+    }
+    return m_tmpPath;
+}
+
+LPCSTR Target::GetRuntimeDirectory()
+{
+    return m_runtimeModulePath;
+}
+
+HRESULT Target::GetRuntime(IRuntime** ppRuntime)
+{
+    return CreateInstance(ppRuntime);
+}
+
+void Target::Flush()
+{
+    if (m_netcore != nullptr) {
+        m_netcore->Flush();
+    }
+#ifndef FEATURE_PAL
+    if (m_desktop != nullptr) {
+        m_desktop->Flush();
+    }
+#endif
+}
+
+void Target::Close()
+{
+    // Clean up the temporary directory files and DAC symlink.
+    LPCSTR tmpPath = (LPCSTR)InterlockedExchangePointer((PVOID *)&m_tmpPath, nullptr);
+    if (tmpPath != nullptr)
+    {
+        std::string directory(tmpPath);
+        directory.append("*");
+
+        WIN32_FIND_DATAA data;
+        HANDLE findHandle = FindFirstFileA(directory.c_str(), &data);
+
+        if (findHandle != INVALID_HANDLE_VALUE) 
+        {
+            do
+            {
+                if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+                {
+                    std::string file(tmpPath);
+                    file.append(data.cFileName);
+                    DeleteFileA(file.c_str());
+                }
+            } 
+            while (0 != FindNextFileA(findHandle, &data));
+
+            FindClose(findHandle);
+        }
+
+        RemoveDirectoryA(tmpPath);
+        free((void*)tmpPath);
+    }
+}
+
+static IHost* g_pHost = nullptr;
+
+IHost* GetHost()
+{
+    if (g_pHost == nullptr)
+    {
+        g_pHost = Host::GetInstance();
+    }
+    return g_pHost;
+}
+
+static ITarget* g_pTarget = nullptr;
+
+ITarget* GetTarget()
+{
+    if (g_pTarget == nullptr)
+    {
+        GetHost()->GetCurrentTarget(&g_pTarget);
+    }
+    return g_pTarget;
+}
+
+void ReleaseTarget()
+{
+    if (g_pTarget != nullptr)
+    {
+        g_pTarget->Release();
+        g_pTarget = nullptr;
+    }
+}
diff --git a/src/SOS/Strike/platform/targetimpl.h b/src/SOS/Strike/platform/targetimpl.h
new file mode 100644 (file)
index 0000000..7afb001
--- /dev/null
@@ -0,0 +1,114 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#pragma once
+
+#include "host.h"
+#include "target.h"
+#include "hostcoreclr.h"
+
+class Runtime;
+
+//----------------------------------------------------------------------------
+// Local implementation of ITarget when the host doesn't provide it
+//----------------------------------------------------------------------------
+class Target : public ITarget
+{
+private:
+    LONG m_ref;
+    LPCSTR m_tmpPath;
+    LPCSTR m_runtimeModulePath;
+#ifndef FEATURE_PAL
+    Runtime* m_desktop;
+#endif
+    Runtime* m_netcore;
+
+    static Target* s_target;
+
+#ifndef FEATURE_PAL
+    bool SwitchRuntimeInstance(bool desktop);
+#endif
+    void SetRuntimeDirectoryInstance(LPCSTR runtimeModulePath);
+    void DisplayStatusInstance();
+
+    Target();
+    virtual ~Target();
+
+public:
+    static ITarget* GetInstance();
+
+    HRESULT CreateInstance(IRuntime** ppRuntime);
+
+    static bool SetRuntimeDirectory(LPCSTR runtimeModulePath)
+    {
+        std::string fullPath;
+        if (!GetAbsolutePath(runtimeModulePath, fullPath))
+        {
+            return false;
+        }
+        GetInstance();
+        _ASSERTE(s_target != nullptr);
+        s_target->SetRuntimeDirectoryInstance(fullPath.c_str());
+        return true;
+    }
+
+#ifndef FEATURE_PAL
+    static bool SwitchRuntime(bool desktop)
+    {
+        GetInstance();
+        _ASSERTE(s_target != nullptr);
+        return s_target->SwitchRuntimeInstance(desktop);
+    }
+#endif
+
+    static void DisplayStatus()
+    {
+        if (s_target != nullptr) 
+        {
+            s_target->DisplayStatusInstance();
+        }
+    }
+
+    static void CleanupTarget()
+    {
+        if (s_target != nullptr)
+        {
+            s_target->Release();
+        }
+    }
+
+    //----------------------------------------------------------------------------
+    // IUnknown
+    //----------------------------------------------------------------------------
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(
+        REFIID InterfaceId,
+        PVOID* Interface);
+
+    ULONG STDMETHODCALLTYPE AddRef();
+
+    ULONG STDMETHODCALLTYPE Release();
+
+    //----------------------------------------------------------------------------
+    // ITarget
+    //----------------------------------------------------------------------------
+
+    OperatingSystem STDMETHODCALLTYPE GetOperatingSystem();
+
+    LPCSTR STDMETHODCALLTYPE GetTempDirectory();
+
+    LPCSTR STDMETHODCALLTYPE GetRuntimeDirectory();
+    
+    HRESULT STDMETHODCALLTYPE GetRuntime(IRuntime** pRuntime);
+
+    void STDMETHODCALLTYPE Flush();
+
+    void STDMETHODCALLTYPE Close();
+};
+
+IHost* GetHost();
+
+ITarget* GetTarget();
+
+void ReleaseTarget();
\ No newline at end of file
diff --git a/src/SOS/Strike/runtime.cpp b/src/SOS/Strike/runtime.cpp
deleted file mode 100644 (file)
index 4875011..0000000
+++ /dev/null
@@ -1,688 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#include "strike.h"
-#include "util.h"
-#include <string>
-#include <corhdr.h>
-#include <cor.h>
-#include <clrdata.h>
-#include <dbghelp.h>
-#include <cordebug.h>
-#include <xcordebug.h>
-#include <mscoree.h>
-#include <psapi.h>
-#include <clrinternal.h>
-#include <metahost.h>
-#include <debugshim.h>
-#include "runtime.h"
-#include "datatarget.h"
-#include "cordebugdatatarget.h"
-#include "cordebuglibraryprovider.h"
-#include "runtimeinfo.h"
-
-#ifdef FEATURE_PAL
-#include <sys/stat.h>
-#include <dlfcn.h>
-#include <unistd.h>
-#endif // !FEATURE_PAL
-
-
-Runtime* Runtime::s_netcore = nullptr;
-#ifndef FEATURE_PAL
-Runtime* Runtime::s_desktop = nullptr;
-#endif
-
-// Used to initialize the runtime instance with values from the host when under dotnet-dump
-IRuntime::RuntimeConfiguration Runtime::s_configuration = IRuntime::Core;
-LPCSTR Runtime::s_dacFilePath = nullptr;
-LPCSTR Runtime::s_dbiFilePath = nullptr;
-
-// The runtime module path set by the "setclrpath" command
-LPCSTR g_runtimeModulePath = nullptr;
-
-// Current runtime instance
-IRuntime* g_pRuntime = nullptr;
-
-#if !defined(__APPLE__)
-
-extern bool TryGetSymbol(uint64_t baseAddress, const char* symbolName, uint64_t* symbolAddress);
-
-bool ElfReaderReadMemory(void* address, void* buffer, size_t size)
-{
-    ULONG read = 0;
-    return SUCCEEDED(g_ExtData->ReadVirtual((ULONG64)address, buffer, (ULONG)size, &read));
-}
-
-/**********************************************************************\
- * Search all the modules in the process for the single-file host
-\**********************************************************************/
-static HRESULT GetSingleFileInfo(PULONG pModuleIndex, PULONG64 pModuleAddress, RuntimeInfo** ppRuntimeInfo)
-{
-    _ASSERTE(pModuleIndex != nullptr);
-    _ASSERTE(pModuleAddress != nullptr);
-
-    ULONG loaded, unloaded;
-    HRESULT hr = g_ExtSymbols->GetNumberModules(&loaded, &unloaded);
-    if (FAILED(hr)) {
-        return hr;
-    }
-
-    for (ULONG index = 0; index < loaded; index++)
-    {
-        ULONG64 baseAddress;
-        hr = g_ExtSymbols->GetModuleByIndex(index, &baseAddress);
-        if (FAILED(hr)) {
-            return hr;
-        }
-        ULONG64 symbolAddress;
-        if (TryGetSymbol(baseAddress, "DotNetRuntimeInfo", &symbolAddress))
-        {
-            ULONG read = 0;
-            ArrayHolder<BYTE> buffer = new BYTE[sizeof(RuntimeInfo)];
-            hr = g_ExtData->ReadVirtual(symbolAddress, buffer, sizeof(RuntimeInfo), &read);
-            if (FAILED(hr)) {
-                return hr;
-            }
-            if (strcmp(((RuntimeInfo*)buffer.GetPtr())->Signature, "DotNetRuntimeInfo") != 0) {
-                break;
-            }
-            *pModuleIndex = index;
-            *pModuleAddress = baseAddress;
-            *ppRuntimeInfo = (RuntimeInfo*)buffer.Detach();
-            return S_OK;
-        }
-    }
-
-    return E_FAIL;
-}
-
-#endif // !defined(__APPLE__)
-
-/**********************************************************************\
- * Creates a desktop or .NET Core instance of the runtime class
-\**********************************************************************/
-HRESULT Runtime::CreateInstance(RuntimeConfiguration configuration, Runtime **ppRuntime)
-{
-    PCSTR runtimeModuleName = ::GetRuntimeModuleName(configuration);
-    ULONG moduleIndex = 0;
-    ULONG64 moduleAddress = 0;
-    ULONG64 moduleSize = 0;
-    RuntimeInfo* runtimeInfo = nullptr;
-    HRESULT hr = S_OK;
-
-    if (*ppRuntime == nullptr)
-    {
-        // Check if the normal runtime module (coreclr.dll, libcoreclr.so, etc.) is loaded
-        hr = g_ExtSymbols->GetModuleByModuleName(runtimeModuleName, 0, &moduleIndex, &moduleAddress);
-#if !defined(__APPLE__)
-        if (FAILED(hr))
-        {
-            // If the standard runtime module isn't loaded, try looking for a single-file program
-            if (configuration == IRuntime::UnixCore)
-            {
-                hr = GetSingleFileInfo(&moduleIndex, &moduleAddress, &runtimeInfo);
-            }
-        }
-#endif // !defined(__APPLE__)
-
-        // If the previous operations were successful, get the size of the runtime module
-        if (SUCCEEDED(hr))
-        {
-#ifdef FEATURE_PAL
-            hr = g_ExtServices2->GetModuleInfo(moduleIndex, nullptr, &moduleSize);
-#else
-            _ASSERTE(moduleAddress != 0);
-            DEBUG_MODULE_PARAMETERS params;
-            hr = g_ExtSymbols->GetModuleParameters(1, &moduleAddress, 0, &params);
-            if (SUCCEEDED(hr))
-            {
-                moduleSize = params.Size;
-            }
-#endif
-        }
-
-        // If the previous operations were successful, create the Runtime instance
-        if (SUCCEEDED(hr))
-        {
-            if (moduleSize > 0) 
-            {
-                *ppRuntime = new Runtime(configuration, moduleIndex, moduleAddress, moduleSize, runtimeInfo);
-                OnUnloadTask::Register(CleanupRuntimes);
-            }
-            else 
-            {
-                ExtOut("Runtime (%s) module size == 0\n", runtimeModuleName);
-                hr = E_INVALIDARG;
-            }
-        }
-    }
-    return hr;
-}
-
-/**********************************************************************\
- * Creates an instance of the runtime class. First it attempts to create
- * the .NET Core instance and if that fails, it will try to create the
- * desktop CLR instance.  If both runtimes exists in the process or dump
- * this runtime only creates the .NET Core version and leaves creating
- * the desktop instance on demand in SwitchRuntime.
-\**********************************************************************/
-HRESULT Runtime::CreateInstance()
-{
-    HRESULT hr = S_OK;
-    if (g_pRuntime == nullptr)
-    {
-        hr = CreateInstance(IRuntime::Core, &s_netcore);
-#ifdef FEATURE_PAL
-        g_pRuntime = s_netcore;
-#else
-        if (FAILED(hr))
-        {
-            hr = CreateInstance(IRuntime::UnixCore, &s_netcore);
-        }
-        if (FAILED(hr))
-        {
-            hr = CreateInstance(IRuntime::WindowsDesktop, &s_desktop);
-        }
-        g_pRuntime = s_netcore != nullptr ? s_netcore : s_desktop;
-#endif
-    }
-    return hr;
-}
-
-/**********************************************************************\
- * Switches between the .NET Core and desktop runtimes (if both 
- * loaded). Creates the desktop CLR runtime instance on demand.
-\**********************************************************************/
-#ifndef FEATURE_PAL
-bool Runtime::SwitchRuntime(bool desktop)
-{
-    if (desktop) {
-        CreateInstance(IRuntime::WindowsDesktop, &s_desktop);
-    }
-    IRuntime* runtime = desktop ? s_desktop : s_netcore;
-    if (runtime == nullptr) {
-        return false;
-    }
-    g_pRuntime = runtime;
-    return true;
-}
-#endif
-
-/**********************************************************************\
- * Cleans up the runtime instances
-\**********************************************************************/
-void Runtime::CleanupRuntimes()
-{
-    if (s_netcore != nullptr)
-    {
-        delete s_netcore;
-        s_netcore = nullptr;
-    }
-#ifndef FEATURE_PAL
-    if (s_desktop != nullptr)
-    {
-        delete s_desktop;
-        s_desktop = nullptr;
-    }
-#endif
-    g_pRuntime = nullptr;
-}
-
-/**********************************************************************\
- * Destroys the runtime instance
-\**********************************************************************/
-Runtime::~Runtime()
-{
-    if (m_runtimeDirectory != nullptr)
-    {
-        free((void*)m_runtimeDirectory);
-        m_runtimeDirectory = nullptr;
-    }
-    if (m_dacFilePath != nullptr)
-    {
-        free((void*)m_dacFilePath);
-        m_dacFilePath = nullptr;
-    }
-    if (m_dbiFilePath != nullptr)
-    {
-        free((void*)m_dbiFilePath);
-        m_dbiFilePath = nullptr;
-    }
-    if (m_pCorDebugProcess != NULL)
-    {
-        m_pCorDebugProcess->Detach();
-        m_pCorDebugProcess->Release();
-        m_pCorDebugProcess = nullptr;
-    }
-    if (m_clrDataProcess != nullptr)
-    {
-        m_clrDataProcess->Release();
-        m_clrDataProcess = nullptr;
-    }
-}
-
-/**********************************************************************\
- * Flushes DAC caches
-\**********************************************************************/
-void Runtime::Flush()
-{
-    if (s_netcore != nullptr && s_netcore->m_clrDataProcess != nullptr)
-    {
-        s_netcore->m_clrDataProcess->Flush();
-    }
-#ifndef FEATURE_PAL
-    if (s_desktop != nullptr && s_desktop->m_clrDataProcess != nullptr)
-    {
-        s_desktop->m_clrDataProcess->Flush();
-    }
-#endif
-}
-
-/**********************************************************************\
- * Returns the runtime directory of the target
-\**********************************************************************/
-LPCSTR Runtime::GetRuntimeDirectory()
-{
-    if (m_runtimeDirectory == nullptr)
-    {
-        if (g_runtimeModulePath != nullptr)
-        {
-            m_runtimeDirectory = _strdup(g_runtimeModulePath);
-        }
-        else 
-        {
-            ArrayHolder<char> szModuleName = new char[MAX_LONGPATH + 1];
-            HRESULT hr = g_ExtSymbols->GetModuleNames(m_index, 0, szModuleName, MAX_LONGPATH, NULL, NULL, 0, NULL, NULL, 0, NULL);
-            if (FAILED(hr))
-            {
-                ExtErr("Error: Failed to get runtime module name\n");
-                return nullptr;
-            }
-            if (GetFileAttributesA(szModuleName) == INVALID_FILE_ATTRIBUTES)
-            {
-                hr = HRESULT_FROM_WIN32(GetLastError());
-                ExtDbgOut("Error: Runtime module %s doesn't exist %08x\n", szModuleName.GetPtr(), hr);
-                return nullptr;
-            }
-            // Parse off the file name
-            char* lastSlash = strrchr(szModuleName, GetTargetDirectorySeparatorW());
-            if (lastSlash != nullptr)
-            {
-                *lastSlash = '\0';
-            }
-            m_runtimeDirectory = _strdup(szModuleName.GetPtr());
-        }
-    }
-    return m_runtimeDirectory;
-}
-
-/**********************************************************************\
- * Returns the DAC module path to the rest of SOS.
-\**********************************************************************/
-LPCSTR Runtime::GetDacFilePath()
-{
-    // If the DAC path hasn't been set by the symbol download support, use the one in the runtime directory.
-    if (m_dacFilePath == nullptr)
-    {
-        LPCSTR directory = GetRuntimeDirectory();
-        if (directory != nullptr)
-        {
-            std::string dacModulePath(directory);
-            dacModulePath.append(DIRECTORY_SEPARATOR_STR_A);
-            dacModulePath.append(GetDacDllName());
-#ifdef FEATURE_PAL
-            // If DAC file exists in the runtime directory
-            if (access(dacModulePath.c_str(), F_OK) == 0)
-#endif
-            {
-#if defined(__linux__)
-                // We are creating a symlink to the DAC in a temp directory
-                // where libcoreclrtraceptprovider.so doesn't exist so it 
-                // doesn't get loaded by the DAC causing a LTTng-UST exception.
-                //
-                // Issue #https://github.com/dotnet/coreclr/issues/20205
-                LPCSTR tmpPath = GetTempDirectory();
-                if (tmpPath != nullptr) 
-                {
-                    std::string dacSymLink(tmpPath);
-                    dacSymLink.append(NETCORE_DAC_DLL_NAME_A);
-
-                    // Check if the DAC file already exists in the temp directory because
-                    // of a "loadsymbols" command which downloads everything.
-                    if (access(dacSymLink.c_str(), F_OK) == 0)
-                    {
-                        dacModulePath.assign(dacSymLink);
-                    }
-                    else
-                    {
-                        int error = symlink(dacModulePath.c_str(), dacSymLink.c_str());
-                        if (error == 0)
-                        {
-                            dacModulePath.assign(dacSymLink);
-                        }
-                        else
-                        {
-                            ExtErr("symlink(%s, %s) FAILED %s\n", dacModulePath.c_str(), dacSymLink.c_str(), strerror(errno));
-                        }
-                    }
-                }
-#endif
-                m_dacFilePath = _strdup(dacModulePath.c_str());
-            }
-        }
-
-        if (m_dacFilePath == nullptr)
-        {
-            // Attempt to only load the DAC/DBI modules
-            LoadRuntimeModules();
-        }
-    }
-    return m_dacFilePath;
-}
-
-/**********************************************************************\
- * Returns the DBI module path to the rest of SOS
-\**********************************************************************/
-LPCSTR Runtime::GetDbiFilePath()
-{
-    if (m_dbiFilePath == nullptr)
-    {
-        LPCSTR directory = GetRuntimeDirectory();
-        if (directory != nullptr)
-        {
-            std::string dbiModulePath(directory);
-            dbiModulePath.append(DIRECTORY_SEPARATOR_STR_A);
-            dbiModulePath.append(NET_DBI_DLL_NAME_A);
-#ifdef FEATURE_PAL
-            // If DBI file exists in the runtime directory
-            if (access(dbiModulePath.c_str(), F_OK) == 0)
-#endif
-            {
-                m_dbiFilePath = _strdup(dbiModulePath.c_str());
-            }
-        }
-
-        if (m_dbiFilePath == nullptr)
-        {
-            // Attempt to only load the DAC/DBI modules
-            LoadRuntimeModules();
-        }
-    }
-    return m_dbiFilePath;
-}
-
-/**********************************************************************\
- * Creates an instance of the DAC clr data process
-\**********************************************************************/
-HRESULT Runtime::GetClrDataProcess(IXCLRDataProcess** ppClrDataProcess)
-{
-    if (m_clrDataProcess == nullptr)
-    {
-        *ppClrDataProcess = nullptr;
-
-        LPCSTR dacFilePath = GetDacFilePath();
-        if (dacFilePath == nullptr)
-        {
-            return CORDBG_E_NO_IMAGE_AVAILABLE;
-        }
-        HMODULE hdac = LoadLibraryA(dacFilePath);
-        if (hdac == NULL)
-        {
-            ExtDbgOut("LoadLibrary(%s) FAILED %08x\n", dacFilePath, HRESULT_FROM_WIN32(GetLastError()));
-            return CORDBG_E_MISSING_DEBUGGER_EXPORTS;
-        }
-        PFN_CLRDataCreateInstance pfnCLRDataCreateInstance = (PFN_CLRDataCreateInstance)GetProcAddress(hdac, "CLRDataCreateInstance");
-        if (pfnCLRDataCreateInstance == nullptr)
-        {
-            FreeLibrary(hdac);
-            return CORDBG_E_MISSING_DEBUGGER_EXPORTS;
-        }
-        ICLRDataTarget *target = new DataTarget(GetModuleAddress());
-        HRESULT hr = pfnCLRDataCreateInstance(__uuidof(IXCLRDataProcess), target, (void**)&m_clrDataProcess);
-        if (FAILED(hr))
-        {
-            m_clrDataProcess = nullptr;
-            return hr;
-        }
-        ULONG32 flags = 0;
-        m_clrDataProcess->GetOtherNotificationFlags(&flags);
-        flags |= (CLRDATA_NOTIFY_ON_MODULE_LOAD | CLRDATA_NOTIFY_ON_MODULE_UNLOAD | CLRDATA_NOTIFY_ON_EXCEPTION);
-        m_clrDataProcess->SetOtherNotificationFlags(flags);
-    }
-    *ppClrDataProcess = m_clrDataProcess;
-    return S_OK;
-}
-
-/**********************************************************************\
- * Loads and initializes the public ICorDebug interfaces. This should be 
- * called at least once per debugger stop state to ensure that the 
- * interface is available and that it doesn't hold stale data. Calling
- * it more than once isn't an error, but does have perf overhead from 
- * needlessly flushing memory caches.
-\**********************************************************************/
-HRESULT Runtime::GetCorDebugInterface(ICorDebugProcess** ppCorDebugProcess)
-{
-    HMODULE hModule = NULL;
-    HRESULT hr;
-    ToRelease<ICLRDebugging> pClrDebugging;
-
-    // We may already have an ICorDebug instance we can use
-    if (m_pCorDebugProcess != nullptr)
-    {
-        // ICorDebugProcess4 is currently considered a private experimental interface on ICorDebug, it might go away so
-        // we need to be sure to handle its absence gracefully
-        ToRelease<ICorDebugProcess4> pProcess4 = NULL;
-        if (SUCCEEDED(m_pCorDebugProcess->QueryInterface(__uuidof(ICorDebugProcess4), (void**)&pProcess4)))
-        {
-            // FLUSH_ALL is more expensive than PROCESS_RUNNING, but this allows us to be safe even if things
-            // like IDNA are in use where we might be looking at non-sequential snapshots of process state
-            if (SUCCEEDED(pProcess4->ProcessStateChanged(FLUSH_ALL)))
-            {
-                // We already have an ICorDebug instance loaded and flushed, nothing more to do
-                *ppCorDebugProcess = m_pCorDebugProcess;
-                return S_OK;
-            }
-        }
-
-        // This is a very heavy handed way of reseting
-        m_pCorDebugProcess->Detach();
-        m_pCorDebugProcess->Release();
-        m_pCorDebugProcess = nullptr;
-    }
-
-    // SOS now has a statically linked version of the loader code that is normally found in mscoree/mscoreei.dll
-    // Its not much code and takes a big step towards 0 install dependencies
-    // Need to pick the appropriate SKU of CLR to detect
-#if defined(FEATURE_CORESYSTEM)
-    GUID skuId = CLR_ID_ONECORE_CLR;
-#else
-    GUID skuId = CLR_ID_CORECLR;
-#endif
-#ifndef FEATURE_PAL
-    if (GetRuntimeConfiguration() == IRuntime::WindowsDesktop)
-    {
-        skuId = CLR_ID_V4_DESKTOP;
-    }
-#endif
-    CLRDebuggingImpl* pDebuggingImpl = new CLRDebuggingImpl(skuId, IsWindowsTarget());
-    hr = pDebuggingImpl->QueryInterface(IID_ICLRDebugging, (LPVOID *)&pClrDebugging);
-    if (FAILED(hr))
-    {
-        delete pDebuggingImpl;
-        return hr;
-    }
-
-    ToRelease<ICorDebugMutableDataTarget> pCorDebugDataTarget = new CorDebugDataTarget;
-    pCorDebugDataTarget->AddRef();
-
-    ToRelease<ICLRDebuggingLibraryProvider> pCorDebugLibraryProvider = new CorDebugLibraryProvider(this);
-    pCorDebugLibraryProvider->AddRef();
-
-    CLR_DEBUGGING_VERSION clrDebuggingVersionRequested = {0};
-    clrDebuggingVersionRequested.wMajor = 4;
-
-    CLR_DEBUGGING_VERSION clrDebuggingVersionActual = {0};
-
-    CLR_DEBUGGING_PROCESS_FLAGS clrDebuggingFlags = (CLR_DEBUGGING_PROCESS_FLAGS)0;
-
-    ToRelease<IUnknown> pUnkProcess;
-    hr = pClrDebugging->OpenVirtualProcess(
-        GetModuleAddress(),
-        pCorDebugDataTarget,
-        pCorDebugLibraryProvider,
-        &clrDebuggingVersionRequested,
-        IID_ICorDebugProcess,
-        &pUnkProcess,
-        &clrDebuggingVersionActual,
-        &clrDebuggingFlags);
-
-    if (FAILED(hr)) {
-        return hr;
-    }
-    hr = pUnkProcess->QueryInterface(IID_ICorDebugProcess, (PVOID*)&m_pCorDebugProcess);
-    if (FAILED(hr)) {
-        return hr;
-    }
-    *ppCorDebugProcess = m_pCorDebugProcess;
-    return hr;
-}
-
-/**********************************************************************\
- * Displays the runtime internal status
-\**********************************************************************/
-void Runtime::DisplayStatus()
-{
-    ExtOut("%s runtime at %08llx size %08llx\n", GetRuntimeConfigurationName(GetRuntimeConfiguration()), m_address, m_size);
-    if (m_runtimeInfo != nullptr) {
-        ArrayHolder<char> szModuleName = new char[MAX_LONGPATH + 1];
-        HRESULT hr = g_ExtSymbols->GetModuleNames(m_index, 0, szModuleName, MAX_LONGPATH, NULL, NULL, 0, NULL, NULL, 0, NULL);
-        if (SUCCEEDED(hr)) {
-            ExtOut("Single-file module path: %s\n", szModuleName.GetPtr());
-        }
-    }
-    if (m_runtimeDirectory != nullptr) {
-        ExtOut("Runtime directory: %s\n", m_runtimeDirectory);
-    }
-    if (m_dacFilePath != nullptr) {
-        ExtOut("DAC file path: %s\n", m_dacFilePath);
-    }
-    if (m_dbiFilePath != nullptr) {
-        ExtOut("DBI file path: %s\n", m_dbiFilePath);
-    }
-}
-
-extern bool g_symbolStoreInitialized;
-extern HRESULT InitializeSymbolStore();
-extern int ReadMemoryForSymbols(ULONG64 address, uint8_t* buffer, int cb);
-
-/**********************************************************************\
- * Attempt to download the runtime modules (runtime, DAC and DBI)
-\**********************************************************************/
-void Runtime::LoadRuntimeModules()
-{
-    HRESULT hr = InitializeSymbolStore();
-    if (SUCCEEDED(hr) && g_symbolStoreInitialized)
-    {
-        if (m_runtimeInfo != nullptr)
-        {
-            _ASSERTE(g_SOSNetCoreCallbacks.LoadNativeSymbolsFromIndexDelegate != nullptr);
-            g_SOSNetCoreCallbacks.LoadNativeSymbolsFromIndexDelegate(
-                SymbolFileCallback,
-                this,
-                GetRuntimeConfiguration(),
-                GetRuntimeDllName(),
-                true,                                   // special keys (runtime, DAC and DBI)
-                m_runtimeInfo->RuntimeModuleIndex[0],   // size of module index
-                &m_runtimeInfo->RuntimeModuleIndex[1]); // beginning of index 
-        }
-        else
-        {
-            ArrayHolder<char> moduleFilePath = new char[MAX_LONGPATH + 1];
-            hr = g_ExtSymbols->GetModuleNames(m_index, 0, moduleFilePath, MAX_LONGPATH, NULL, NULL, 0, NULL, NULL, 0, NULL);
-            if (SUCCEEDED(hr))
-            {
-                _ASSERTE(g_SOSNetCoreCallbacks.LoadNativeSymbolsDelegate != nullptr);
-                g_SOSNetCoreCallbacks.LoadNativeSymbolsDelegate(
-                    SymbolFileCallback,
-                    this,
-                    GetRuntimeConfiguration(),
-                    moduleFilePath,
-                    m_address,
-                    (int)m_size,
-                    ReadMemoryForSymbols);
-            }
-        }
-    }
-}
-
-/**********************************************************************\
- * Called by LoadRuntimeModules to set the DAC and DBI file paths
-\**********************************************************************/
-void Runtime::SymbolFileCallback(const char* moduleFileName, const char* symbolFilePath)
-{
-    if (strcmp(moduleFileName, GetRuntimeDllName()) == 0) {
-        return;
-    }
-    if (strcmp(moduleFileName, GetDacDllName()) == 0) {
-        SetDacFilePath(symbolFilePath);
-        return;
-    }
-    if (strcmp(moduleFileName, NET_DBI_DLL_NAME_A) == 0) {
-        SetDbiFilePath(symbolFilePath);
-        return;
-    }
-}
-
-#ifndef FEATURE_PAL
-
-/**********************************************************************\
- * Internal function to load and check the version of the module
-\**********************************************************************/
-HMODULE LoadLibraryAndCheck(
-    PCWSTR filename,
-    DWORD timestamp,
-    DWORD filesize)
-{
-    HMODULE hModule = LoadLibraryExW(
-        filename,
-        NULL,                               //  __reserved
-        LOAD_WITH_ALTERED_SEARCH_PATH);     // Ensure we check the dir in wszFullPath first
-
-    if (hModule == NULL)
-    {
-        ExtOut("Unable to load '%S'. hr = 0x%x.\n", filename, HRESULT_FROM_WIN32(GetLastError()));
-        return NULL;
-    }
-    
-    // Did we load the right one?
-    MODULEINFO modInfo = {0};
-    if (!GetModuleInformation(
-        GetCurrentProcess(),
-        hModule,
-        &modInfo,
-        sizeof(modInfo)))
-    {
-        ExtOut("Failed to read module information for '%S'. hr = 0x%x.\n", filename, HRESULT_FROM_WIN32(GetLastError()));
-        FreeLibrary(hModule);
-        return NULL;
-    }
-
-    IMAGE_DOS_HEADER * pDOSHeader = (IMAGE_DOS_HEADER *) modInfo.lpBaseOfDll;
-    IMAGE_NT_HEADERS * pNTHeaders = (IMAGE_NT_HEADERS *) (((LPBYTE) modInfo.lpBaseOfDll) + pDOSHeader->e_lfanew);
-    DWORD dwSizeActual = pNTHeaders->OptionalHeader.SizeOfImage;
-    DWORD dwTimeStampActual = pNTHeaders->FileHeader.TimeDateStamp;
-    if ((dwSizeActual != filesize) || (dwTimeStampActual != timestamp))
-    {
-        ExtOut("Found '%S', but it does not match the CLR being debugged.\n", filename);
-        ExtOut("Size: Expected '0x%x', Actual '0x%x'\n", filesize, dwSizeActual);
-        ExtOut("Time stamp: Expected '0x%x', Actual '0x%x'\n", timestamp, dwTimeStampActual);
-        FreeLibrary(hModule);
-        return NULL;
-    }
-
-    return hModule;
-}
-
-#endif // FEATURE_PAL
diff --git a/src/SOS/Strike/runtime.h b/src/SOS/Strike/runtime.h
deleted file mode 100644 (file)
index 5ad139f..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#ifndef __runtime_h__
-#define __runtime_h__
-
-#include <runtimeinfo.h>
-
-#ifdef FEATURE_PAL
-
-#define NETCORE_DAC_MODULE_NAME_W       MAKEDLLNAME_W(W("mscordaccore"))
-#define NETCORE_DAC_MODULE_NAME_A       MAKEDLLNAME_A("mscordaccore")
-#define NETCORE_DAC_DLL_NAME_W          NETCORE_DAC_MODULE_NAME_W
-#define NETCORE_DAC_DLL_NAME_A          NETCORE_DAC_MODULE_NAME_A
-
-#define NET_DBI_MODULE_NAME_W           MAKEDLLNAME_W(W("mscordbi"))
-#define NET_DBI_MODULE_NAME_A           MAKEDLLNAME_A("mscordbi")
-#define NET_DBI_DLL_NAME_W              NET_DBI_MODULE_NAME_W       
-#define NET_DBI_DLL_NAME_A              NET_DBI_MODULE_NAME_A       
-
-#else
-
-#define NETCORE_DAC_MODULE_NAME_W       W("mscordaccore")
-#define NETCORE_DAC_MODULE_NAME_A       "mscordaccore"
-#define NETCORE_DAC_DLL_NAME_W          MAKEDLLNAME_W(NETCORE_DAC_MODULE_NAME_W)
-#define NETCORE_DAC_DLL_NAME_A          MAKEDLLNAME_A(NETCORE_DAC_MODULE_NAME_A)
-
-#define NET_DBI_MODULE_NAME_W           W("mscordbi")
-#define NET_DBI_MODULE_NAME_A           "mscordbi"
-#define NET_DBI_DLL_NAME_W              MAKEDLLNAME_W(W("mscordbi"))
-#define NET_DBI_DLL_NAME_A              MAKEDLLNAME_A("mscordbi")
-
-#endif // FEATURE_PAL
-
-#define DESKTOP_DAC_MODULE_NAME_W       W("mscordacwks")
-#define DESKTOP_DAC_MODULE_NAME_A       "mscordacwks"
-#define DESKTOP_DAC_DLL_NAME_W          MAKEDLLNAME_W(W("mscordacwks"))
-#define DESKTOP_DAC_DLL_NAME_A          MAKEDLLNAME_A("mscordacwks")
-
-/**********************************************************************\
- * Runtime interface
-\**********************************************************************/
-class IRuntime
-{
-public:
-    enum RuntimeConfiguration
-    {
-        WindowsDesktop      = 0,
-        WindowsCore         = 1,
-        UnixCore            = 2,
-        OSXCore             = 3,
-        ConfigurationEnd,
-#ifdef FEATURE_PAL
-#ifdef __APPLE__
-        Core = OSXCore
-#else
-        Core = UnixCore
-#endif
-#else
-        Core = WindowsCore
-#endif
-    };
-
-    // Returns the runtime configuration
-    virtual RuntimeConfiguration GetRuntimeConfiguration() const = 0;
-
-    // Returns the runtime module index
-    virtual ULONG GetModuleIndex() const = 0;
-
-    // Returns the runtime module base address
-    virtual ULONG64 GetModuleAddress() const = 0;
-
-    // Returns the runtime module size
-    virtual ULONG64 GetModuleSize() const = 0;
-
-    // Returns the directory of the runtime file
-    virtual LPCSTR GetRuntimeDirectory() = 0;
-
-    // Returns the DAC module path to the rest of SOS
-    virtual LPCSTR GetDacFilePath() = 0;
-
-    // Returns the DBI module path to the rest of SOS
-    virtual LPCSTR GetDbiFilePath() = 0;
-
-    // Returns the DAC data process instance
-    virtual HRESULT GetClrDataProcess(IXCLRDataProcess** ppClrDataProcess) = 0;
-
-    // Initializes and returns the DBI debugging interface instance
-    virtual HRESULT GetCorDebugInterface(ICorDebugProcess** ppCorDebugProcess) = 0;
-
-    // Displays the runtime internal status
-    virtual void DisplayStatus() = 0;
-};
-
-extern LPCSTR g_runtimeModulePath;
-extern IRuntime* g_pRuntime;
-
-// Returns the runtime configuration as a string
-inline static const char* GetRuntimeConfigurationName(IRuntime::RuntimeConfiguration config)
-{
-    static const char* name[IRuntime::ConfigurationEnd] = {
-        "Desktop",
-        ".NET Core (Windows)",
-        ".NET Core (Unix)",
-        ".NET Core (Mac)"
-    };
-    return (config < IRuntime::ConfigurationEnd) ? name[config] : nullptr;
-}
-
-// Returns the runtime module DLL name (clr.dll, coreclr.dll, libcoreclr.so, libcoreclr.dylib)
-inline static const char* GetRuntimeDllName(IRuntime::RuntimeConfiguration config)
-{
-    static const char* name[IRuntime::ConfigurationEnd] = {
-        "clr.dll",
-        "coreclr.dll",
-        "libcoreclr.so",
-        "libcoreclr.dylib"
-    };
-    return (config < IRuntime::ConfigurationEnd) ? name[config] : nullptr;
-}
-
-// Returns the runtime module name (clr, coreclr, libcoreclr.so, libcoreclr.dylib).
-inline static const char* GetRuntimeModuleName(IRuntime::RuntimeConfiguration config)
-{
-#ifdef FEATURE_PAL
-    return GetRuntimeDllName(config);
-#else
-    // On a windows host the module name does not include the extension.
-    static const char* name[IRuntime::ConfigurationEnd] = {
-        "clr",
-        "coreclr",
-        "libcoreclr",
-        "libcoreclr"
-    };
-    return (config < IRuntime::ConfigurationEnd) ? name[config] : nullptr;
-#endif
-}
-
-// Returns the runtime module name (clr, coreclr, libcoreclr.so, libcoreclr.dylib).
-inline const char* GetRuntimeModuleName()
-{
-    return GetRuntimeModuleName(g_pRuntime->GetRuntimeConfiguration());
-}
-
-// Returns the runtime module DLL name (clr.dll, coreclr.dll, libcoreclr.so, libcoreclr.dylib)
-inline const char* GetRuntimeDllName()
-{
-    return GetRuntimeDllName(g_pRuntime->GetRuntimeConfiguration());
-}
-
-// Returns the DAC module name (mscordacwks, mscordaccore, libmscordaccore.so, libmscordaccore.dylib) 
-inline const char* GetDacModuleName()
-{
-    return (g_pRuntime->GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_MODULE_NAME_A : NETCORE_DAC_MODULE_NAME_A;
-}
-
-// Returns the DAC module name (mscordacwks.dll, mscordaccore.dll, libmscordaccore.so, libmscordaccore.dylib) 
-inline const char* GetDacDllName()
-{
-    return (g_pRuntime->GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_DLL_NAME_A : NETCORE_DAC_DLL_NAME_A;
-}
-
-inline bool IsWindowsTarget(IRuntime::RuntimeConfiguration config)
-{
-    return (config == IRuntime::WindowsCore) || (config == IRuntime::WindowsDesktop);
-}
-
-inline bool IsWindowsTarget()
-{
-    return IsWindowsTarget(g_pRuntime->GetRuntimeConfiguration());
-}
-
-/**********************************************************************\
- * Local Runtime interface implementation
-\**********************************************************************/
-class Runtime : public IRuntime
-{
-private:
-    RuntimeConfiguration m_configuration;
-    ULONG m_index;
-    ULONG64 m_address;
-    ULONG64 m_size;
-    RuntimeInfo* m_runtimeInfo;
-    LPCSTR m_runtimeDirectory;
-    LPCSTR m_dacFilePath;
-    LPCSTR m_dbiFilePath;
-    IXCLRDataProcess* m_clrDataProcess;
-    ICorDebugProcess* m_pCorDebugProcess;
-
-    static Runtime* s_netcore;
-#ifndef FEATURE_PAL
-    static Runtime* s_desktop;
-#endif
-    static RuntimeConfiguration s_configuration;
-    static LPCSTR s_dacFilePath;
-    static LPCSTR s_dbiFilePath;
-
-    Runtime(RuntimeConfiguration configuration, ULONG index, ULONG64 address, ULONG64 size, RuntimeInfo* runtimeInfo) :
-        m_configuration(configuration),
-        m_index(index),
-        m_address(address),
-        m_size(size),
-        m_runtimeInfo(runtimeInfo),
-        m_runtimeDirectory(nullptr),
-        m_dacFilePath(nullptr),
-        m_dbiFilePath(nullptr),
-        m_clrDataProcess(nullptr),
-        m_pCorDebugProcess(nullptr)
-    {
-        _ASSERTE(index != -1);
-        _ASSERTE(address != 0);
-        _ASSERTE(size != 0);
-        if (configuration == s_configuration) {
-            SetDacFilePath(s_dacFilePath);
-            SetDbiFilePath(s_dbiFilePath);
-        }
-    }
-
-    virtual Runtime::~Runtime();
-
-    static HRESULT CreateInstance(RuntimeConfiguration configuration, Runtime** ppRuntime);
-
-    void LoadRuntimeModules();
-
-    void SymbolFileCallback(const char* moduleFileName, const char* symbolFilePath);
-
-    static void SymbolFileCallback(void* param, const char* moduleFileName, const char* symbolFilePath)
-    {
-        ((Runtime*)param)->SymbolFileCallback(moduleFileName, symbolFilePath);
-    }
-
-    void SetDacFilePath(LPCSTR dacFilePath)
-    { 
-        if (m_dacFilePath == nullptr && dacFilePath != nullptr) {
-            m_dacFilePath = _strdup(dacFilePath);
-        }
-    }
-
-    void SetDbiFilePath(LPCSTR dbiFilePath) 
-    { 
-        if (m_dbiFilePath == nullptr && dbiFilePath != nullptr) {
-            m_dbiFilePath = _strdup(dbiFilePath);
-        }
-    }
-
-public:
-    static HRESULT CreateInstance();
-
-    static void CleanupRuntimes();
-
-#ifndef FEATURE_PAL
-    static bool SwitchRuntime(bool desktop);
-#endif
-
-    static void SetDacDbiPath(bool isDesktop, LPCSTR dacFilePath, LPCSTR dbiFilePath)
-    {
-        s_configuration = isDesktop ? IRuntime::WindowsDesktop : IRuntime::Core;
-        if (dacFilePath != nullptr) {
-            s_dacFilePath = _strdup(dacFilePath);
-        }
-        if (dbiFilePath != nullptr) {
-            s_dbiFilePath = _strdup(dbiFilePath);
-        }
-    }
-
-    static void Flush();
-
-    virtual RuntimeConfiguration GetRuntimeConfiguration() const { return m_configuration; }
-
-    virtual ULONG GetModuleIndex() const { return m_index; }
-
-    virtual ULONG64 GetModuleAddress() const { return m_address; }
-
-    virtual ULONG64 GetModuleSize() const { return m_size; }
-
-    LPCSTR GetRuntimeDirectory();
-
-    LPCSTR GetDacFilePath();
-
-    LPCSTR GetDbiFilePath();
-
-    HRESULT GetClrDataProcess(IXCLRDataProcess** ppClrDataProcess);
-
-    HRESULT GetCorDebugInterface(ICorDebugProcess** ppCorDebugProcess);
-
-    void DisplayStatus();
-
-    // Returns the runtime module DLL name (clr.dll, coreclr.dll, libcoreclr.so, libcoreclr.dylib)
-    inline const char* GetRuntimeDllName() const
-    {
-        return ::GetRuntimeDllName(GetRuntimeConfiguration());
-    }
-
-    // Returns the DAC module name (mscordacwks.dll, mscordaccore.dll, libmscordaccore.so, libmscordaccore.dylib) 
-    inline const char* GetDacDllName() const
-    {
-        return (GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_DLL_NAME_A : NETCORE_DAC_DLL_NAME_A;
-    }
-
-    // Returns the DAC module name (mscordacwks, mscordaccore, libmscordaccore.so, libmscordaccore.dylib) 
-    inline const WCHAR* GetDacModuleNameW() const
-    {
-        return (GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_MODULE_NAME_W : NETCORE_DAC_MODULE_NAME_W;
-    }
-
-    // Returns the DAC module name (mscordacwks.dll, mscordaccore.dll, libmscordaccore.so, libmscordaccore.dylib) 
-    inline const WCHAR* GetDacDllNameW() const
-    {
-        return (GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_DLL_NAME_W : NETCORE_DAC_DLL_NAME_W;
-    }
-};
-
-#endif // __runtime_h__
index 07ce5c3bb3e3bc229e6544c2d69eb4f8a8de1b3b..a5bdc5ccf30cc821e3e24f92af59977e70ae9fde 100644 (file)
@@ -217,6 +217,8 @@ EXPORTS
     procinfo=ProcInfo
     SOSStatus
     sosstatus=SOSStatus
+
+    runtimes
     VerifyStackTrace
     WatsonBuckets
 
index e7e516d4e9daca1e768b3596b911fb71f54600b4..cc733729eeb68fb321208d7cd81705b79834d0b1 100644 (file)
@@ -52,6 +52,7 @@ SetClrPath
 SetSymbolServer
 SOSFlush
 SOSStatus
+runtimes
 SuppressJitOptimization
 SyncBlk
 Threads
index 20c3ca5b511941443744f748217c3af7fe3a5947..c75bf42eb5dfcc8652d45d15eaae9e71f0f165c6 100644 (file)
@@ -2661,6 +2661,7 @@ COMMAND: setsymbolserver.
 -mi - Use the internal symweb symbol server.
 -disable - Disable symbol download support.
 -directory - Directory to search for symbols. Can be more than one.
+-timeout - Specify the symbol server timeout in minutes
 -pat - Access token to the authenticated server.
 -cache - Specific a symbol cache directory. The default is %%TEMP%%\SymbolCache if not specified.
 -log - Enable symbol download logging.
@@ -2675,11 +2676,9 @@ To disable downloading or clear the current SOS symbol settings allowing new sym
 \\
 
 COMMAND: sosstatus.
-!SOSStatus [-netfx] [-netcore] [-reset]
+!SOSStatus [-reset]
 
--netfx   - switch to the desktop .NET Framework runtime if loaded.
--netcore - switch to the .NET Core runtime if loaded.
--reset   - reset all the cached internal SOS state.
+-reset - reset all the cached internal SOS state.
 
 Display internal SOS status, reset the internal cached state, or change between the desktop .NET framework
 or .NET Core runtimes when both are loaded in the process or dump.
@@ -2691,7 +2690,7 @@ or .NET Core runtimes when both are loaded in the process or dump.
     DBI file path: C:\Users\mikem\AppData\Local\Temp\SymbolCache\mscordbi.dll/5d0707425c2000/mscordbi.dll
     Cache: C:\Users\mikem\AppData\Local\Temp\SymbolCache
     Server: http://msdl.microsoft.com/download/symbols/
-//
+\\
 
 COMMAND: setclrpath.
 !setclrpath <path-to-runtime>
@@ -2701,4 +2700,19 @@ on another machine or for triage dumps because there are no module paths include
 runtime directory.
 
     0:000> !setclrpath "C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.0"
-//
\ No newline at end of file
+\\
+
+COMMAND: runtimes.
+runtimes [-netfx] [-netcore]
+
+-netfx   - switch to the desktop .NET Framework runtime if loaded.
+-netcore - switch to the .NET Core runtime if loaded.
+
+List and select the .NET runtimes in the target process.
+\\
+
+COMMAND: logging.
+logging [enable] [disable]
+
+Enables or disables the internal trace logging.
+\\
index 740189371d604a1a8d4405dd6d9daf1441d4d46a..2e1bcf2044f3a6e78325ce0d17da2db4acd017d0 100644 (file)
@@ -1936,15 +1936,15 @@ You can use the "dotnet --info" in a command shell to find the path of an instal
 COMMAND: setsymbolserver.
 COMMAND: loadsymbols.
 COMMAND: sympath.
-SetSymbolServer [-ms] [-disable] [-log]  [-loadsymbols] [-cache <cache-path>] [-directory <search-directory>] [-pat <token>] [-sympath <windows-symbol-path>] [<symbol-server-URL>]
+SetSymbolServer [-ms] [-disable] [-log]  [-loadsymbols] [-cache <cache-path>] [-directory <search-directory>] [-timeout <minutes> ] [-pat <token>] [-sympath <windows-symbol-path>] [<symbol-server-URL>]
 
 -ms - Use the public Microsoft symbol server.
 -disable - Disable symbol download support.
 -directory - Directory to search for symbols. Can be more than one.
+-timeout - Specify the symbol server timeout in minutes
 -pat - Access token to the authenticated server.
 -cache - Specific a symbol cache directory. The default is $HOME/.dotnet/symbolcache if not specified.
 -sympath - Add server, cache and directory paths in the Windows symbol path format.
--log - Enable symbol download logging.
 -loadsymbols - Attempts to download the native .NET Core symbols for the runtime
 <symbol-server-URL> - Symbol server URL.
 
@@ -2006,3 +2006,15 @@ on another machine or for triage dumps.
 
     (lldb) setclrpath /home/user/coreclr/bin/Product/Linux.x64.Debug
 \\
+
+COMMAND: runtimes.
+runtimes
+
+List the .NET runtimes in the target process.
+\\
+
+COMMAND: logging.
+logging [enable] [disable]
+
+Enables or disables the internal trace logging.
+\\
index 20717e2f1e1dd84ee4a53bd5d421e6516707368f..0b9f57b725425c6875b77206ac788f32688ddce7 100644 (file)
@@ -8341,7 +8341,7 @@ DECLARE_API(bpmd)
         }
 
         // Get modules that may need a breakpoint bound
-        if ((Status = CheckEEDll()) == S_OK)
+        if ((Status = GetTarget()->GetRuntime(&g_pRuntime)) == S_OK)
         {
             if ((Status = LoadClrDebugDll()) != S_OK)
             {
@@ -10847,7 +10847,8 @@ DECLARE_API(EEVersion)
     ArrayHolder<char> fileVersionBuffer = new char[fileVersionBufferSize];
     VS_FIXEDFILEINFO version;
 
-    if (GetEEVersion(&version, fileVersionBuffer.GetPtr(), fileVersionBufferSize))
+    HRESULT hr = g_pRuntime->GetEEVersion(&version, fileVersionBuffer.GetPtr(), fileVersionBufferSize);
+    if (SUCCEEDED(hr))
     {
         ExtOut("%u.%u.%u.%u",
             HIWORD(version.dwFileVersionMS),
@@ -10928,61 +10929,22 @@ DECLARE_API(SOSStatus)
 {
     INIT_API_EXT();
 
-    BOOL bDesktop = FALSE;
-    BOOL bNetCore = FALSE;
     BOOL bReset = FALSE;
     CMDOption option[] =
     {   // name, vptr, type, hasValue
-#ifndef FEATURE_PAL
-        {"-netfx", &bDesktop, COBOOL, FALSE},
-        {"-netcore", &bNetCore, COBOOL, FALSE},
-#endif
         {"-reset", &bReset, COBOOL, FALSE},
     };
     if (!GetCMDOption(args, option, _countof(option), NULL, 0, NULL))
     {
         return Status;
     }
-#ifndef FEATURE_PAL
-    if (bNetCore || bDesktop)
-    {
-        if (IsWindowsTarget())
-        {
-            PCSTR name = bDesktop ? "desktop CLR" : ".NET Core";;
-            if (!Runtime::SwitchRuntime(bDesktop))
-            {
-                ExtErr("The %s runtime is not loaded\n", name);
-                return E_FAIL;
-            }
-            ExtOut("Switched to %s runtime successfully\n", name);
-            return S_OK;
-        }
-        else
-        {
-            ExtErr("The '-netfx' and '-netcore' options are only supported on Windows targets\n");
-            return E_FAIL;
-        }
-    }
-#endif
     if (bReset)
     {
-        Runtime::CleanupRuntimes();
-        CleanupTempDirectory();
+        Target::CleanupTarget();
         ExtOut("SOS state reset\n");
         return S_OK;
     }
-    if (g_targetMachine != nullptr) {
-        ExtOut("Target platform: %04x Context size %04x\n", g_targetMachine->GetPlatform(), g_targetMachine->GetContextSize());
-    }
-    if (g_runtimeModulePath != nullptr) {
-        ExtOut("Runtime module path: %s\n", g_runtimeModulePath);
-    }
-    if (g_pRuntime != nullptr) {
-        g_pRuntime->DisplayStatus();
-    }
-    if (g_tmpPath != nullptr) {
-        ExtOut("Temp path: %s\n", g_tmpPath);
-    }
+    Target::DisplayStatus();
 #if !defined(FEATURE_PAL) && !defined(_TARGET_ARM64_)
     if (g_useDesktopClrHost) {
         ExtOut("Using the desktop .NET Framework to host the managed SOS code\n");
@@ -10993,7 +10955,6 @@ DECLARE_API(SOSStatus)
         ExtOut("Host runtime path: %s\n", g_hostRuntimeDirectory);
     }
     DisplaySymbolStore();
-
     return Status;
 }
 
@@ -14884,12 +14845,7 @@ DECLARE_API( VMMap )
 DECLARE_API(SOSFlush)
 {
     INIT_API_EXT();
-
-    Runtime::Flush();
-#ifdef FEATURE_PAL
-    FlushMetadataRegions();
-#endif
-
+    GetTarget()->Flush();
     return Status;
 }
 
@@ -16142,11 +16098,7 @@ DECLARE_API(SuppressJitOptimization)
 
     if (nArg == 1 && (_stricmp(onOff.data, "On") == 0))
     {
-        // if CLR is already loaded, try to change the flags now
-        if (CheckEEDll() == S_OK)
-        {
-            SetNGENCompilerFlags(CORDEBUG_JIT_DISABLE_OPTIMIZATION);
-        }
+        SetNGENCompilerFlags(CORDEBUG_JIT_DISABLE_OPTIMIZATION);
 
         if (!g_fAllowJitOptimization)
         {
@@ -16161,11 +16113,7 @@ DECLARE_API(SuppressJitOptimization)
     }
     else if(nArg == 1 && (_stricmp(onOff.data, "Off") == 0))
     {
-        // if CLR is already loaded, try to change the flags now
-        if (CheckEEDll() == S_OK)
-        {
-            SetNGENCompilerFlags(CORDEBUG_JIT_DEFAULT);
-        }
+        SetNGENCompilerFlags(CORDEBUG_JIT_DEFAULT);
 
         if (g_fAllowJitOptimization)
             ExtOut("JIT optimization is already permitted\n");
@@ -16189,31 +16137,19 @@ HRESULT SetNGENCompilerFlags(DWORD flags)
 {
     HRESULT hr;
 
-    ToRelease<ICorDebugProcess2> proc2;
-    ICorDebugProcess* pCorDebugProcess;
-    if (FAILED(hr = g_pRuntime->GetCorDebugInterface(&pCorDebugProcess)))
-    {
-        ExtOut("SOS: warning, prejitted code optimizations could not be changed. Failed to load ICorDebug HR = 0x%x\n", hr);
-    }
-    else if (FAILED(pCorDebugProcess->QueryInterface(__uuidof(ICorDebugProcess2), (void**) &proc2)))
+    // if CLR is already loaded, try to change the flags now
+    hr = GetTarget()->GetRuntime(&g_pRuntime);
+    if (SUCCEEDED(hr))
     {
-        if (flags != CORDEBUG_JIT_DEFAULT)
-        {
-            ExtOut("SOS: warning, prejitted code optimizations could not be changed. This CLR version doesn't support the functionality\n");
-        }
-        else
+        ToRelease<ICorDebugProcess2> proc2;
+        ICorDebugProcess* pCorDebugProcess;
+        if (FAILED(hr = g_pRuntime->GetCorDebugInterface(&pCorDebugProcess)))
         {
-            hr = S_OK;
+            ExtOut("SOS: warning, prejitted code optimizations could not be changed. Failed to load ICorDebug HR = 0x%x\n", hr);
         }
-    }
-    else if (FAILED(hr = proc2->SetDesiredNGENCompilerFlags(flags)))
-    {
-        // Versions of CLR that don't have SetDesiredNGENCompilerFlags DAC-ized will return E_FAIL.
-        // This was first supported in the clr_triton branch around 4/1/12, Apollo release
-        // It will likely be supported in desktop CLR during Dev12
-        if(hr == E_FAIL)
+        else if (FAILED(pCorDebugProcess->QueryInterface(__uuidof(ICorDebugProcess2), (void**)&proc2)))
         {
-            if(flags != CORDEBUG_JIT_DEFAULT)
+            if (flags != CORDEBUG_JIT_DEFAULT)
             {
                 ExtOut("SOS: warning, prejitted code optimizations could not be changed. This CLR version doesn't support the functionality\n");
             }
@@ -16222,37 +16158,54 @@ HRESULT SetNGENCompilerFlags(DWORD flags)
                 hr = S_OK;
             }
         }
-        else if (hr == CORDBG_E_NGEN_NOT_SUPPORTED)
+        else if (FAILED(hr = proc2->SetDesiredNGENCompilerFlags(flags)))
         {
-            if (flags != CORDEBUG_JIT_DEFAULT)
+            // Versions of CLR that don't have SetDesiredNGENCompilerFlags DAC-ized will return E_FAIL.
+            // This was first supported in the clr_triton branch around 4/1/12, Apollo release
+            // It will likely be supported in desktop CLR during Dev12
+            if (hr == E_FAIL)
             {
-                ExtOut("SOS: warning, prejitted code optimizations could not be changed. This CLR version doesn't support NGEN\n");
+                if (flags != CORDEBUG_JIT_DEFAULT)
+                {
+                    ExtOut("SOS: warning, prejitted code optimizations could not be changed. This CLR version doesn't support the functionality\n");
+                }
+                else
+                {
+                    hr = S_OK;
+                }
             }
-            else
+            else if (hr == CORDBG_E_NGEN_NOT_SUPPORTED)
             {
-                hr = S_OK;
-            }
-        }
-        else if (hr == CORDBG_E_MUST_BE_IN_CREATE_PROCESS)
-        {
-            DWORD currentFlags = 0;
-            if (FAILED(hr = proc2->GetDesiredNGENCompilerFlags(&currentFlags)))
-            {
-                ExtOut("SOS: warning, prejitted code optimizations could not be changed. GetDesiredNGENCompilerFlags failed hr=0x%x\n", hr);
+                if (flags != CORDEBUG_JIT_DEFAULT)
+                {
+                    ExtOut("SOS: warning, prejitted code optimizations could not be changed. This CLR version doesn't support NGEN\n");
+                }
+                else
+                {
+                    hr = S_OK;
+                }
             }
-            else if (currentFlags != flags)
+            else if (hr == CORDBG_E_MUST_BE_IN_CREATE_PROCESS)
             {
-                ExtOut("SOS: warning, prejitted code optimizations could not be changed at this time. This setting is fixed once CLR starts\n");
+                DWORD currentFlags = 0;
+                if (FAILED(hr = proc2->GetDesiredNGENCompilerFlags(&currentFlags)))
+                {
+                    ExtOut("SOS: warning, prejitted code optimizations could not be changed. GetDesiredNGENCompilerFlags failed hr=0x%x\n", hr);
+                }
+                else if (currentFlags != flags)
+                {
+                    ExtOut("SOS: warning, prejitted code optimizations could not be changed at this time. This setting is fixed once CLR starts\n");
+                }
+                else
+                {
+                    hr = S_OK;
+                }
             }
             else
             {
-                hr = S_OK;
+                ExtOut("SOS: warning, prejitted code optimizations could not be changed at this time. SetDesiredNGENCompilerFlags hr = 0x%x\n", hr);
             }
         }
-        else
-        {
-            ExtOut("SOS: warning, prejitted code optimizations could not be changed at this time. SetDesiredNGENCompilerFlags hr = 0x%x\n", hr);
-        }
     }
 
     return hr;
@@ -16691,19 +16644,64 @@ DECLARE_API(SetClrPath)
     }
     if (narg > 0)
     {
-        if (g_runtimeModulePath != nullptr)
+        if (!Target::SetRuntimeDirectory(runtimeModulePath.data))
         {
-            free((void*)g_runtimeModulePath);
+            ExtErr("Invalid runtime path %s\n", runtimeModulePath.data);
+            return E_FAIL;
         }
-        g_runtimeModulePath = _strdup(runtimeModulePath.data);
     }
-    if (g_runtimeModulePath != nullptr)
-    {
-        ExtOut("Runtime module path: %s\n", g_runtimeModulePath);
+    const char* runtimeDirectory = GetTarget()->GetRuntimeDirectory();
+    if (runtimeDirectory != nullptr) {
+        ExtOut("Runtime module path: %s\n", runtimeDirectory);
     }
     return S_OK;
 }
 
+//
+// Lists and selects the current runtime
+//
+DECLARE_API(runtimes)
+{
+    INIT_API_EXT();
+
+    BOOL bNetFx = FALSE;
+    BOOL bNetCore = FALSE;
+    CMDOption option[] =
+    {   // name, vptr, type, hasValue
+        {"-netfx", &bNetFx, COBOOL, FALSE},
+        {"-netcore", &bNetCore, COBOOL, FALSE},
+    };
+    if (!GetCMDOption(args, option, _countof(option), NULL, 0, NULL))
+    {
+        return Status;
+    }
+    if (bNetCore || bNetFx)
+    {
+#ifndef FEATURE_PAL
+        if (IsWindowsTarget())
+        {
+            PCSTR name = bNetFx ? "desktop .NET Framework" : ".NET Core";
+            if (!Target::SwitchRuntime(bNetFx))
+            {
+                ExtErr("The %s runtime is not loaded\n", name);
+                return E_FAIL;
+            }
+            ExtOut("Switched to %s runtime successfully\n", name);
+        }
+        else
+#endif
+        {
+            ExtErr("The '-netfx' and '-netcore' options are only supported on Windows targets\n");
+            return E_FAIL;
+        }
+    }
+    else
+    {
+        Target::DisplayStatus();
+    }
+    return Status;
+}
+
 void PrintHelp (__in_z LPCSTR pszCmdName)
 {
     static LPSTR pText = NULL;
index 17f3baa102a78d837c416729861eaebcf4a93fac..af949c9f877ad77a15c3df41cf7d9dc3786821b6 100644 (file)
@@ -71,7 +71,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
-
+#include "host.h"
 
 #ifndef PAL_STDCPP_COMPAT
 #include <malloc.h>
index 0fdfa4fb9e0e8bcffcfc3b9214cef66e738765c5..dd2ff8de04d4efd1c381035dfe45c4fa1e7564d5 100644 (file)
@@ -25,8 +25,6 @@
 #include <mscoree.h>
 #include <tchar.h>
 #include "debugshim.h"
-#include "datatarget.h"
-#include "runtime.h"
 #include "gcinfo.h"
 
 #ifndef STRESS_LOG
@@ -40,7 +38,7 @@
 #include <dlfcn.h>
 #endif // !FEATURE_PAL
 
-#include <coreclrhost.h>
+#include "coreclrhost.h"
 #include <set>
 #include <string>
 
@@ -163,11 +161,6 @@ void ReportOOM()
     ExtOut("SOS Error: Out of memory\n");
 }
 
-HRESULT CheckEEDll()
-{
-    return Runtime::CreateInstance();
-}
-
 BOOL IsDumpFile()
 {
     static int g_fDumpFile = -1;
@@ -3415,42 +3408,6 @@ size_t FunctionType (size_t EIP)
     return (size_t) pMD;
 }
 
-//
-// Gets version info for the CLR in the debuggee process.
-//
-BOOL GetEEVersion(VS_FIXEDFILEINFO* pFileInfo, char* fileVersionBuffer, int fileVersionBufferSizeInBytes)
-{
-    _ASSERTE(pFileInfo != nullptr);
-    _ASSERTE(g_ExtSymbols2 != nullptr);
-    _ASSERTE(g_pRuntime != nullptr);
-
-#ifdef FEATURE_PAL
-    // Load the symbols for runtime. On Linux we are looking for the "sccsid" 
-    // global so "libcoreclr.so/.dylib" symbols need to be loaded.
-    LoadNativeSymbols(true);
-#endif
-
-    HRESULT hr = g_ExtSymbols2->GetModuleVersionInformation(g_pRuntime->GetModuleIndex(), 0, "\\", pFileInfo, sizeof(VS_FIXEDFILEINFO), NULL);
-
-    // 0.0.0.0 is not a valid version. This is sometime returned by windbg for Linux core dumps
-    if (SUCCEEDED(hr) && (pFileInfo->dwFileVersionMS == (DWORD)-1 || (pFileInfo->dwFileVersionLS == 0 && pFileInfo->dwFileVersionMS == 0))) {
-        return FALSE;
-    }
-
-    // Attempt to get the the FileVersion string that contains version and the "built by" and commit id info
-    if (fileVersionBuffer != nullptr)
-    {
-        if (fileVersionBufferSizeInBytes > 0) {
-            fileVersionBuffer[0] = '\0';
-        }
-        // We can assume the English/CP_UNICODE lang/code page for the runtime modules
-        g_ExtSymbols2->GetModuleVersionInformation(
-            g_pRuntime->GetModuleIndex(), 0, "\\StringFileInfo\\040904B0\\FileVersion", fileVersionBuffer, fileVersionBufferSizeInBytes, NULL);
-    }
-
-    return SUCCEEDED(hr);
-}
-
 //
 // Return true if major runtime version (logical product version like 2.1, 
 // 3.0 or 5.x). Currently only major versions of 3 or 5 are supported.
@@ -3458,7 +3415,7 @@ BOOL GetEEVersion(VS_FIXEDFILEINFO* pFileInfo, char* fileVersionBuffer, int file
 bool IsRuntimeVersion(DWORD major)
 {
     VS_FIXEDFILEINFO fileInfo;
-    if (GetEEVersion(&fileInfo, nullptr, 0))
+    if (SUCCEEDED(g_pRuntime->GetEEVersion(&fileInfo, nullptr, 0)))
     {
         return IsRuntimeVersion(fileInfo, major);
     }
@@ -3483,7 +3440,7 @@ bool IsRuntimeVersion(VS_FIXEDFILEINFO& fileInfo, DWORD major)
 bool IsRuntimeVersionAtLeast(DWORD major)
 {
     VS_FIXEDFILEINFO fileInfo;
-    if (GetEEVersion(&fileInfo, nullptr, 0))
+    if (SUCCEEDED(g_pRuntime->GetEEVersion(&fileInfo, nullptr, 0)))
     {
         return IsRuntimeVersionAtLeast(fileInfo, major);
     }
@@ -5051,6 +5008,7 @@ ConvertNativeToIlOffset(
 
     if ((Status = GetClrMethodInstance(nativeOffset, &pMethodInst)) != S_OK)
     {
+        ExtDbgOut("ConvertNativeToIlOffset(%p): GetClrMethodInstance FAILED %08x\n", nativeOffset, Status);
         return Status;
     }
 
@@ -5068,6 +5026,7 @@ ConvertNativeToIlOffset(
 
     if ((Status = pMethodInst->GetILOffsetsByAddress(nativeOffset, 1, NULL, methodOffs)) != S_OK)
     {
+        ExtDbgOut("ConvertNativeToIlOffset(%p): GetILOffsetsByAddress FAILED %08x\n", nativeOffset, Status);
         *methodOffs = 0;
     }
     else
@@ -5116,8 +5075,11 @@ GetLineByOffset(
     IfFailRet(ConvertNativeToIlOffset(nativeOffset, bAdjustOffsetForLineNumber, &pModule, &methodToken, &methodOffs));
 
     ToRelease<IMetaDataImport> pMDImport(NULL);
-    pModule->QueryInterface(IID_IMetaDataImport, (LPVOID *) &pMDImport);
-
+    Status = pModule->QueryInterface(IID_IMetaDataImport, (LPVOID *) &pMDImport);
+    if (FAILED(Status))
+    {
+        ExtDbgOut("GetLineByOffset(%p): QueryInterface(IID_IMetaDataImport) FAILED %08x\n", nativeOffset, Status);
+    }
     SymbolReader symbolReader;
     IfFailRet(symbolReader.LoadSymbols(pMDImport, pModule));
 
@@ -5814,6 +5776,7 @@ void FlushMetadataRegions()
     {
         const_cast<MemoryRegion&>(region).Dispose();
     }
+    g_metadataRegions.clear();
     g_metadataRegionsPopulated = false;
 }
 
index 0c5dcfbd33d9622e7b2526aaf8a78b3a2d658857..ced7bad3a0947c9e00542893f790a8fa394f079f 100644 (file)
@@ -2,11 +2,6 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-// ==++==
-//
-
-//
-// ==--==
 #ifndef __util_h__
 #define __util_h__
 
@@ -38,8 +33,11 @@ inline void RestoreSOToleranceState() {}
 #include "cordebug.h"
 #include "static_assert.h"
 #include <string>
+#include "releaseholder.h"
+#include "hostimpl.h"
+#include "targetimpl.h"
+#include "runtimeimpl.h"
 #include "hostcoreclr.h"
-#include "holder.h"
 
 typedef LPCSTR  LPCUTF8;
 typedef LPSTR   LPUTF8;
@@ -1666,7 +1664,7 @@ SafeReadMemory (TO_TADDR(src), &(dst), sizeof(dst), NULL)
 
 extern "C" PDEBUG_DATA_SPACES g_ExtData;
 
-#include <arrayholder.h>
+#include "arrayholder.h"
 
 // This class acts a smart pointer which calls the Release method on any object
 // you place in it when the ToRelease class falls out of scope.  You may use it
@@ -1754,7 +1752,6 @@ void DecodeIL(IMetaDataImport *pImport, BYTE *buffer, ULONG bufSize);
 void DecodeDynamicIL(BYTE *data, ULONG Size, DacpObjectData& tokenArray);
 ULONG DisplayILOperation(const UINT indentCount, BYTE* pBuffer, ULONG position, std::function<void(DWORD)>& func);
 
-BOOL GetEEVersion(VS_FIXEDFILEINFO* pFileInfo, char* fileVersionBuffer, int fileVersionBufferSizeInBytes);
 bool IsRuntimeVersion(DWORD major);
 bool IsRuntimeVersion(VS_FIXEDFILEINFO& fileInfo, DWORD major);
 bool IsRuntimeVersionAtLeast(DWORD major);
index 438bcfca33ae1731279a51a7999825248fb5d921..2f3e7ac690cd79a2c8cce72641046ca891fb868f 100644 (file)
@@ -13,8 +13,8 @@
 
 #include <unknwn.h>
 #include <rpc.h>
-#include <lldbservices.h>
-#include <arrayholder.h>
+#include "lldbservices.h"
+#include "arrayholder.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -339,10 +339,10 @@ public:
     //----------------------------------------------------------------------------
 
     HRESULT 
-    GetCurrentProcessId(
+    GetCurrentProcessSystemId(
         PULONG id)
     {
-        return m_lldbservices->GetCurrentProcessId(id);
+        return m_lldbservices->GetCurrentProcessSystemId(id);
     }
 
     HRESULT 
index 96871e89d773f2732fc52d1a746e8523339ff04b..43a7e7b47f1ba790b4f18add9c25566a9b6e02cc 100644 (file)
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\dbgutil\Debug\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\dbgutil\Debug\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">dbgutil.dir\Debug\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">dbgutil</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.lib</TargetExt>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\dbgutil\Checked\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\dbgutil\Checked\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">dbgutil.dir\Checked\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">dbgutil</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">.lib</TargetExt>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\dbgutil\Release\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\dbgutil\Release\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">dbgutil.dir\Release\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">dbgutil</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.lib</TargetExt>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\dbgutil\RelWithDebInfo\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\dbgutil\RelWithDebInfo\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">dbgutil.dir\RelWithDebInfo\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">dbgutil</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">.lib</TargetExt>
   <ImportGroup Label="ExtensionTargets">
     <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index 9b7ebbbe530b72c3a29c07f3a1d12c3c7dd2f0dd..756d7ac757b5b233f94d34ca53f9f2e1940d7654 100644 (file)
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\debugshim\Debug\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\debugshim\Debug\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debugshim.dir\Debug\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debugshim</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.lib</TargetExt>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\debugshim\Checked\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\debugshim\Checked\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">debugshim.dir\Checked\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">debugshim</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">.lib</TargetExt>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\debugshim\Release\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\debugshim\Release\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">debugshim.dir\Release\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">debugshim</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.lib</TargetExt>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\debugshim\RelWithDebInfo\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\debugshim\RelWithDebInfo\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">debugshim.dir\RelWithDebInfo\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">debugshim</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">.lib</TargetExt>
   <ImportGroup Label="ExtensionTargets">
     <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index abed0ae94b8d25081f46d2b8815288464d3e08d9..473667a4602d756f15b8521c077491ec7e67601f 100644 (file)
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\gcdump\Debug\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\gcdump\Debug\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">gcdump.dir\Debug\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">gcdump</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.lib</TargetExt>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\gcdump\Checked\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\gcdump\Checked\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">gcdump.dir\Checked\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">gcdump</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Checked|x64'">.lib</TargetExt>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\gcdump\Release\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\gcdump\Release\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">gcdump.dir\Release\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">gcdump</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.lib</TargetExt>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">C:\ssd\diagnostics\artifacts\obj\Windows_NT.x64.Debug\src\SOS\gcdump\RelWithDebInfo\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">$(ArtifactsObjDir)Windows_NT.x64.Debug\src\SOS\gcdump\RelWithDebInfo\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">gcdump.dir\RelWithDebInfo\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">gcdump</TargetName>
     <TargetExt Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">.lib</TargetExt>
   <ImportGroup Label="ExtensionTargets">
     <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/src/SOS/inc/dbgeng/DbgModel.h b/src/SOS/inc/dbgeng/DbgModel.h
new file mode 100644 (file)
index 0000000..7bdab70
--- /dev/null
@@ -0,0 +1,7349 @@
+//*******************************************************************************
+//
+// Debugger Data Model
+//
+// Copyright (c) Microsoft Corporation.  All rights reserved.
+//
+//*******************************************************************************
+
+#ifndef __DBGMODEL_H__
+#define __DBGMODEL_H__
+
+#include <winapifamily.h>
+
+#pragma region Desktop Family or WER Package
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PKG_WER)
+
+//
+// A number of the model APIs have a convention to return extended error information in the resulting object.
+// This means that a series of APIs which return model objects will
+//
+// - On success
+//       Always have a valid model object
+//
+// - On failure
+//       Possibly return back a model object which is an error object which contains extended error information
+//       beyond the failing HRESULT.  Such objects are immediately convertable to display strings, etc...
+//
+#define _COM_Errorptr_ _Outptr_
+#define _COM_Errorptr_opt_ _Outptr_opt_
+#define _COM_Errorptr_opt_result_maybenull_ _Outptr_opt_result_maybenull_
+
+//
+// Location:
+//
+// Defines the location for an object.  This particular variant of Location is the C-COM access struct.
+// Note that a location only has meaning in conjunction with a host context.  It is a location within
+// a context.  When performing an operation on the location (reading bytes, writing bytes, etc...),
+// a valid host context must be supplied.
+//
+struct Location
+{
+    // The HostDefined field has two states that are "Non-Opaque" at the API layer.
+    //
+    //            0: Indicates that the offset is a pointer into virtual address space of the target.
+    //     Non-Zero: The defined value is proprietary to the host.  Clients can propagate and change offset.  They cannot
+    //               legally change the value.
+    //
+    // This can be determined by the IsVirtualAddress() method if this structure is built from C++ code.
+    //
+    ULONG64 HostDefined;
+    ULONG64 Offset;
+
+#ifdef __cplusplus
+
+    // Location():
+    //
+    // Default constructs an equivalent nullptr.
+    //
+    Location() :
+        HostDefined(0),
+        Offset(0)
+    {
+    }
+
+    // Location():
+    //
+    // Constructs a location from an offset into the virtual address space of the target.
+    //
+    Location(ULONG64 virtualAddress) :
+        HostDefined(0),
+        Offset(virtualAddress)
+    {
+    }
+
+    Location(const Location& src) :
+        HostDefined(src.HostDefined),
+        Offset(src.Offset)
+    {
+    }
+
+    Location& operator=(const Location& src)
+    {
+        HostDefined = src.HostDefined;
+        Offset = src.Offset;
+        return *this;
+    }
+
+    Location& operator=(ULONG64 virtualAddress)
+    {
+        HostDefined = 0;
+        Offset = virtualAddress;
+        return *this;
+    }
+
+    bool operator==(const Location& rhs) const
+    {
+        return (rhs.HostDefined == HostDefined && rhs.Offset == Offset);
+    }
+
+    bool operator!=(const Location& rhs) const
+    {
+        return !(operator==(rhs));
+    }
+
+    Location& operator+=(LONG64 offset)
+    {
+        Offset += offset;
+        return *this;
+    }
+
+    Location& operator-=(LONG64 offset)
+    {
+        Offset -= offset;
+        return *this;
+    }
+
+    Location operator+(LONG64 offset) const
+    {
+        Location l = *this;
+        l += offset;
+        return l;
+    }
+
+    Location operator-(LONG64 offset) const
+    {
+        Location l = *this;
+        l -= offset;
+        return l;
+    }
+
+    // GetOffset():
+    //
+    // Returns the offset of the location.
+    //
+    ULONG64 GetOffset() const
+    {
+        return Offset;
+    }
+
+    // IsVirtualAddress():
+    //
+    // Indicates whether the location refers to a virtual address.
+    //
+    bool IsVirtualAddress() const
+    {
+        return (HostDefined == 0);
+    }
+
+#endif // __cplusplus
+
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+//*************************************************
+// Public Interfaces:
+
+// {F2BCE54E-4835-4f8a-836E-7981E29904D1}
+DEFINE_GUID(IID_IHostDataModelAccess, 0xf2bce54e, 0x4835, 0x4f8a, 0x83, 0x6e, 0x79, 0x81, 0xe2, 0x99, 0x4, 0xd1);
+
+// {0FC7557D-401D-4fca-9365-DA1E9850697C}
+DEFINE_GUID(IID_IKeyStore, 0xfc7557d, 0x401d, 0x4fca, 0x93, 0x65, 0xda, 0x1e, 0x98, 0x50, 0x69, 0x7c);
+
+// {E28C7893-3F4B-4b96-BACA-293CDC55F45D}
+DEFINE_GUID(IID_IModelObject, 0xe28c7893, 0x3f4b, 0x4b96, 0xba, 0xca, 0x29, 0x3c, 0xdc, 0x55, 0xf4, 0x5d);
+
+// {73FE19F4-A110-4500-8ED9-3C28896F508C}
+DEFINE_GUID(IID_IDataModelManager, 0x73fe19f4, 0xa110, 0x4500, 0x8e, 0xd9, 0x3c, 0x28, 0x89, 0x6f, 0x50, 0x8c);
+
+// {5253DCF8-5AFF-4c62-B302-56A289E00998}
+DEFINE_GUID(IID_IModelKeyReference, 0x5253dcf8, 0x5aff, 0x4c62, 0xb3, 0x2, 0x56, 0xa2, 0x89, 0xe0, 0x9, 0x98);
+
+// {5A0C63D9-0526-42b8-960C-9516A3254C85}
+DEFINE_GUID(IID_IModelPropertyAccessor, 0x5a0c63d9, 0x526, 0x42b8, 0x96, 0xc, 0x95, 0x16, 0xa3, 0x25, 0x4c, 0x85);
+
+// {80600C1F-B90B-4896-82AD-1C00207909E8}
+DEFINE_GUID(IID_IModelMethod, 0x80600c1f, 0xb90b, 0x4896, 0x82, 0xad, 0x1c, 0x0, 0x20, 0x79, 0x9, 0xe8);
+
+// {345FA92E-5E00-4319-9CAE-971F7601CDCF}
+DEFINE_GUID(IID_IKeyEnumerator, 0x345fa92e, 0x5e00, 0x4319, 0x9c, 0xae, 0x97, 0x1f, 0x76, 0x1, 0xcd, 0xcf);
+
+// {E13613F9-3A3C-40b5-8F48-1E5EBFB9B21B}
+DEFINE_GUID(IID_IRawEnumerator, 0xe13613f9, 0x3a3c, 0x40b5, 0x8f, 0x48, 0x1e, 0x5e, 0xbf, 0xb9, 0xb2, 0x1b);
+
+// {FCB98D1D-1114-4fbf-B24C-EFFCB5DEF0D3}
+DEFINE_GUID(IID_IDataModelConcept, 0xfcb98d1d, 0x1114, 0x4fbf, 0xb2, 0x4c, 0xef, 0xfc, 0xb5, 0xde, 0xf0, 0xd3);
+
+// {D28E8D70-6C00-4205-940D-501016601EA3}
+DEFINE_GUID(IID_IStringDisplayableConcept, 0xd28e8d70, 0x6c00, 0x4205, 0x94, 0xd, 0x50, 0x10, 0x16, 0x60, 0x1e, 0xa3);
+
+// {E4622136-927D-4490-874F-581F3E4E3688}
+DEFINE_GUID(IID_IModelIterator, 0xe4622136, 0x927d, 0x4490, 0x87, 0x4f, 0x58, 0x1f, 0x3e, 0x4e, 0x36, 0x88);
+
+// {F5D49D0C-0B02-4301-9C9B-B3A6037628F3}
+DEFINE_GUID(IID_IIterableConcept, 0xf5d49d0c, 0xb02, 0x4301, 0x9c, 0x9b, 0xb3, 0xa6, 0x3, 0x76, 0x28, 0xf3);
+
+// {D1FAD99F-3F53-4457-850C-8051DF2D3FB5}
+DEFINE_GUID(IID_IIndexableConcept, 0xd1fad99f, 0x3f53, 0x4457, 0x85, 0xc, 0x80, 0x51, 0xdf, 0x2d, 0x3f, 0xb5);
+
+// {9D6C1D7B-A76F-4618-8068-5F76BD9A4E8A}
+DEFINE_GUID(IID_IPreferredRuntimeTypeConcept, 0x9d6c1d7b, 0xa76f, 0x4618, 0x80, 0x68, 0x5f, 0x76, 0xbd, 0x9a, 0x4e, 0x8a);
+
+// {B8C74943-6B2C-4eeb-B5C5-35D378A6D99D}
+DEFINE_GUID(IID_IDebugHost, 0xb8c74943, 0x6b2c, 0x4eeb, 0xb5, 0xc5, 0x35, 0xd3, 0x78, 0xa6, 0xd9, 0x9d);
+
+// {A68C70D8-5EC0-46e5-B775-3134A48EA2E3}
+DEFINE_GUID(IID_IDebugHostContext, 0xa68c70d8, 0x5ec0, 0x46e5, 0xb7, 0x75, 0x31, 0x34, 0xa4, 0x8e, 0xa2, 0xe3);
+
+// {854FD751-C2E1-4eb2-B525-6619CB97A588}
+DEFINE_GUID(IID_IDebugHostSymbols, 0x854fd751, 0xc2e1, 0x4eb2, 0xb5, 0x25, 0x66, 0x19, 0xcb, 0x97, 0xa5, 0x88);
+
+// {212149C9-9183-4a3e-B00E-4FD1DC95339B}
+DEFINE_GUID(IID_IDebugHostMemory, 0x212149c9, 0x9183, 0x4a3e, 0xb0, 0xe, 0x4f, 0xd1, 0xdc, 0x95, 0x33, 0x9b);
+
+// {0F819103-87DE-4e96-8277-E05CD441FB22}
+DEFINE_GUID(IID_IDebugHostSymbol, 0xf819103, 0x87de, 0x4e96, 0x82, 0x77, 0xe0, 0x5c, 0xd4, 0x41, 0xfb, 0x22);
+
+// {28D96C86-10A3-4976-B14E-EAEF4790AA1F}
+DEFINE_GUID(IID_IDebugHostSymbolEnumerator, 0x28d96c86, 0x10a3, 0x4976, 0xb1, 0x4e, 0xea, 0xef, 0x47, 0x90, 0xaa, 0x1f);
+
+// {C9BA3E18-D070-4378-BBD0-34613B346E1E}
+DEFINE_GUID(IID_IDebugHostModule, 0xc9ba3e18, 0xd070, 0x4378, 0xbb, 0xd0, 0x34, 0x61, 0x3b, 0x34, 0x6e, 0x1e);
+
+// {F219B848-63B2-4a43-A6C9-72ABF25A9711}
+DEFINE_GUID(IID_IDebugHostType, 0xf219b848, 0x63b2, 0x4a43, 0xa6, 0xc9, 0x72, 0xab, 0xf2, 0x5a, 0x97, 0x11);
+
+// {62787EDC-FA76-4690-BD71-5E8C3E2937EC}
+DEFINE_GUID(IID_IDebugHostConstant, 0x62787edc, 0xfa76, 0x4690, 0xbd, 0x71, 0x5e, 0x8c, 0x3e, 0x29, 0x37, 0xec);
+
+// {31E53A5A-01EE-4BBB-B899-4B46AE7D595C}
+DEFINE_GUID(IID_IDebugHostModuleSignature, 0x31e53a5a, 0x01ee, 0x4bbb, 0xb8, 0x99, 0x4b, 0x46, 0xae, 0x7d, 0x59, 0x5c);
+
+// {3AADC353-2B14-4abb-9893-5E03458E07EE}
+DEFINE_GUID(IID_IDebugHostTypeSignature, 0x3aadc353, 0x2b14, 0x4abb, 0x98, 0x93, 0x5e, 0x3, 0x45, 0x8e, 0x7, 0xee);
+
+// {E06F6495-16BC-4cc9-B11D-2A6B23FA72F3}
+DEFINE_GUID(IID_IDebugHostField, 0xe06f6495, 0x16bc, 0x4cc9, 0xb1, 0x1d, 0x2a, 0x6b, 0x23, 0xfa, 0x72, 0xf3);
+
+// {A3D64993-826C-44fa-897D-926F2FE7AD0B}
+DEFINE_GUID(IID_IDebugHostData, 0xa3d64993, 0x826c, 0x44fa, 0x89, 0x7d, 0x92, 0x6f, 0x2f, 0xe7, 0xad, 0xb);
+
+// {B94D57D2-390B-40f7-B5B4-B6DB897D974B}
+DEFINE_GUID(IID_IDebugHostBaseClass, 0xb94d57d2, 0x390b, 0x40f7, 0xb5, 0xb4, 0xb6, 0xdb, 0x89, 0x7d, 0x97, 0x4b);
+
+// {C8FF0F0B-FCE9-467e-8BB3-5D69EF109C00}
+DEFINE_GUID(IID_IDebugHostErrorSink, 0xc8ff0f0b, 0xfce9, 0x467e, 0x8b, 0xb3, 0x5d, 0x69, 0xef, 0x10, 0x9c, 0x0);
+
+// {0FEF9A21-577E-4997-AC7B-1C4883241D99}
+DEFINE_GUID(IID_IDebugHostEvaluator, 0xfef9a21, 0x577e, 0x4997, 0xac, 0x7b, 0x1c, 0x48, 0x83, 0x24, 0x1d, 0x99);
+
+// {6C597AC9-FB4D-4f6d-9F39-22488539F8F4}
+DEFINE_GUID(IID_IDebugHostPublic, 0x6c597ac9, 0xfb4d, 0x4f6d, 0x9f, 0x39, 0x22, 0x48, 0x85, 0x39, 0xf8, 0xf4);
+
+// {B28632B9-8506-4676-87CE-8F7E05E59876}
+DEFINE_GUID(IID_IDebugHostType2, 0xb28632b9, 0x8506, 0x4676, 0x87, 0xce, 0x8f, 0x7e, 0x5, 0xe5, 0x98, 0x76);
+
+// {4F3E1CE2-86B2-4C7A-9C65-D0A9D0EECF44}
+DEFINE_GUID(IID_IDebugHostStatus, 0x4f3e1ce2, 0x86b2, 0x4c7a, 0x9c, 0x65, 0xd0, 0xa9, 0xd0, 0xee, 0xcf, 0x44);
+
+// {3B362B0E-89F0-46c6-A663-DFDC95194AEF}
+DEFINE_GUID(IID_IDataModelScriptClient, 0x3b362b0e, 0x89f0, 0x46c6, 0xa6, 0x63, 0xdf, 0xdc, 0x95, 0x19, 0x4a, 0xef);
+
+// {1303DEC4-FA3B-4F1B-9224-B953D16BABB5}
+DEFINE_GUID(IID_IDataModelScriptTemplate, 0x1303dec4, 0xfa3b, 0x4f1b, 0x92, 0x24, 0xb9, 0x53, 0xd1, 0x6b, 0xab, 0xb5);
+
+// {7B4D30FC-B14A-49f8-8D87-D9A1480C97F7}
+DEFINE_GUID(IID_IDataModelScript, 0x7b4d30fc, 0xb14a, 0x49f8, 0x8d, 0x87, 0xd9, 0xa1, 0x48, 0xc, 0x97, 0xf7);
+
+// {513461E0-4FCA-48ce-8658-32F3E2056F3B}
+DEFINE_GUID(IID_IDataModelScriptProvider, 0x513461e0, 0x4fca, 0x48ce, 0x86, 0x58, 0x32, 0xf3, 0xe2, 0x5, 0x6f, 0x3b);
+
+// {6FD11E33-E5AD-410b-8011-68C6BC4BF80D}
+DEFINE_GUID(IID_IDataModelScriptManager, 0x6fd11e33, 0xe5ad, 0x410b, 0x80, 0x11, 0x68, 0xc6, 0xbc, 0x4b, 0xf8, 0xd);
+
+// {95BA00E2-704A-4fe2-A8F1-A7E7D8FB0941}
+DEFINE_GUID(IID_IDataModelScriptProviderEnumerator, 0x95ba00e2, 0x704a, 0x4fe2, 0xa8, 0xf1, 0xa7, 0xe7, 0xd8, 0xfb, 0x9, 0x41);
+
+// {B70334A4-B92C-4570-93A1-D3EB686649A0}
+DEFINE_GUID(IID_IDebugHostScriptHost, 0xb70334a4, 0xb92c, 0x4570, 0x93, 0xa1, 0xd3, 0xeb, 0x68, 0x66, 0x49, 0xa0);
+
+// {014D366A-1F23-4981-9219-B2DB8B402054}
+DEFINE_GUID(IID_IDataModelScriptHostContext, 0x14d366a, 0x1f23, 0x4981, 0x92, 0x19, 0xb2, 0xdb, 0x8b, 0x40, 0x20, 0x54);
+
+// {AF352B7B-8292-4c01-B360-2DC3696C65E7}
+DEFINE_GUID(IID_IDataModelNameBinder, 0xaf352b7b, 0x8292, 0x4c01, 0xb3, 0x60, 0x2d, 0xc3, 0x69, 0x6c, 0x65, 0xe7);
+
+// {E7983FA1-80A7-498c-988F-518DDC5D4025}
+DEFINE_GUID(IID_IDynamicKeyProviderConcept, 0xe7983fa1, 0x80a7, 0x498c, 0x98, 0x8f, 0x51, 0x8d, 0xdc, 0x5d, 0x40, 0x25);
+
+// {95A7F7DD-602E-483f-9D06-A15C0EE13174}
+DEFINE_GUID(IID_IDynamicConceptProviderConcept, 0x95a7f7dd, 0x602e, 0x483f, 0x9d, 0x6, 0xa1, 0x5c, 0xe, 0xe1, 0x31, 0x74);
+
+// {69CE6AE2-2268-4e6f-B062-20CE62BFE677}
+DEFINE_GUID(IID_IDataModelScriptTemplateEnumerator, 0x69ce6ae2, 0x2268, 0x4e6f, 0xb0, 0x62, 0x20, 0xce, 0x62, 0xbf, 0xe6, 0x77);
+
+// {80E2F7C5-7159-4e92-887E-7E0347E88406}
+DEFINE_GUID(IID_IModelKeyReference2, 0x80e2f7c5, 0x7159, 0x4e92, 0x88, 0x7e, 0x7e, 0x3, 0x47, 0xe8, 0x84, 0x6);
+
+// {21515B67-6720-4257-8A68-077DC944471C}
+DEFINE_GUID(IID_IDebugHostSymbol2, 0x21515b67, 0x6720, 0x4257, 0x8a, 0x68, 0x7, 0x7d, 0xc9, 0x44, 0x47, 0x1c);
+
+// {A117A435-1FB4-4092-A2AB-A929576C1E87}
+DEFINE_GUID(IID_IDebugHostEvaluator2, 0xa117a435, 0x1fb4, 0x4092, 0xa2, 0xab, 0xa9, 0x29, 0x57, 0x6c, 0x1e, 0x87);
+
+// {F412C5EA-2284-4622-A660-A697160D3312}
+DEFINE_GUID(IID_IDataModelManager2, 0xf412c5ea, 0x2284, 0x4622, 0xa6, 0x60, 0xa6, 0x97, 0x16, 0xd, 0x33, 0x12);
+
+// {EEA033DE-38F6-416b-A251-1D3771001270}
+DEFINE_GUID(IID_IDebugHostMemory2, 0xeea033de, 0x38f6, 0x416b, 0xa2, 0x51, 0x1d, 0x37, 0x71, 0x0, 0x12, 0x70);
+
+// {3C2B24E1-11D0-4f86-8AE5-4DF166F73253}
+DEFINE_GUID(IID_IDebugHostExtensibility, 0x3c2b24e1, 0x11d0, 0x4f86, 0x8a, 0xe5, 0x4d, 0xf1, 0x66, 0xf7, 0x32, 0x53);
+
+// {DE8E0945-9750-4471-AB76-A8F79D6EC350}
+DEFINE_GUID(IID_IDataModelScriptDebug, 0xde8e0945, 0x9750, 0x4471, 0xab, 0x76, 0xa8, 0xf7, 0x9d, 0x6e, 0xc3, 0x50);
+
+// {53159B6D-D4C4-471b-A863-5B110CA800CA}
+DEFINE_GUID(IID_IDataModelScriptDebugClient, 0x53159b6d, 0xd4c4, 0x471b, 0xa8, 0x63, 0x5b, 0x11, 0xc, 0xa8, 0x0, 0xca);
+
+// {051364DD-E449-443e-9762-FE578F4A5473}
+DEFINE_GUID(IID_IDataModelScriptDebugStack, 0x51364dd, 0xe449, 0x443e, 0x97, 0x62, 0xfe, 0x57, 0x8f, 0x4a, 0x54, 0x73);
+
+// {DEC6ED5E-6360-4941-AB4C-A26409DE4F82}
+DEFINE_GUID(IID_IDataModelScriptDebugStackFrame, 0xdec6ed5e, 0x6360, 0x4941, 0xab, 0x4c, 0xa2, 0x64, 0x9, 0xde, 0x4f, 0x82);
+
+// {0F9FEED7-D045-4ac3-98A8-A98942CF6A35}
+DEFINE_GUID(IID_IDataModelScriptDebugVariableSetEnumerator, 0xf9feed7, 0xd045, 0x4ac3, 0x98, 0xa8, 0xa9, 0x89, 0x42, 0xcf, 0x6a, 0x35);
+
+// {6BB27B35-02E6-47cb-90A0-5371244032DE}
+DEFINE_GUID(IID_IDataModelScriptDebugBreakpoint, 0x6bb27b35, 0x2e6, 0x47cb, 0x90, 0xa0, 0x53, 0x71, 0x24, 0x40, 0x32, 0xde);
+
+// {39484A75-B4F3-4799-86DA-691AFA57B299}
+DEFINE_GUID(IID_IDataModelScriptDebugBreakpointEnumerator, 0x39484a75, 0xb4f3, 0x4799, 0x86, 0xda, 0x69, 0x1a, 0xfa, 0x57, 0xb2, 0x99);
+
+// {CBB10ED3-839E-426c-9243-E23535C1AE1A}
+DEFINE_GUID(IID_IDataModelScriptDebug2, 0xcbb10ed3, 0x839e, 0x426c, 0x92, 0x43, 0xe2, 0x35, 0x35, 0xc1, 0xae, 0x1a);
+
+// {A7830646-9F0C-4a31-BA19-503F33E6C8A3}
+DEFINE_GUID(IID_IComparableConcept, 0xa7830646, 0x9f0c, 0x4a31, 0xba, 0x19, 0x50, 0x3f, 0x33, 0xe6, 0xc8, 0xa3);
+
+// {C52D5D3D-609D-4d5d-8A82-46B0ACDEC4F4}
+DEFINE_GUID(IID_IEquatableConcept, 0xc52d5d3d, 0x609d, 0x4d5d, 0x8a, 0x82, 0x46, 0xb0, 0xac, 0xde, 0xc4, 0xf4);
+
+// {B51887E8-BCD0-4e8f-A8C7-434398B78C37}
+DEFINE_GUID(IID_IDebugHostModule2, 0xb51887e8, 0xbcd0, 0x4e8f, 0xa8, 0xc7, 0x43, 0x43, 0x98, 0xb7, 0x8c, 0x37);
+
+struct DECLSPEC_UUID("F2BCE54E-4835-4f8a-836E-7981E29904D1") IHostDataModelAccess;
+
+struct DECLSPEC_UUID("0FC7557D-401D-4fca-9365-DA1E9850697C") IKeyStore;
+struct DECLSPEC_UUID("E28C7893-3F4B-4b96-BACA-293CDC55F45D") IModelObject;
+struct DECLSPEC_UUID("73FE19F4-A110-4500-8ED9-3C28896F508C") IDataModelManager;
+struct DECLSPEC_UUID("5253DCF8-5AFF-4c62-B302-56A289E00998") IModelKeyReference;
+struct DECLSPEC_UUID("5A0C63D9-0526-42b8-960C-9516A3254C85") IModelPropertyAccessor;
+struct DECLSPEC_UUID("80600C1F-B90B-4896-82AD-1C00207909E8") IModelMethod;
+struct DECLSPEC_UUID("345FA92E-5E00-4319-9CAE-971F7601CDCF") IKeyEnumerator;
+struct DECLSPEC_UUID("E13613F9-3A3C-40b5-8F48-1E5EBFB9B21B") IRawEnumerator;
+
+struct DECLSPEC_UUID("FCB98D1D-1114-4fbf-B24C-EFFCB5DEF0D3") IDataModelConcept;
+struct DECLSPEC_UUID("D28E8D70-6C00-4205-940D-501016601EA3") IStringDisplayableConcept;
+struct DECLSPEC_UUID("E4622136-927D-4490-874F-581F3E4E3688") IModelIterator;
+struct DECLSPEC_UUID("F5D49D0C-0B02-4301-9C9B-B3A6037628F3") IIterableConcept;
+struct DECLSPEC_UUID("D1FAD99F-3F53-4457-850C-8051DF2D3FB5") IIndexableConcept;
+struct DECLSPEC_UUID("9D6C1D7B-A76F-4618-8068-5F76BD9A4E8A") IPreferredRuntimeTypeConcept;
+
+struct DECLSPEC_UUID("B8C74943-6B2C-4eeb-B5C5-35D378A6D99D") IDebugHost;
+struct DECLSPEC_UUID("A68C70D8-5EC0-46e5-B775-3134A48EA2E3") IDebugHostContext;
+struct DECLSPEC_UUID("854FD751-C2E1-4eb2-B525-6619CB97A588") IDebugHostSymbols;
+struct DECLSPEC_UUID("31E53A5A-01EE-4BBB-B899-4B46AE7D595C") IDebugHostModuleSignature;
+struct DECLSPEC_UUID("3AADC353-2B14-4abb-9893-5E03458E07EE") IDebugHostTypeSignature;
+struct DECLSPEC_UUID("212149C9-9183-4a3e-B00E-4FD1DC95339B") IDebugHostMemory;
+struct DECLSPEC_UUID("C8FF0F0B-FCE9-467e-8BB3-5D69EF109C00") IDebugHostErrorSink;
+struct DECLSPEC_UUID("0FEF9A21-577E-4997-AC7B-1C4883241D99") IDebugHostEvaluator;
+
+struct DECLSPEC_UUID("28D96C86-10A3-4976-B14E-EAEF4790AA1F") IDebugHostSymbolEnumerator;
+struct DECLSPEC_UUID("0F819103-87DE-4e96-8277-E05CD441FB22") IDebugHostSymbol;
+struct DECLSPEC_UUID("C9BA3E18-D070-4378-BBD0-34613B346E1E") IDebugHostModule;
+struct DECLSPEC_UUID("3AADC353-2B14-4abb-9893-5E03458E07EE") IDebugHostType;
+struct DECLSPEC_UUID("62787EDC-FA76-4690-BD71-5E8C3E2937EC") IDebugHostConstant;
+struct DECLSPEC_UUID("E06F6495-16BC-4cc9-B11D-2A6B23FA72F3") IDebugHostField;
+struct DECLSPEC_UUID("A3D64993-826C-44fa-897D-926F2FE7AD0B") IDebugHostData;
+struct DECLSPEC_UUID("B94D57D2-390B-40f7-B5B4-B6DB897D974B") IDebugHostBaseClass;
+struct DECLSPEC_UUID("6C597AC9-FB4D-4f6d-9F39-22488539F8F4") IDebugHostPublic;
+
+struct DECLSPEC_UUID("B28632B9-8506-4676-87CE-8F7E05E59876") IDebugHostType2;
+struct DECLSPEC_UUID("4F3E1CE2-86B2-4C7A-9C65-D0A9D0EECF44") IDebugHostStatus;
+struct DECLSPEC_UUID("3B362B0E-89F0-46c6-A663-DFDC95194AEF") IDataModelScriptClient;
+struct DECLSPEC_UUID("1303DEC4-FA3B-4F1B-9224-B953D16BABB5") IDataModelScriptTemplate;
+struct DECLSPEC_UUID("7B4D30FC-B14A-49f8-8D87-D9A1480C97F7") IDataModelScript;
+struct DECLSPEC_UUID("513461E0-4FCA-48ce-8658-32F3E2056F3B") IDataModelScriptProvider;
+struct DECLSPEC_UUID("6FD11E33-E5AD-410b-8011-68C6BC4BF80D") IDataModelScriptManager;
+struct DECLSPEC_UUID("95BA00E2-704A-4fe2-A8F1-A7E7D8FB0941") IDataModelScriptProviderEnumerator;
+struct DECLSPEC_UUID("B70334A4-B92C-4570-93A1-D3EB686649A0") IDebugHostScriptHost;
+struct DECLSPEC_UUID("014D366A-1F23-4981-9219-B2DB8B402054") IDataModelScriptHostContext;
+struct DECLSPEC_UUID("AF352B7B-8292-4c01-B360-2DC3696C65E7") IDataModelNameBinder;
+struct DECLSPEC_UUID("69CE6AE2-2268-4e6f-B062-20CE62BFE677") IDataModelScriptTemplateEnumerator;
+
+struct DECLSPEC_UUID("E7983FA1-80A7-498c-988F-518DDC5D4025") IDynamicKeyProviderConcept;
+struct DECLSPEC_UUID("95A7F7DD-602E-483f-9D06-A15C0EE13174") IDynamicConceptProviderConcept;
+struct DECLSPEC_UUID("80E2F7C5-7159-4e92-887E-7E0347E88406") IModelKeyReference2;
+struct DECLSPEC_UUID("A117A435-1FB4-4092-A2AB-A929576C1E87") IDebugHostEvaluator2;
+
+struct DECLSPEC_UUID("21515B67-6720-4257-8A68-077DC944471C") IDebugHostSymbol2;
+struct DECLSPEC_UUID("F412C5EA-2284-4622-A660-A697160D3312") IDataModelManager2;
+struct DECLSPEC_UUID("EEA033DE-38F6-416b-A251-1D3771001270") IDebugHostMemory2;
+
+struct DECLSPEC_UUID("3C2B24E1-11D0-4f86-8AE5-4DF166F73253") IDebugHostExtensibility;
+
+struct DECLSPEC_UUID("DE8E0945-9750-4471-AB76-A8F79D6EC350") IDataModelScriptDebug;
+struct DECLSPEC_UUID("53159B6D-D4C4-471b-A863-5B110CA800CA") IDataModelScriptDebugClient;
+struct DECLSPEC_UUID("051364DD-E449-443e-9762-FE578F4A5473") IDataModelScriptDebugStack;
+struct DECLSPEC_UUID("DEC6ED5E-6360-4941-AB4C-A26409DE4F82") IDataModelScriptDebugStackFrame;
+struct DECLSPEC_UUID("0F9FEED7-D045-4ac3-98A8-A98942CF6A35") IDataModelScriptDebugVariableSetEnumerator;
+struct DECLSPEC_UUID("6BB27B35-02E6-47cb-90A0-5371244032DE") IDataModelScriptDebugBreakpoint;
+struct DECLSPEC_UUID("39484A75-B4F3-4799-86DA-691AFA57B299") IDataModelScriptDebugBreakpointEnumerator;
+struct DECLSPEC_UUID("CBB10ED3-839E-426c-9243-E23535C1AE1A") IDataModelScriptDebug2;
+
+struct DECLSPEC_UUID("A7830646-9F0C-4a31-BA19-503F33E6C8A3") IComparableConcept;
+struct DECLSPEC_UUID("C52D5D3D-609D-4d5d-8A82-46B0ACDEC4F4") IEquatableConcept;
+
+struct DECLSPEC_UUID("B51887E8-BCD0-4e8f-A8C7-434398B78C37") IDebugHostModule2;
+
+//
+// ModelObjectKind:
+//
+// Describes what an IModelObject is intrinsically.
+//
+enum ModelObjectKind
+{
+    // The model object is a property accessor which can be called to retrieve value, etc...
+    //
+    // Calling GetIntrinsicValue on the object will yield a variant in which the punkVal
+    // IUnknown pointer is an IModelPropertyAccessor.
+    //
+    ObjectPropertyAccessor,
+
+    // The model object is a wrapped host context (allowing such to be used as an indexer, etc...)
+    //
+    // Calling GetIntrinsicValue on the object will yield a variant in which the punkVal
+    // IUnknown pointer is an IDebugHostContext.
+    //
+    ObjectContext,
+
+    // It's a typed object within the debuggee.  It may or may not have a model associated with it.
+    // If it has a model, key/value pairs may be associated.
+    //
+    // This object type has no "intrinsic value".  It always has a location which can be acquired.
+    //
+    ObjectTargetObject,
+
+    // It's a reference to an object within the debuggee (e.g.: the object *REFERS TO* a "target int" or a
+    // "target int&").  This is distinct from an object within the debuggee which is a reference (e.g.:
+    // the object *IS* a "target int&").
+    //
+    // This allows an evaluator or other client of the model to take a "reference" to a "reference"
+    // (object reference to a int&) or to take a "reference" to an object which is enregistered.
+    //
+    // This object type has no "intrinsic value".  It always has a location which can be acquired.
+    // The underlying object can be acquired through the Dereference method.
+    //
+    ObjectTargetObjectReference,
+
+    // The model object is a synthetic object (a key/value/metadata store)
+    //
+    // This object type has no "intrinsic value" or location.  It is purely a key/value/metadata store.
+    //
+    ObjectSynthetic,
+
+    // The model object represents no value.  If a given key exists but only has a value conditionally (e.g.: it's
+    // a property accessor), it can return NoValue to indicate this.  The caller should treat this appropriately (e.g.:
+    // not displaying the key/value in a visualization, etc...)
+    //
+    // This object type has no "intrinsic value" or location.
+    //
+    ObjectNoValue,
+
+    // The model object represents an error.
+    //
+    // This object type has no "intrinsci value" or location.  It can always be converted to a string to determine
+    // the error message.
+    //
+    ObjectError,
+
+    // The type is an intrinsic which is communicated through a variant (and the resulting variant type)
+    //
+    // Calling GetIntrinsicValue on this type will yield a variant in which the value has been packed in
+    // its natural form.  String objects are packed as VT_BSTR.
+    //
+    ObjectIntrinsic,
+
+    // The model object is a method which can be called.
+    //
+    // Calling GetIntrinsicValue on the object will yield a variant in which the punkVal
+    // IUnknown pointer is an IModelMethod.
+    //
+    ObjectMethod,
+
+    // The model object is a key reference.
+    //
+    // Calling GetIntrinsicValue on the object will yield a variant in which the punkVal
+    // IUnknown pointer is an IKeyReference.
+    //
+    ObjectKeyReference,
+
+};
+
+// SymbolKind:
+//
+// Defines the kind of a symbol.
+//
+enum SymbolKind
+{
+    // Unspecified symbol type.
+    Symbol,
+
+    // The symbol is a module and is QI'able for IDebugHostModule
+    SymbolModule,
+
+    // The symbol is a type and is QI'able for IDebugHostType
+    SymbolType,
+
+    // The symbol is a field and is QI'able for IDebugHostField
+    SymbolField,
+
+    // The symbol is a constant and is QI'able for IDebugHostConstant
+    SymbolConstant,
+
+    // The symbol is data which is not a field of a structure and is QI'able for IDebugHostData
+    SymbolData,
+
+    // The symbol is a base class and is QI'able for IDebugHostBaseClass
+    SymbolBaseClass,
+
+    // The symbol is a public symbol and is QI'able for IDebugHostPublic
+    SymbolPublic,
+
+    // The symbol is a function symbol and is QI'able for IDebugHostData
+    SymbolFunction,
+};
+
+// TypeKind:
+//
+// Defines the kind of a type.
+//
+enum TypeKind
+{
+    // The type is a UDT (user defined type -- a struct, class, etc...)
+    //
+    // The canonical form of an IModelObject which represents a UDT *value* is
+    // ObjectTargetObject where the type is always kept.
+    //
+    TypeUDT,
+
+    // The type is a pointer
+    //
+    // The canonical form of an IModelObject which represents a pointer *value* is
+    // ObjectIntrinsic where the type is always kept.  The value of the pointer
+    // is zero extended to 64-bits and can be retrieved with a fetch of the intrinsic
+    // value of the object.  The value is packed into the VT_UI8 (ullVal) field of
+    // the object's variant data.
+    //
+    // The base type of a pointer as returned by GetBaseType() is the type pointed to.
+    //
+    TypePointer,
+
+    // The type is a member pointer
+    //
+    // The canonical form of an IModelObject which represents a member pointer *value* is
+    // much the same as that of pointer.  The specific meaning of the intrinsic value
+    // packed into the variant is compiler specific.
+    //
+    TypeMemberPointer,
+
+    // The type is an array
+    //
+    // The canonical form of an IModelObject which represents an array *value* is
+    // ObjectTargetObject where the type is always kept.  The array is always referred
+    // to by a location which can be retrieved via the object's GetLocation() method.
+    // The actual array is not packed into the model object.
+    //
+    // The base type of an array as returned by GetBaseType() is the type of each element
+    // of the array.
+    //
+    TypeArray,
+
+    // The type is a function
+    TypeFunction,
+
+    // **************************************************************************
+    // This entry is **DEPRECATED**.
+    // **************************************************************************
+    //
+    // The canonical form of an IModelObject which is a typedef is the same as the canonical
+    // form of whatever the typedef is for.  A typedef will appear completely transparent to
+    // the user of the object and the type information unless the explicit typedef methods of
+    // IDebugHostType2 are utilized to query typedef information or there is an explicit data
+    // model registered against the typedef.
+    //
+    TypeTypedef,
+
+    // The type is an enum
+    //
+    // The canonical form of an IModelObject which represents an enum *value* is
+    // ObjectIntrinsic where the type is always kept.  The value is packed into
+    // the appropriate type in the object's variant data as described by the
+    // storage type of the enumeration.
+    //
+    TypeEnum,
+
+    // The type is an intrinsic (basic type)
+    //
+    // The canonical form of an IModelObject which represents an intrinsic *value* is
+    // ObjectIntrinsic.  The value is packed into the appropriate tyep in the object's
+    // variant data as indicated by the kind of intrinsic.
+    //
+    // Note that keeping the type information associated with the IModelObject is optional
+    // if the underlying type is fully described by the variant data type (VT_*).
+    //
+    TypeIntrinsic,
+
+    // The type is an array which cannot be expressed as TypeArray.
+    //
+    // This is due to things such as dynamic sizes, dynamic bounds, etc...  CLI arrays are
+    // represented as TypeExtendedArray.
+    //
+    TypeExtendedArray
+};
+
+// IntrinsicKind:
+//
+// Defines the kind of an intrinsic (basic) type.  This is distinct from the variant type
+// which carries the type.
+//
+enum IntrinsicKind
+{
+    // void
+    IntrinsicVoid,
+
+    // bool
+    IntrinsicBool,
+
+    // char
+    IntrinsicChar,
+
+    // wchar_t
+    IntrinsicWChar,
+
+    // signed int (of some size -- not necessarily 4 bytes)
+    IntrinsicInt,
+
+    // unsigned int (of some size -- not necessarily 4 bytes)
+    IntrinsicUInt,
+
+    // long (of some size)
+    IntrinsicLong,
+
+    // unsigned long (of some size)
+    IntrinsicULong,
+
+    // floating point (of some size -- not necessarily 4 bytes)
+    IntrinsicFloat,
+
+    // HRESULT
+    IntrinsicHRESULT,
+
+    // char16_t
+    IntrinsicChar16,
+
+    // char32_t
+    IntrinsicChar32
+
+};
+
+// PointerKind:
+//
+// Defines the kind of a pointer type.
+//
+enum PointerKind
+{
+    // *
+    PointerStandard,
+
+    // &
+    PointerReference,
+
+    // &&
+    PointerRValueReference,
+
+    // ^
+    PointerCXHat,
+
+    // CLI reference (invisible to the user)
+    PointerManagedReference
+};
+
+// CallingConventionKind:
+//
+// Defines the kind of calling convention of a function type.
+//
+enum CallingConventionKind
+{
+    // The calling convention is not known
+    CallingConventionUnknown,
+
+    // The calling convention is __cdecl
+    CallingConventionCDecl,
+
+    // The calling convention is fastcall
+    CallingConventionFastCall,
+
+    // The calling convention is stdcall
+    CallingConventionStdCall,
+
+    // The calling convention is syscall
+    CallingConventionSysCall,
+
+    // The calling convention is thiscall
+    CallingConventionThisCall,
+
+};
+
+// LocationKind:
+//
+// Defines the location of a field or other data.
+//
+enum LocationKind
+{
+    // The field is a member and has an offset relative to the this pointer
+    LocationMember,
+
+    // The field is static and has an address
+    LocationStatic,
+
+    // The field is constant and has a value
+    LocationConstant,
+
+    // The field has no location (e.g.: it has been optimized out or was a static which was defined but not
+    // declared)
+    LocationNone,
+};
+
+//*************************************************
+// Metadata Keys:
+
+//
+// "PreferredFormat"
+//     contains a value which is from the PreferredFormat enumeration below that indicates the preferred manner in which a given
+//     value should be *DISPLAYED*.  It does not affect the value itself.
+//
+// "PreferredRadix"
+//     contains a value which indicates the preferred display radix for an integral value.  This is either 8, 10, or 16
+//
+
+//
+// PreferredFormat
+//
+// Predefined values of the "PreferredFormat" key which may appear as the metadata on a returned key value.  This indicates
+// the preferred DISPLAY FORMAT for a given value.
+//
+enum PreferredFormat
+{
+    // There is no preferred format
+    FormatNone,
+
+    // The preferred format is a single character as '*'
+    FormatSingleCharacter,
+
+    // The preferred format is a quoted 8-bit string
+    FormatQuotedString,
+
+    // The preferred format is a non-quoted 8-bit string
+    FormatString,
+
+    // The preferred format is a quoted Unicode (UTF-16) string
+    FormatQuotedUnicodeString,
+
+    // The preferred format is a non-quoted Unicode (UTF-16) string
+    FormatUnicodeString,
+
+    // The preferred format is a quoted UTF-8 string
+    FormatQuotedUTF8String,
+
+    // The preferred format is a non-quoted UTF-8 string
+    FormatUTF8String,
+
+    // The preferred format is a quoted BSTR
+    FormatBSTRString,
+
+    // The preferred format is a quoted WinRT HSTRING
+    FormatQuotedHString,
+
+    // The preferred format is a non-quoted WinRT HSTRING
+    FormatHString,
+
+    // The preferred format is the raw (native) type
+    FormatRaw,
+
+    // The preferred format is the enum name only
+    FormatEnumNameOnly,
+
+    // The preferred format is the quoted string with escaped characters
+    FormatEscapedStringWithQuote,
+
+    // The preferred format is a non-quoted Unicode (UTF-32) string
+    FormatUTF32String,
+
+    // The preferred format is a quoted Unicode (UTF-32) string
+    FormatQuotedUTF32String
+};
+
+//
+// IHostDataModelAccess:
+//
+// An interface *suggested* on the per-host extensibility mechanism to get from the host extensibility
+// mechanism to the model based one.  Extensions which are written to a host-specific API set can query
+// this mechanism to get to the data model and create host-agnostic extensions.
+//
+// As an example, DbgEng based extensions can query for this interface from any IDebug* (Client/Control/etc...)
+// interface to get to the model and access model APIs.  Such extensions are hybrid (they are still specific
+// to a particular host but contain portions that may be factored out later for a general model based extension)
+//
+// This is the **ONLY** interface in this set of APIs which is not intended to be host agnostic.
+//
+#undef INTERFACE
+#define INTERFACE IHostDataModelAccess
+DECLARE_INTERFACE_(IHostDataModelAccess, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IKeyStore
+
+    // GetDataModel():
+    //
+    // Returns the core interfaces to the data model.  A hybrid extension can query its host's
+    // extensibility interfaces for IHostDataModelAccess and subsequently call this method to
+    // get to the data model interfaces.
+    //
+    // There is no guarantee that any particular host supports this interface.
+    //
+    STDMETHOD(GetDataModel)(
+        THIS_
+        _COM_Outptr_ IDataModelManager** manager,
+        _COM_Outptr_ IDebugHost** host
+        ) PURE;
+};
+
+//
+// IKeyStore:
+//
+// An interface which represents a set of key/value/metadata tuples.  This is primarily the
+// interface by which metadata is represented.
+//
+#undef INTERFACE
+#define INTERFACE IKeyStore
+DECLARE_INTERFACE_(IKeyStore, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IKeyStore
+
+    // GetKey():
+    //
+    // If the store or its parent has a key named according to the argument 'key', this will
+    // return the value of that key and, optionally, any metadata associated with that key.
+    //
+    // If the key is a property accessor, this API will return the property accessor itself.  It is the responsibility
+    // of the caller to resolve the property by fetching the IModelPropertyAccessor interface and calling into it
+    // passing the appropriate context object.
+    //
+    STDMETHOD(GetKey)(
+        THIS_
+        _In_ PCWSTR key,
+        _COM_Errorptr_opt_ IModelObject** object,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // SetKey():
+    //
+    // If the store or its parent has a key named according to the argument 'key', this will
+    // set the value of that key and optionally its associated metadata.
+    //
+    // If the key is a property accessor, this will not set the value of the property.  It will explicitly
+    // overwrite the property with the new value.
+    //
+    // This is the only method which is capable of creating a new key.  If a new key is to be created, this
+    // will create the key on the store where SetKey was called.  It will not create a key on the parent store.
+    //
+    STDMETHOD(SetKey)(
+        THIS_
+        _In_ PCWSTR key,
+        _In_opt_ IModelObject* object,
+        _In_opt_ IKeyStore* metadata
+        ) PURE;
+
+    // GetKeyValue():
+    //
+    // If the store or its parent has a key named according to the argument 'key', this will
+    // return the value of that key and, optionally, any metadata associated with that key.
+    //
+    // If the key is a property accessor, this API will fetch the value underlying the property and return it.
+    // It will not return the IModelPropertyAccessor interface for the property.
+    //
+    STDMETHOD(GetKeyValue)(
+        THIS_
+        _In_ PCWSTR key,
+        _COM_Errorptr_opt_ IModelObject** object,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // SetKeyValue():
+    //
+    // If the store or its parent has a key named according to the argument 'key', this will
+    // set the value of that key.
+    //
+    // If the key is a property accessor, this API will call the underlying property to set the value of the
+    // property.  Note that some properties are read-only and, as such, this API may return a failure if called
+    // on such a property.  If the key is not a property accessor, it will overwrite the value of the key directly.
+    //
+    // This method will never create a new key named 'key'.
+    //
+    STDMETHOD(SetKeyValue)(
+        THIS_
+        _In_ PCWSTR key,
+        _In_ IModelObject* object
+        ) PURE;
+
+    // ClearKeys():
+    //
+    // This will clear all keys on the store but *NOT* on its parent.
+    //
+    STDMETHOD(ClearKeys)(
+        THIS
+        ) PURE;
+
+};
+
+// RawSearchFlags:
+//
+// Flags to GetRawValue/EnumerateRawValues
+//
+enum RawSearchFlags
+{
+    // There are no search flags
+    RawSearchNone = 0x00000000,
+
+    // Indicates that the search should not recurse to base children (e.g.: base classes).  Only names/types
+    // which are in the object itself should be returned.
+    RawSearchNoBases = 0x00000001,
+};
+
+//
+// IModelObject:
+//
+// The core object model interface.  All object instances that the model can represent are directly referred
+// to by the IModelObject interface.
+//
+// This interface is never directly implemented by a client.
+//
+#undef INTERFACE
+#define INTERFACE IModelObject
+DECLARE_INTERFACE_(IModelObject, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IModelObject
+
+    // Client Methods:
+
+    // GetContext():
+    //
+    // Gets the host (debugger) context that is associated with this object.
+    //
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_result_maybenull_ IDebugHostContext** context
+        ) PURE;
+
+    // GetKind():
+    //
+    // Gets the kind of this object.  This indicates the kind of object (e.g.: a boxed intrinsic value,
+    // an object within the address space of the debug target, a synthetic object created by the
+    // debugger, an error, etc...).  This does not indicate the language type of the object.
+    //
+    STDMETHOD(GetKind)(
+        THIS_
+        _Out_ ModelObjectKind *kind
+        ) PURE;
+
+    // GetIntrinsicValue():
+    //
+    // If the object has an intrinsic value because it is a boxed intrinsic, a pointer, or a construct
+    // which has an associated IUnknown, this will return the intrinsic value of the object as a
+    // VARIANT.
+    //
+    // If the object does not have an intrinsic value (e.g.: it is a completely synthetic object), calling
+    // this API will result in an error.
+    //
+    STDMETHOD(GetIntrinsicValue)(
+        THIS_
+        _Out_ VARIANT* intrinsicData
+        ) PURE;
+
+    // GetIntrinsicValueAs():
+    //
+    // If the object has an intrinsic value because it is a boxed intrinsic, a pointer, or a construct
+    // which has an associated IUnknown, this will return the intrinsic value of the object converted
+    // to the variant type passed in the 'vt' argument.  If the value cannot be converted to the given
+    // variant type, this will return an error.
+    //
+    STDMETHOD(GetIntrinsicValueAs)(
+        THIS_
+        _In_ VARTYPE vt,
+        _Out_ VARIANT* intrinsicData
+        ) PURE;
+
+    // GetKeyValue():
+    //
+    // If the object or one of its parent models has a key named according to the argument 'key', this will
+    // return the value of that key and, optionally, any metadata associated with that key.
+    //
+    // If the key is a property accessor, this API will fetch the value underlying the property and return it.
+    // It will not return the IModelPropertyAccessor interface for the property.
+    //
+    STDMETHOD(GetKeyValue)(
+        THIS_
+        _In_ PCWSTR key,
+        _COM_Errorptr_opt_ IModelObject** object,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // SetKeyValue():
+    //
+    // If the object or one of its parent models has a key named according to the argument 'key', this will
+    // set the value of that key.
+    //
+    // If the key is a property accessor, this API will call the underlying property to set the value of the
+    // property.  Note that some properties are read-only and, as such, this API may return a failure if called
+    // on such a property.  If the key is not a property accessor, it will overwrite the value of the key directly.
+    //
+    // This method will never create a new key named 'key'.
+    //
+    STDMETHOD(SetKeyValue)(
+        THIS_
+        _In_ PCWSTR key,
+        _In_opt_ IModelObject* object
+        ) PURE;
+
+    // EnumerateKeyValues():
+    //
+    // This returns an enumerator which will enumerate all keys and their associated values on this object and
+    // any of its parent values.  Note that if any of the enumerated values are property accessors, the underlying
+    // property will be fetched and returned by the enumerator.  This will never return an object which is an
+    // IModelPropertyAccessor.
+    //
+    STDMETHOD(EnumerateKeyValues)(
+        THIS_
+        _COM_Outptr_ IKeyEnumerator** enumerator
+        ) PURE;
+
+    // GetRawValue():
+    //
+    // If the object represents an object within the address space of the debug target which has children (e.g.: a user
+    // defined type such as a struct or class), this will attempt to return the child named 'name'.  The kind of child
+    // being sought (e.g.: field, base class, etc...) should be passed in the 'kind' argument.
+    //
+    // If no child named 'name' can be found, this method will fail.  If there is an ambiguity presented by 'name', an
+    // error will be returned.
+    //
+    STDMETHOD(GetRawValue)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_ PCWSTR name,
+        _In_ ULONG searchFlags,
+        _COM_Errorptr_ IModelObject** object
+        ) PURE;
+
+    // EnumerateRawValues():
+    //
+    // This returns an enumerator which will enumerate all raw (native) children of the object of the kind 'kind'.
+    //
+    STDMETHOD(EnumerateRawValues)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_ ULONG searchFlags,
+        _COM_Outptr_ IRawEnumerator** enumerator
+        ) PURE;
+
+    // Dereference():
+    //
+    // If the object in question is something which is dereferencable (e.g.: a pointer or reference), calling this API will
+    // return the dereferenced object.  Calling this API on a non-dereferencable object will result in an error being returned.
+    //
+    STDMETHOD(Dereference)(
+        THIS_
+        _COM_Errorptr_ IModelObject** object
+        ) PURE;
+
+    // TryCastToRuntimeType():
+    //
+    // If the debug host can identify the runtime type of this object (e.g.: the most derived class), calling this method
+    // will return that object.  If the debug host cannot identify such runtime type or the present object is the runtime
+    // type, the output object 'runtimeTypedObject' will be this object.
+    // A given object can specify it's "runtime type" by implementing the IPreferredRuntimeTypeConcept concept. If that concept
+    // is not implemented the debug host method will be used.
+    //
+    // Note that it is possible for this method to fail for a variety of reasons (e.g.: inability to locate symbols, etc...).
+    //
+    STDMETHOD(TryCastToRuntimeType)(
+        THIS_
+        _COM_Errorptr_ IModelObject** runtimeTypedObject
+        ) PURE;
+
+    // GetConcept():
+    //
+    // If the object or one of its parent models has a concept identified by the IID contained in the 'conceptId'
+    // argument, this will return the concept interface in the 'conceptInterface' argument.  This is the only valid method
+    // of acquiring any concept interface.  Concept interfaces should not attempt to be accessed via a QueryInterface
+    // call.
+    //
+    STDMETHOD(GetConcept)(
+        THIS_
+        _In_ REFIID conceptId,
+        _COM_Outptr_ IUnknown** conceptInterface,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** conceptMetadata
+        ) PURE;
+
+    // GetLocation():
+    //
+    // If the object represents an object in the address space of the debug target, this will return the address
+    // of the object.
+    //
+    // It is a failure to call this API on any type other than one which declares that it is a TargetObjectType via the
+    // GetKind method.
+    //
+    STDMETHOD(GetLocation)(
+        THIS_
+        _Out_ Location* location
+        ) PURE;
+
+    // GetTypeInfo():
+    //
+    // If the object has an associated type (native language type), this will return an interface representing that type.
+    // Note that if a given type is inherently described by the type of a VARIANT structure, it will not have associated
+    // type information.
+    //
+    // If the object does not have associated type information, this API will return 'nullptr'.  This is not a failure.
+    //
+    STDMETHOD(GetTypeInfo)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    // GetTargetInfo():
+    //
+    // If the object represents an object in the address space of the debug target, this will return both the address
+    // of the object and the type (native language type) of the object.  The type returned from this method is identical
+    // to the one returned from the GetTypeInfo method.
+    //
+    // It is a failure to call this API on any type other than one which declares that it is a TargetObjectType via the
+    // GetType method.
+    //
+    STDMETHOD(GetTargetInfo)(
+        THIS_
+        _Out_ Location* location,
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    // Advanced clients:
+
+    // GetNumberOfParentModels():
+    //
+    // Returns the number of parent models of this object.  An object may have zero or more parent models associated with it.
+    // If the object does not have a given key or concept when queried, such calls are passed to all parent models in
+    // linear order to satisfy the request.
+    //
+    STDMETHOD(GetNumberOfParentModels)(
+        _Out_ ULONG64* numModels
+        ) PURE;
+
+    // GetParentModel():
+    //
+    // Returns the 'i'-th parent model of this object and, optionally, the adjusted context object associated with that
+    // parent model.
+    //
+    // If the object does not have a given key or concept when queried, such calls are passed to all parent models in
+    // linear order to satisfy the request.  A parent model may also adjust the context (effective this pointer) object.  If
+    // the model performs such adjustment, the adjusted object is returned in the 'contextObject' argument.  If not,
+    // nullptr is returned in the 'contextObject' argument.
+    //
+    STDMETHOD(GetParentModel)(
+        _In_ ULONG64 i,
+        _COM_Outptr_ IModelObject **model,
+        _COM_Outptr_result_maybenull_ IModelObject **contextObject
+        ) PURE;
+
+    // AddParentModel():
+    //
+    // Adds a new parent model to this object.  If the object does not have a given key or concept when queried, such calls are
+    // passed to all parent models in linear order to satisfy the request.
+    //
+    // If the parent model needs to adjust the context (effective this pointer) object so that property accessors and other
+    // concept interfaces on the parent model receive a different context pointer than the object itself, such an adjusted context
+    // can be passed in the 'contextObject' argument.  If no adjustment is necessary, nullptr should be passed.  Note that it
+    // is perfectly legitimate for the object passed in 'contextObject' to be a property accessor.  In that case, the property
+    // will always be resolved before being given to any caller of GetParentModel or passed to any other accessor or concept.
+    //
+    // If this model should take precedence over any other parent models, the 'override' argument should be 'true'; otherwise,
+    // it should be 'false' and the new model will be added last in search order.
+    //
+    STDMETHOD(AddParentModel)(
+        THIS_
+        _In_ IModelObject* model,
+        _In_opt_ IModelObject* contextObject,
+        _In_ bool override) PURE;
+
+    // RemoveParentModel():
+    //
+    // Removes a parent model as indicated by the 'model' argument from the list of parent models of this object.
+    //
+    STDMETHOD(RemoveParentModel)(
+        THIS_
+        _In_ IModelObject* model
+        ) PURE;
+
+    // GetKey():
+    //
+    // If the object or one of its parent models has a key named according to the argument 'key', this will
+    // return the value of that key and, optionally, any metadata associated with that key.
+    //
+    // If the key is a property accessor, this API will return the property accessor itself.  It is the responsibility
+    // of the caller to resolve the property by fetching the IModelPropertyAccessor interface and calling into it
+    // passing the appropriate context object.
+    //
+    STDMETHOD(GetKey)(
+        THIS_
+        _In_ PCWSTR key,
+        _COM_Errorptr_opt_ IModelObject** object,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // GetKeyReference():
+    //
+    // If the object or one of its parent models has a key named according to the argument 'key', this will
+    // return a reference to that key (and optionally the *present* metadata associated with that key).
+    //
+    STDMETHOD(GetKeyReference)(
+        THIS_
+        _In_ PCWSTR key,
+        _COM_Errorptr_opt_ IModelObject** objectReference,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // SetKey():
+    //
+    // If the object or one of its parent models has a key named according to the argument 'key', this will
+    // set the value of that key and optionally its associated metadata.
+    //
+    // If the key is a property accessor, this will not set the value of the property.  It will explicitly
+    // overwrite the property with the new value.
+    //
+    // This is the only method which is capable of creating a new key.  If a new key is to be created, this
+    // will create the key on the object where SetKey was called.  It will not create a key on a parent
+    // model.
+    //
+    STDMETHOD(SetKey)(
+        THIS_
+        _In_ PCWSTR key,
+        _In_opt_ IModelObject* object,
+        _In_opt_ IKeyStore* metadata
+        ) PURE;
+
+    // ClearKeys():
+    //
+    // This will clear all keys on the object but *NOT* on the parents that are attached to the object.
+    //
+    STDMETHOD(ClearKeys)(
+        THIS
+        ) PURE;
+
+    // EnumerateKeys():
+    //
+    // This returns an enumerator which will enumerate all keys and their associated values on this object and
+    // any of its parent values.  Note that if any of the enumerated values are property accessors, the underlying
+    // value will not be fetched.  The enumerator will instead return the property accessor object.  It is the responsibility
+    // of the user of the enumerator to resolve the property value by fetching the IModelPropertyAccessor interface and
+    // calling into it passing the appropriate context object.
+    //
+    STDMETHOD(EnumerateKeys)(
+        THIS_
+        _COM_Outptr_ IKeyEnumerator** enumerator
+        ) PURE;
+
+    // EnumerateKeyReferences():
+    //
+    // This returns an enumerator which will enumerate all keys on this object and any of its parent values.  This will
+    // return references to those keys rather than the keys themselves.
+    //
+    STDMETHOD(EnumerateKeyReferences)(
+        THIS_
+        _COM_Outptr_ IKeyEnumerator** enumerator
+        ) PURE;
+
+    // SetConcept():
+    //
+    // This sets a concept interface identified by the 'conceptId' argument on the object.  Such concept interfaces
+    // can make the object convertible to a string, iterable, indexable, etc...
+    //
+    STDMETHOD(SetConcept)(
+        THIS_
+        _In_ REFIID conceptId,
+        _In_ IUnknown* conceptInterface,
+        _In_opt_ IKeyStore* conceptMetadata
+        ) PURE;
+
+    // ClearConcepts():
+    //
+    // This clears all concepts on the object but *NOT* on the parents that are attached to the object.
+    //
+    STDMETHOD(ClearConcepts)(
+        THIS
+        ) PURE;
+
+    // GetRawReference():
+    //
+    // If the object represents an object within the address space of the debug target which has children (e.g.: a user
+    // defined type such as a struct or class), this will attempt to return a reference to the child named 'name'.  The type
+    // of child being sought (e.g.: field, base class, etc...) should be passed in the 'type' argument.
+    //
+    // If no child named 'name' can be found, this method will fail.  If there is an ambiguity presented by 'name', an
+    // error will be returned.
+    //
+    STDMETHOD(GetRawReference)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_ PCWSTR name,
+        _In_ ULONG searchFlags,
+        _COM_Errorptr_ IModelObject** object
+        ) PURE;
+
+    // EnumerateRawReferences():
+    //
+    // This returns an enumerator which will enumerate references to all raw (native) children of the object of the type 'type'.
+    //
+    STDMETHOD(EnumerateRawReferences)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_ ULONG searchFlags,
+        _COM_Outptr_ IRawEnumerator** enumerator
+        ) PURE;
+
+    // SetContextForDataModel():
+    //
+    // This method allows a parent data model which is linked to multiple instance objects to add cache information to each
+    // instance object.  The model object for the data model is passed in the 'dataModelObject' interface and an IUnknown
+    // which represents the information to cache is passed in the 'context' argument.  When the instance object destructs,
+    // it will release the cached information.
+    //
+    STDMETHOD(SetContextForDataModel)(
+        THIS_
+        _In_ IModelObject* dataModelObject,
+        _In_ IUnknown* context
+        ) PURE;
+
+    // GetContextForDataModel():
+    //
+    // If a parent model has associated cached information with an instance through a prior call to SetContextForDataModel,
+    // this method allows the parent model to fetch the previously stored information.  The model object for the data model
+    // is passed in the 'dataModelObject' argument.
+    //
+    // Note that a lack of cache information is not a failure.  The returned 'context' argument will simply be nullptr in this
+    // case.
+    //
+    STDMETHOD(GetContextForDataModel)(
+        THIS_
+        _In_ IModelObject* dataModelObject,
+        _Out_ IUnknown** context
+        ) PURE;
+
+    // Compare():
+    //
+    // Compares this object against another object.  Returns -1 (this < other), 0 (this == other), or 1 (this > other).
+    // If the objects cannot be compared, a failure occurs.
+    //
+    // Only intrinsic values may be compared using this method.
+    //
+    STDMETHOD(Compare)(
+        THIS_
+        _In_ IModelObject* other,
+        _COM_Outptr_opt_result_maybenull_ IModelObject **ppResult
+        ) PURE;
+
+    // IsEqualTo():
+    //
+    // Compares this object against another object.  Returns true or false as to whether the objects are equal.
+    // For objects which have an ordering, this returning true is equivalent to Compare(...) returning 0.  For objects
+    // that have no ordering but are equatable, Compare(...) will fail, but this will not.
+    //
+    // Note that this is a value based comparison as defined by the type.
+    //
+    STDMETHOD(IsEqualTo)(
+        THIS_
+        _In_ IModelObject* other,
+        _Out_ bool* equal
+        ) PURE;
+
+};
+
+//
+// IDataModelManager:
+//
+// The core interface for the data model manager.  This is the interface by which new objects are created,
+// intrinsic values are boxed and unboxed, and models are registered for types.
+//
+// This interface is never directly implemented by a client.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelManager
+DECLARE_INTERFACE_(IDataModelManager, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelManager
+
+    // Close():
+    //
+    // Cleanup method for the data model manager.  This **MUST** be called when a host is shutting down the data model
+    // manager prior to releasing its reference to the manager.
+    //
+    STDMETHOD(Close)(
+        THIS
+        ) PURE;
+
+
+    // CreateNoValue():
+    //
+    // Creates an object which represents nothing.  In essence, this appears like "void".  A property
+    // which does not exist for a particular instance of an object may return "NoValue" instead of an error.
+    // A parent model which is a property accessor but only applies to some objects may return "NoValue"
+    // instead of an error.
+    //
+    // "NoValue" objects will not be displayed by many clients.
+    //
+    STDMETHOD(CreateNoValue)(
+        THIS_
+        _Out_ IModelObject** object
+        ) PURE;
+
+    // CreateErrorObject():
+    //
+    // Creates an object which encapsulates a failure (code and message).
+    //
+    STDMETHOD(CreateErrorObject)(
+        THIS_
+        _In_ HRESULT hrError,
+        _In_opt_ PCWSTR pwszMessage,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    // CreateTypedObject():
+    //
+    // Creates an object within the address space of the host at the supplied location.  If a particular
+    // host context is passed, the object will acquire that context; otherwise -- the object will inherit
+    // its context from that of the supplied type.
+    //
+    // If the given object location is an *offset* from a location fetched from another object (e.g.: it is
+    // a field of that object), the context supplied here should be explicitly passed from object where
+    // that location came from.
+    //
+    // CreateTypedObject may return an error object in the output argument even in the case of failure.
+    //
+    STDMETHOD(CreateTypedObject)(
+        THIS_
+        _In_opt_ IDebugHostContext* context,
+        _In_ Location objectLocation,
+        _In_ IDebugHostType* objectType,
+        _COM_Errorptr_ IModelObject** object
+        ) PURE;
+
+    // CreateTypedObjectReference():
+    //
+    // Creates a reference to an object within the address space of the host.  This is a reference as defined
+    // by the model API, not a reference as defined by the language.
+    //
+    // In respects other than creating a reference, this behaves as per CreateTypedObject.
+    //
+    STDMETHOD(CreateTypedObjectReference)(
+        THIS_
+        _In_opt_ IDebugHostContext* context,
+        _In_ Location objectLocation,
+        _In_ IDebugHostType* objectType,
+        _COM_Errorptr_ IModelObject** object
+        ) PURE;
+
+    // CreateSyntheticObject():
+    //
+    // Creates an empty synthetic object (a store of key/value/metadata tuples).
+    //
+    STDMETHOD(CreateSyntheticObject)(
+        THIS_
+        _In_opt_ IDebugHostContext* context,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    // CreateDataModelObject():
+    //
+    // Creates a synthetic object designed to be a data model.  This method is a convenience for the caller.
+    // The resulting syntehtic object is an empty synthetic object onto which the supplied data model concept
+    // has been added via SetConcept().
+    //
+    STDMETHOD(CreateDataModelObject)(
+        THIS_
+        _In_ IDataModelConcept* dataModel,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    // CreateIntrinsicObject():
+    //
+    // Creates an object representing an intrinsic value.  In some language parlences, this would be called
+    // "boxing" a value.
+    //
+    // The full type of the value is defined by the VARIANT in which it is carried.  For values which have
+    // ancillary type information (e.g.: enumerations), CreateTypedIntrinsicObject can be used.
+    //
+    STDMETHOD(CreateIntrinsicObject)(
+        THIS_
+        _In_ ModelObjectKind objectKind,
+        _In_ VARIANT* intrinsicData,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    // CreateTypedIntrinsicObject():
+    //
+    // Similar to CreateIntrinsicObject(), this creates a value object which has ancillary type information.
+    // Ancillary type information is used for enumerations, pointer types, and other things which have an
+    // inherit value but by which that value is interpreted differently than just the bits of the value.
+    //
+    STDMETHOD(CreateTypedIntrinsicObject)(
+        THIS_
+        _In_ VARIANT* intrinsicData,
+        _In_ IDebugHostType* type,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    // GetModelForTypeSignature():
+    //
+    // Returns the model currently registered for a given type signature.  Such registration can be performed
+    // by calling RegisterModelForTypeSignature().
+    //
+    STDMETHOD(GetModelForTypeSignature)(
+        THIS_
+        _In_ IDebugHostTypeSignature* typeSignature,
+        _Out_ IModelObject** dataModel
+        ) PURE;
+
+    // GetModelForType():
+    //
+    // Returns the model (registered via RegisterModelForTypeSignature) whose type signature is the best
+    // match for the given type.  In addition to returning the registered model, the type signature
+    // and a list of wildcard matches between the signature and the actual type is also returned.
+    //
+    STDMETHOD(GetModelForType)(
+        THIS_
+        _In_ IDebugHostType* type,
+        _COM_Outptr_ IModelObject** dataModel,
+        _COM_Outptr_opt_ IDebugHostTypeSignature** typeSignature,
+        _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches
+        ) PURE;
+
+    // RegisterModelForTypeSignature():
+    //
+    // Registers a model for a given type signature.  Any object which has a type that matches the signature
+    // will have the inpassed model applied as a parent model of the object when the object is created.
+    //
+    STDMETHOD(RegisterModelForTypeSignature)(
+        THIS_
+        _In_ IDebugHostTypeSignature* typeSignature,
+        _In_ IModelObject* dataModel
+        ) PURE;
+
+    // UnregisterModelForTypeSignature():
+    //
+    // Undoes a prior call to RegisterModelForTypeSignature().  Newly created objects of the type which matches
+    // the supplied signature will no longer have the supplied data model applied as a parent model.
+    //
+    // Note that calling this method has no effect on pre-existing objects which matched the signature.
+    //
+    STDMETHOD(UnregisterModelForTypeSignature)(
+        THIS_
+        _In_ IModelObject* dataModel,
+        _In_opt_ IDebugHostTypeSignature* typeSignature
+        ) PURE;
+
+    // RegisterExtensionForTypeSignature():
+    //
+    // Registers an extension for a given type signature.  Any object which has a type signature that matches the signature
+    // will have the inpassed model applied as a parent model of the object when the object is created.
+    //
+    // Unlike RegisterModelForTypeSignature -- which affects the single CANONICAL model for a given type signature
+    // and can have no ambiguous registrations -- any number of extensions can be registered against a type signature
+    // (or multiple ambiguous type signatures).  All such extensions will be automatically attached.
+    //
+    STDMETHOD(RegisterExtensionForTypeSignature)(
+        THIS_
+        _In_ IDebugHostTypeSignature* typeSignature,
+        _In_ IModelObject* dataModel
+        ) PURE;
+
+    // UnregisterExtensionForTypeSignature():
+    //
+    // Behaves as UnregisterModelForTypeSignature excepting that it undoes RegisterExtensionForTypeSignature.
+    //
+    STDMETHOD(UnregisterExtensionForTypeSignature)(
+        THIS_
+        _In_ IModelObject* dataModel,
+        _In_opt_ IDebugHostTypeSignature* typeSignature
+        ) PURE;
+
+    // CreateMetadataStore():
+    //
+    // Creates a new key store for metadata.  Any tagging of metadata onto key names is done by creating such
+    // an object, filling it, and passing it to SetKey().
+    //
+    STDMETHOD(CreateMetadataStore)(
+        THIS_
+        _In_opt_ IKeyStore* parentStore,
+        _COM_Outptr_ IKeyStore** metadataStore
+        ) PURE;
+
+    // GetRootNamespace():
+    //
+    // Gets the root namespace which is managed by the data model.  A host and its extensions have full control
+    // of what goes into this namespace.
+    //
+    STDMETHOD(GetRootNamespace)(
+        THIS_
+        _COM_Outptr_ IModelObject** rootNamespace
+        ) PURE;
+
+    // RegisterNamedModel():
+    //
+    // Associates a given data model with a well defined name.  This name can then be used to look up the data model.
+    // All of the data models which the model itself creates are well named and registered via this mechanism.
+    //
+    STDMETHOD(RegisterNamedModel)(
+        THIS_
+        _In_ PCWSTR modelName,
+        _In_ IModelObject *modeObject
+        ) PURE;
+
+    // UnregisterNamedModel():
+    //
+    // Removes the registration of a given name.  This undoes a prior call to RegisterNamedModel().
+    //
+    STDMETHOD(UnregisterNamedModel)(
+        THIS_
+        _In_ PCWSTR modelName
+        ) PURE;
+
+    // AcquireNamedModel():
+    //
+    // This looks up a well known model name and returns the data model registered by that name.  Note that if
+    // there is no model registered by the supplied name, a stub will be created and returned to the caller.
+    // Anything added to the stub will be added to the real object at the time a registration is made.
+    //
+    STDMETHOD(AcquireNamedModel)(
+        THIS_
+        _In_ PCWSTR modelName,
+        _COM_Outptr_ IModelObject **modelObject
+        ) PURE;
+};
+
+//
+// IModelKeyReference:
+//
+// Represents a reference to a key which can be resolved (dereferenced) to get the underlying key.
+//
+// This interface is never directly implemented by a client.
+//
+#undef INTERFACE
+#define INTERFACE IModelKeyReference
+DECLARE_INTERFACE_(IModelKeyReference, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IModelKeyReference:
+
+    // GetKeyName():
+    //
+    // Gets the name of the key this reference refers to.
+    //
+    STDMETHOD(GetKeyName)(
+        THIS_
+        _Out_ BSTR* keyName
+        ) PURE;
+
+    // GetOriginalObject():
+    //
+    // Gets the object on which the original "GetKeyReference" which produced this
+    // key reference was called.
+    //
+    // If a key reference is resolved to a property accessor with GetKey(), the original
+    // object should be passed as context.  The IModelPropertyAccessor object which
+    // is acquired from the resolution will automatically perform the necessary adjustment
+    // thunk between the return value of this method and the return value of
+    // GetContextObject().
+    //
+    STDMETHOD(GetOriginalObject)(
+        THIS_
+        _COM_Outptr_ IModelObject** originalObject
+        ) PURE;
+
+    // GetContextObject():
+    //
+    // Gets the (potentially adjusted) context object for the key.  If the key was found on
+    // a parent model that had a context adjustor, this will be different from the value returned
+    // in GetOriginalObject; otherwise -- it will be identical.
+    //
+    // This object is not typically needed.
+    //
+    STDMETHOD(GetContextObject)(
+        THIS_
+        _COM_Outptr_ IModelObject** containingObject
+        ) PURE;
+
+    //*************************************************
+    // Accessors:
+    //
+
+    //
+    // These are the **ONLY** valid way to resolve a key reference.  The particular parent model
+    // on which the key was found is not exposed.  There is no way for a caller to fetch
+    // the particular key by using an IModelObject->GetKey(this->GetKeyName()) for any
+    // given IModelObject.
+    //
+
+    // GetKey():
+    //
+    // Resolves (dereferences) the reference and returns the underlying value as if a call to the
+    // "GetKey" method were made on the IModelObject from which this key reference was derived.
+    //
+    // Note that this method will not resolve underlying properties.  If the value of the key is
+    // a property accessor, it will return it.
+    //
+    STDMETHOD(GetKey)(
+        THIS_
+        _COM_Errorptr_opt_ IModelObject** object,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // GetKeyValue():
+    //
+    // Resolves (dereferences) the reference and returns the underlying value as if a call to the
+    // "GetKeyValue" method were made on the IModelObject from which this key reference was derived.
+    //
+    // Note that this method will resolve underlying properties.  If the value of the key is
+    // a property accessor, this API will fetch the value underlying the property and return it.
+    // It will not return the IModelPropertyAccessor interface for the property.
+    //
+    STDMETHOD(GetKeyValue)(
+        THIS_
+        _COM_Errorptr_opt_ IModelObject** object,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // SetKey():
+    //
+    // Resolves (dereferences) the reference and sets the underlying key.  Note that this does not
+    // behave identically to a "SetKey" call on the IModelObject from which this key reference was
+    // derived.
+    //
+    // This will always set the value of the PARTICULAR key to which the reference refers.
+    //
+    STDMETHOD(SetKey)(
+        THIS_
+        _In_opt_ IModelObject* object,
+        _In_opt_ IKeyStore* metadata
+        ) PURE;
+
+    // SetKeyValue():
+    //
+    // Resolves (dereferences) the reference and sets the underlying key.
+    //
+    // Note that this method will resolve underlying properties.  If the value of the key is
+    // a property accessor, this API will call the set method on the underlying property.
+    //
+    STDMETHOD(SetKeyValue)(
+        THIS_
+        _In_ IModelObject* object
+        ) PURE;
+};
+
+//
+// IModelPropertyAccessor:
+//
+// Represents a read-only or read-write property on an object.  A client which only wishes to fetch the value
+// of a property would normally call a "GetKeyValue" method on an object and not deal directly with this interface.
+//
+// Extensions which implement properties would implement this interface one or more times for the properties
+// which it provides.
+//
+#undef INTERFACE
+#define INTERFACE IModelPropertyAccessor
+DECLARE_INTERFACE_(IModelPropertyAccessor, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IModelPropertyAccessor:
+
+    // GetValue():
+    //
+    // Gets the underlying value of the property.  The name of the key and the original context object
+    // passed to the "GetKey" method that returned this property accessor must be passed to this
+    // call.
+    //
+    STDMETHOD(GetValue)(
+        THIS_
+        _In_ PCWSTR key,
+        _In_opt_ IModelObject* contextObject,
+        _COM_Outptr_ IModelObject** value
+        ) PURE;
+
+    // SetValue():
+    //
+    // Sets the underlying value of the property.  The name of the key and the original context object
+    // passed to the "GetKey" method that returned this property accessor must be passed to this
+    // call.
+    //
+    // Note that some properties are read-only.  In such a case, this method will fail.
+    //
+    STDMETHOD(SetValue)(
+        THIS_
+        _In_ PCWSTR key,
+        _In_opt_ IModelObject* contextObject,
+        _In_ IModelObject* value
+        ) PURE;
+};
+
+//
+// IModelMethod:
+//
+// Represents a method which can be called.
+//
+// Extensions which implement methods would implement this interface one or more times for the methods
+// which it provides.
+//
+#undef INTERFACE
+#define INTERFACE IModelMethod
+DECLARE_INTERFACE_(IModelMethod, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IModelMethod:
+
+
+    // Call():
+    //
+    // Call the method.  The arguments to the method must be packed into a linear
+    // array.  A singular result (or error) is returned.  Metadata about the result
+    // can also optionally be returned.
+    //
+    STDMETHOD(Call)(
+        THIS_
+        _In_opt_ IModelObject *pContextObject,
+        _In_ ULONG64 argCount,
+        _In_reads_(argCount) IModelObject **ppArguments,
+        _COM_Errorptr_ IModelObject **ppResult,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore **ppMetadata
+        ) PURE;
+};
+
+//
+// IKeyEnumerator:
+//
+// An interface which enumerates the model based keys on an object (and their values and associated
+// metadata).  A key enumerator can be acquired through the EnumerateKeys, EnumerateKeyValues, and
+// EnumerateKeyReferences methods on an IModelObject.
+//
+#undef INTERFACE
+#define INTERFACE IKeyEnumerator
+DECLARE_INTERFACE_(IKeyEnumerator, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IKeyEnumerator:
+
+    // Reset():
+    //
+    // Resets the enumerator to its initial state.  A subsequent GetNext call will return
+    // the first key in enumerator order.
+    //
+    STDMETHOD(Reset)(
+        THIS
+        ) PURE;
+
+    // GetNext():
+    //
+    // Moves the iterator forward and fetches the name of the next key and, optionally, its value (or a
+    // reference to it) and associated metadata.
+    //
+    // Note that depending on how this enumerator was acquired, the object returned in the value field
+    // may be the value associated with the key (EnumerateKeys), the resolved value of any property that
+    // the key referes to (EnumerateKeyValues), or a reference to the key (EnumerateKeyReferences).
+    //
+    // If there was an error in resolving the value of the key (for EnumerateKeyValues, for instance),
+    // the method may return an error *AND* fill value with an error object.
+    //
+    // When the enumerator hits the end of the sequence, E_BOUNDS will be returned.
+    //
+    STDMETHOD(GetNext)(
+        _Out_ BSTR* key,
+        _COM_Errorptr_opt_ IModelObject** value,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+};
+
+//
+// IRawEnumerator:
+//
+// An interface which enumerates the raw children (e.g.: base classes, fields, etc...) of an object
+// (and their values and associated metadata).  A raw enumerator can be acquired through the
+// EnumerateRawValues or EnumerateRawReferences methods on IModelObject.
+//
+#undef INTERFACE
+#define INTERFACE IRawEnumerator
+DECLARE_INTERFACE_(IRawEnumerator, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IKeyEnumerator:
+
+    // Reset():
+    //
+    // Resets the enumerator to its initial state.  A subsequent GetNext call will return
+    // the first raw element (native field, base class, etc...) in enumerator order.
+    //
+    STDMETHOD(Reset)(
+        THIS
+        ) PURE;
+
+    // GetNext():
+    //
+    // Moves the iterator forward and fetches the name of the raw element and, optionally, its value (or a
+    // reference to it) and what kind of element it is.
+    //
+    // Note that depending on how this enumerator was acquired, the object returned in the value field
+    // may be the value of the raw element (EnumerateRawValues) or a reference to the raw element
+    // (EnumerateRawReferences).
+    //
+    // If there was an error in reading the value of the raw element (for EnumerateRawValues, for instance),
+    // the method may return an error *AND* fill value with an error object.
+    //
+    // When the enumerator hits the end of the sequence, E_BOUNDS will be returned.
+    //
+    STDMETHOD(GetNext)(
+        _Out_opt_ BSTR* name,
+        _Out_opt_ SymbolKind *kind,
+        _COM_Errorptr_opt_ IModelObject** value
+        ) PURE;
+
+};
+
+//
+// IDataModelConcept:
+//
+// Any object which represents a data model which is registered under a name or
+// is registered for a particular type signature must implement this concept and add it to the data model
+// object via IModelObject::SetConcept.
+//
+// Clients which create data models implement this interface.  It is most frequently
+// consumed by the data model manager itself.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelConcept
+DECLARE_INTERFACE_(IDataModelConcept, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelConcept:
+
+    // InitializeObject():
+    //
+    // If a particular data model is attached to a type signature
+    // (via IDataModelManager::RegisterModelForTypeSignature) before an instance of a type matching
+    // that signature is created, this method will be called on the model.  The method will be passed
+    // the instance object which is being created (modelObject), the type signature which matched
+    // the specific type of the instance object (matchingTypeSignature), and an enumerator to any wildcard
+    // matches between the specific type and the type signature.
+    //
+    // Note that a data model implementation **MUST NOT** rely on this method being called.  A data model
+    // may be attached after instances of a particular type already exist.  This method is most frequently
+    // used for caching purposes.
+    //
+    // A client of the model never calls this API directly.  It is called by the model itself.  An
+    // implementor may choose to do nothing in the method; however -- any such "do nothing" implementation
+    // must still succeed via an S_OK return.  A failure returned from this method will prevent object
+    // construction.
+    //
+    STDMETHOD(InitializeObject)(
+        THIS_
+        _In_ IModelObject* modelObject,
+        _In_opt_ IDebugHostTypeSignature* matchingTypeSignature,
+        _In_opt_ IDebugHostSymbolEnumerator* wildcardMatches
+        ) PURE;
+
+    // GetName():
+    //
+    // Returns the name of the data model.  If the data model is registered under a default name
+    // (via IDataModelManager::RegisterNamedModel), it is expected that the returned name is the
+    // registered default name.  Note that a data model may be registered under multiple names.
+    // It is also perfectly legitimate for a data model to be completely unnamed.  In such cases,
+    // the GetName method may return E_NOTIMPL.
+    //
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* modelName
+        ) PURE;
+
+};
+
+//
+// IStringDisplayableConcept:
+//
+// Any object (or data model) which has a string conversion suitable for display implements this concept.
+// Clients should not rely on the form of this string conversion for programmatic purposes.  It is intended
+// for display purposes only.
+//
+#undef INTERFACE
+#define INTERFACE IStringDisplayableConcept
+DECLARE_INTERFACE_(IStringDisplayableConcept, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IStringDisplayableConcept:
+
+    // ToDisplayString():
+    //
+    // Called in order to convert an instance of an object to a string suitable for display.
+    // The "contextObject" argument refers to the object being converted.  If there is metadata which
+    // governs the string conversion (e.g.: choosing which radix to convert an ordinal in), the associated
+    // metadata store is passed in the "metadata" argument.
+    //
+    STDMETHOD(ToDisplayString)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _In_opt_ IKeyStore* metadata,
+        _Out_ BSTR* displayString
+        ) PURE;
+};
+
+//
+// IModelIterator:
+//
+// This interface enumerates the iterable elements of a collection.  An object which is iterable
+// via IIterableConcept must return an implementation of IModelIterator from its GetIterator method.
+//
+#undef INTERFACE
+#define INTERFACE IModelIterator
+DECLARE_INTERFACE_(IModelIterator, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IModelIterator:
+
+    // Reset():
+    //
+    // Resets the enumerator to its initial state.  A subsequent GetNext call will return
+    // the first iterated element in iteration order.
+    //
+    // Note that it is legitimate for a particular iterator to E_NOTIMPL this particular
+    // call.  In such circumstances, the iterator is forward only and cannot be reset to its
+    // initial state.  While this is legitimate, it is highly recommended that any iterator which
+    // can support the reset capability.
+    //
+    STDMETHOD(Reset)(
+        THIS
+        ) PURE;
+
+    // GetNext():
+    //
+    // Moves the iterator forward and fetches the next iterated element and, optionally, the default
+    // indexer for that element.  Note that any iterable which returns a non-zero value from
+    // IIterableConcept::GetDefaultIndexDimensionality *MUST* return that dimensionality of indexer
+    // from any call to GetNext.  A client of the GetNext method may choose to pass 0/nullptr and not
+    // retrieve the indexer or choose to pass the dimensionality and a buffer of that size to retrieve
+    // the indexer.  It is illegal to request or pass back only part of an indexer via a non-zero "dimensions"
+    // argument which is less than the default index dimensionality returned from
+    // IIterableConcept::GetDefaultIndexDimensionality.
+    //
+    // If the iterator moved forward successfully but there was an error in reading the value of
+    // the iterated element, the method may return an error *AND* fill "object" with an error object.
+    //
+    // When the enumerator hits the end of the sequence, E_BOUNDS will be returned.
+    //
+    STDMETHOD(GetNext)(
+        _COM_Errorptr_ IModelObject** object,
+        _In_ ULONG64 dimensions,
+        _Out_writes_opt_(dimensions) IModelObject** indexers,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+};
+
+//
+// IIterableConcept:
+//
+// Any object (or data model) which is a container which can be iterated implements this concept.
+//
+#undef INTERFACE
+#define INTERFACE IIterableConcept
+DECLARE_INTERFACE_(IIterableConcept, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IIterableConcept:
+
+    // GetDefaultIndexDimensionality():
+    //
+    // If the iterable object also supports indexing via supporting IIndexableConcept, the iterator may optionally
+    // return a "default index" for each element it produces.  The dimensionality of that "default index" is returned
+    // from this method.
+    //
+    // An implementation of this method may return 0 / S_OK indicating that there is no default index returned
+    // from the iterator or it may return non-zero / S_OK indicating that there is a default index returned from
+    // each GetNext of the iterator.
+    //
+    // Note that an implementation which returns non-zero for dimensionality here is promising:
+    //
+    //     - It supports IIndexableConcept
+    //
+    //     - The GetNext method of the IModelIterator returned from the GetIterator method here will return a default
+    //       index of this dimensionality for each element that is UNIQUE
+    //
+    //     - Passing the default index from IModelIterator::GetNext to IIndexableConcept::GetAt will return the same
+    //       value
+    //
+    STDMETHOD(GetDefaultIndexDimensionality)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _Out_ ULONG64* dimensionality
+        ) PURE;
+
+    // GetIterator():
+    //
+    // Returns an iterator instance for this iterable.  The instance of the object being iterated is passed in
+    // the "contextObject" argument.
+    //
+    STDMETHOD(GetIterator)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _Out_ IModelIterator** iterator
+        ) PURE;
+
+};
+
+//
+// IIndexableConcept:
+//
+// Any object which is a container that supports random access retrieval of elements from given N-dimensional
+// indexers implements this concept.
+//
+// It is legal for an object to be indexable (via support of IIndexableConcept) and not iterable (via lack of support
+// for IIterableConcept).
+//
+#undef INTERFACE
+#define INTERFACE IIndexableConcept
+DECLARE_INTERFACE_(IIndexableConcept, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IIndexableConcept:
+
+    // GetDimensionality():
+    //
+    // Returns the dimensionality of the indexer.
+    //
+    // Note that if the object in question is iterable as well as indexable and the object supports a
+    // default indexer (as inquired through IIterableConcept::GetDefaultIndexDimensionality), the
+    // dimensionality returned from the iterator and this method must agree.
+    //
+    STDMETHOD(GetDimensionality)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _Out_ ULONG64* dimensionality
+        ) PURE;
+
+    // GetAt():
+    //
+    // Returns the value of the element at a particular N-dimensional index.  An indexer of N-dimensions
+    // where N is the value returned from GetDimensionality **MUST** be supported.
+    //
+    // Note that a given object may be indexable in different domains by different types (e.g.: indexable
+    // via both ordinals and strings).
+    //
+    // If the index is out of range (or could not be accessed), the method will return a failure; however,
+    // in such cases, the output object may still be set to an error object.
+    //
+    STDMETHOD(GetAt)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _In_ ULONG64 indexerCount,
+        _In_reads_(indexerCount) IModelObject** indexers,
+        _COM_Errorptr_ IModelObject** object,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // SetAt():
+    //
+    // Attempts to set the value of the element at a particular N-dimensional index.  An indexer of N-dimensions
+    // where N is the value returned from GetDimensionality **MUST** be supported.
+    //
+    // Note that a given object may be indexable in different domains by different types (e.g.: indexable
+    // via both ordinals and strings).
+    //
+    // If the index is out of range (or could not be accessed), the method will return a failure; however,
+    // in such cases, the output object may still be set to an error object.
+    //
+    // Note that some indexers are read-only.  This method may fail on such indexers (with E_NOTIMPL).
+    //
+    STDMETHOD(SetAt)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _In_ ULONG64 indexerCount,
+        _In_reads_(indexerCount) IModelObject** indexers,
+        _In_ IModelObject *value
+        ) PURE;
+};
+
+//
+// IPreferredRuntimeTypeConcept:
+//
+// This interface provides a facility to use custom logic when casting an object to it's runtime type. For most types this is not
+// needed as in most instances the runtime type can be determined by the debugger automatically. In some cases this is not
+// possible and this interface can be used in order to provide the correct runtime type.
+//
+#undef INTERFACE
+#define INTERFACE IPreferredRuntimeTypeConcept
+DECLARE_INTERFACE_(IPreferredRuntimeTypeConcept, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IPreferredRuntimeTypeConcept:
+
+    // CastToPreferredRuntimeType()
+    //
+    // Casts the object to it's preferred runtime type.
+    //
+    // If the cast is successful the method will return success.
+    // Otherwise a failure is returned.
+    //
+    // Note that the error E_NOT_SET is considered special by this method.
+    // An implementation of this method which returns E_NOT_SET is indicating
+    // to the data model that it does not wish to override the default
+    // (type system based) conversion to a runtime type.
+    //
+    STDMETHOD(CastToPreferredRuntimeType)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _COM_Errorptr_ IModelObject** object
+        ) PURE;
+};
+
+//
+// IDebugHost:
+//
+// The core interface which represents the underlying debugger which is hosting the data model.
+// The host is required to support this interface.  The various other IDebugHost* interfaces
+// can be queried once an extension has access to the debug host.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHost
+DECLARE_INTERFACE_(IDebugHost, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHost:
+
+    // GetHostDefinedInterface():
+    //
+    // Returns an object (interface cast to IUnknown) which only has meaning to a specific host.
+    // The DbgEng host of the model might return an IDebugClient (cast to IUnknown) as an example.
+    //
+    // A host may E_NOTIMPL this if it does not wish to provide any access to its implementation
+    // specific interfaces.
+    //
+    STDMETHOD(GetHostDefinedInterface)(
+        THIS_
+        _COM_Outptr_ IUnknown** hostUnk
+        ) PURE;
+
+    // GetCurrentContext():
+    //
+    // Returns a context object which represents the current "state" of the debugger.  This is the context
+    // in which all expression evaluations happen, modules are queried, memory reads and writes occur, etc...
+    // The exact meaning of this is specific to a host.  It may include which target/process is being debugged,
+    // etc...
+    //
+    // A host may not E_NOTIMPL this method.
+    //
+    STDMETHOD(GetCurrentContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    // GetDefaultMetadata():
+    //
+    // Returns a default metadata store for the host.  The core object model relies on default metadata for
+    // certain operations if specific metadata is not provided.  The display radix for a given type is one
+    // example where the core model will fall back to default metadata.
+    //
+    // A host may E_NOTIMPL this if it does not provide a default metadata store.
+    //
+    STDMETHOD(GetDefaultMetadata)(
+        THIS_
+        _COM_Outptr_ IKeyStore** defaultMetadataStore
+        ) PURE;
+};
+
+//
+// IDebugHostContext:
+//
+// This interface represents an opaque blob of state managed by the debugger which hosts
+// the data model interfaces.  This opaque blob represents the "state" of the debugger
+// as it pertains to an object.  This may include, for instance, what target / process
+// the object belongs to, what address space the object is in, etc...
+//
+// The "current" context of the debugger can be acquired via IDebugHost::GetCurrentContext
+// Similarly, the context of any object can be acquired via IModelObject::GetContext.
+//
+// Child objects which are created by an extension should propagate the state of the parent
+// whenever possible.  Only the debug host should extend or alter the context.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostContext
+DECLARE_INTERFACE_(IDebugHostContext, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostContext:
+
+    // IsEqualTo():
+    //
+    // Returns whether two IDebugHostContext objects are equal by value.  Note that there
+    // is no requirement for a debug host to have interface pointer equality for two contexts
+    // which are equivalent.  The actual contexts can be compared through this method.
+    //
+    STDMETHOD(IsEqualTo)(
+        THIS_
+        _In_ IDebugHostContext *pContext,
+        _Out_ bool *pIsEqual
+        ) PURE;
+};
+
+// USE_CURRENT_HOST_CONTEXT:
+//
+// Methods which take an IDebugHostContext can be called with this special defined value to indicate
+// to the debug host that the "current" context of the debugger should be used.  This is in lieu of
+// explicitly calling IDebugHost::GetCurrentContext and explicitly passing it to the method needing
+// an IDebugHostContext.
+//
+// Using this may be more efficient than the explicit query and pass.
+//
+#define USE_CURRENT_HOST_CONTEXT ((IDebugHostContext *)((ULONG_PTR)-1))
+
+//
+// ErrorClass:
+//
+// Defines the class of error which is being reported to the host.
+//
+enum ErrorClass
+{
+    ErrorClassWarning,
+    ErrorClassError
+};
+
+//
+// IDebugHostErrorSink:
+//
+// Represents an error sink for the debug host.  Errors which occur during certain operations
+// are sent to the error sink to be handled (or notify the user).
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostErrorSink
+DECLARE_INTERFACE_(IDebugHostErrorSink, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostErrorSink:
+
+    // ReportError():
+    //
+    // Called by the debug host to report an error.
+    //
+    STDMETHOD(ReportError)(
+        THIS_
+        _In_ ErrorClass errClass,
+        _In_ HRESULT hrError,
+        _In_ PCWSTR message
+        ) PURE;
+
+};
+
+//
+// IDebugHostSymbol:
+//
+// The base interface for any symbol (field, type, function, etc...) represented by
+// the debug host.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostSymbol
+DECLARE_INTERFACE_(IDebugHostSymbol, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    // GetContext():
+    //
+    // Gets the debug host's context for this symbol.  Any object which is created relative to this symbol
+    // can be created with this context.
+    //
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    // EnumerateChidlren():
+    //
+    // Enumerates all child symbols of the given type and name.  SymbolType::Symbol can be used to search
+    // to search for any kind of child.
+    //
+    // Note that if name is nullptr, children of any name will be produced by the resulting enumerator.
+    //
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    // GetSymbolKind():
+    //
+    // Gets the kind of symbol that this is (e.g.: a field, a base class, a type, etc...)
+    //
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    // GetName():
+    //
+    // Returns the name of the symbol if the symbol has a name.  If the symbol does not have a name, an error
+    // is returned.
+    //
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    // GetType():
+    //
+    // Returns the type (e.g.: "int *") of the symbol if the symbol has a type.  If the symbol does not have a
+    // type, an error is returned.
+    //
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    // GetContainingModule():
+    //
+    // Returns the module which contains this symbol if the symbol has a containing module.  If the symbol does
+    // not have a containing module, an error is returned.
+    //
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    // CompareAgainst():
+    //
+    // Compares two symbols for equality.  A host is under no obligation to ensure that there is interface pointer
+    // equality for two identical symbols.  This can be used to check for equality.
+    //
+    // Note that presently, "comparisonFlags" is reserved.
+    //
+    STDMETHOD(CompareAgainst)(
+        THIS_
+        _In_ IDebugHostSymbol *pComparisonSymbol,
+        _In_ ULONG comparisonFlags,
+        _Out_ bool *pMatches
+        ) PURE;
+
+};
+
+//
+// IDebugHostSymbolEnumerator:
+//
+// This enumerates a set of symbols.  Such may be the set of children acquired from a call to
+// the IDebugHostSymbol::EnumerateChildren method.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostSymbolEnumerator
+DECLARE_INTERFACE_(IDebugHostSymbolEnumerator, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbolEnumerator:
+
+    // Reset():
+    //
+    // Resets the enumerator to its initial state.  A subsequent GetNext call will return
+    // the first symbol in the set in enumerator order.
+    //
+    STDMETHOD(Reset)(
+        THIS
+        ) PURE;
+
+    // GetNext():
+    //
+    // Moves the iterator forward and fetches the next symbol in the set.
+    //
+    // E_BOUNDS will be returned when the enumerator hits the end of the set.
+    //
+    STDMETHOD(GetNext)(
+        THIS_
+        _COM_Outptr_ IDebugHostSymbol** symbol
+        ) PURE;
+};
+
+//
+// IDebugHostModule:
+//
+// A specialization of IDebugHostSymbol representing a module (e.g.: a DLL or executable).
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostModule
+DECLARE_INTERFACE_(IDebugHostModule, IDebugHostSymbol)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostModule:
+
+    // GetImageName():
+    //
+    // Returns the image name of the module.  If "allowPath" is set, the resulting imageName **MAY OR MAY NOT**
+    // include the path to the image (depending on the particular debug host).  If the "allowPath" is not set,
+    // the resulting imageName will only include the name.
+    //
+    STDMETHOD(GetImageName)(
+        THIS_
+        _In_ bool allowPath,
+        _Out_ BSTR* imageName
+        ) PURE;
+
+    // GetBaseLocation():
+    //
+    // Returns the location of the base of the module in the address space of the debug target.
+    //
+    STDMETHOD(GetBaseLocation)(
+        THIS_
+        _Out_ Location* moduleBaseLocation
+        ) PURE;
+
+    // GetVersion():
+    //
+    // Returns the file and product version of the module (assuming they can be read).  If a given version
+    // is requested (via a non-nullptr output pointer) and it cannot be read, an appropriate error will be
+    // returned.
+    //
+    STDMETHOD(GetVersion)(
+        THIS_
+        _Out_opt_ ULONG64* fileVersion,
+        _Out_opt_ ULONG64* productVersion
+        ) PURE;
+
+    // FindTypeByName():
+    //
+    // Finds a type (e.g.: "int *") which is defined within the module by name.  This method may return a valid
+    // IDebugHostType which would never be returned via an explicit recursion of children of the module.  The
+    // debug host may allow the creation of "derivative types" of things not in the module in question
+    // (e.g.: a "MyStruct **" where "MyStruct" is never used in pointer form).
+    //
+    STDMETHOD(FindTypeByName)(
+        THIS_
+        _In_z_ PCWSTR typeName,
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    // FindSymbolByRVA():
+    //
+    // Finds a single symbol at the given relative virtual address within the module.  If there is not a single
+    // symbol at the supplied RVA, an error will be returned.
+    //
+    STDMETHOD(FindSymbolByRVA)(
+        THIS_
+        _In_ ULONG64 rva,
+        _Out_ IDebugHostSymbol** symbol
+        ) PURE;
+
+    // FindSymbolByName():
+    //
+    // Finds a single symbol by name within the module.  If there is not a single symbol matching the given name,
+    // an error will be returned.
+    //
+    STDMETHOD(FindSymbolByName)(
+        THIS_
+        _In_z_ PCWSTR symbolName,
+        _Out_ IDebugHostSymbol** symbol
+        ) PURE;
+};
+
+//
+// ArrayDimension:
+//
+// Defines the memory layout of one dimension of an array.
+//
+struct ArrayDimension
+{
+    // The lower bounds of the array.  For C style zero based arrays, this will always be zero.  There is no
+    // uniform restriction that all arrays represented by these interfaces are zero based.
+    LONG64 LowerBound;
+
+    // Defines the length of the dimension.  The dimension is considered to be of the form [LowerBound, LowerBound + Length)
+    ULONG64 Length;
+
+    // Defines how many bytes to move forward in memory to walk from index N of the dimension to index N + 1
+    ULONG64 Stride;
+};
+
+//
+// IDebugHostType:
+//
+// A specialization of IDebugHostSymbol representing a type (e.g.: "MyStruct *")
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostType
+DECLARE_INTERFACE_(IDebugHostType, IDebugHostSymbol)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostType:
+
+    // GetKind():
+    //
+    // Returns the kind of type (e.g.: a pointer, an array, an intrinsic, etc...)
+    //
+    STDMETHOD(GetTypeKind)(
+        THIS_
+        _Out_ TypeKind *kind
+        ) PURE;
+
+    // GetSize():
+    //
+    // Returns the overall size of the type as laid out in memory.
+    //
+    STDMETHOD(GetSize)(
+        THIS_
+        _Out_ ULONG64* size
+        ) PURE;
+
+    // GetBaseType():
+    //
+    // If the type is a derivative of another single type (e.g.: as "MyStruct *" is derived from "MyStruct"),
+    // this returns the base type of the derivation.  For pointers, this would return the type pointed to.
+    // For arrays, this would return what the array is an array of.  If the type is not such a derivative
+    // type, an error is returned.
+    //
+    // Not that this method has nothing to do with C++ base classes.  Such are symbols (IDebugHostBaseClass)
+    // which can be enumerated from the derived class via a call to EnumerateChildren.
+    //
+    STDMETHOD(GetBaseType)(
+        THIS_
+        _Out_ IDebugHostType** baseType
+        ) PURE;
+
+    // GetHashCode():
+    //
+    // Returns a 32-bit hash code for the type.  With the exception of a global match (e.g.: a type signature
+    // like "*" if permitted by the host), any type instance which can match a particular type signature must
+    // return the same hash code.
+    //
+    // This is used in conjunction with type signatures in order to match type signatures to type instances.
+    //
+    STDMETHOD(GetHashCode)(
+        THIS_
+        _Out_ ULONG* hashCode
+        ) PURE;
+
+    // GetIntrinsicType():
+    //
+    // If the type kind as reported by GetTypeKind is an intrinsic, this returns more information about the
+    // particular kind of intrinsic.
+    //
+    // The returned "intrinsicKind" indicates things like whether it is a bool, integer, floating point, etc...
+    // but not necessarily the size.  The returned "carrierType" indicates how this intrinsic value is
+    // packed into a VARIANT structure.  The combination of this information indicates the full set
+    // of information about the intrinsic.
+    //
+    STDMETHOD(GetIntrinsicType)(
+        THIS_
+        _Out_opt_ IntrinsicKind *intrinsicKind,
+        _Out_opt_ VARTYPE *carrierType
+        ) PURE;
+
+    //*************************************************
+    // Bitfield Information:
+    //
+    // The following methods only apply to types which are bitfields:
+    //
+
+    // GetBitField():
+    //
+    // If the type is a bit field, this returns the numeric position of the least significant bit of the
+    // field and the length of the field.  Bit positions (lsbOfField + lengthOfField : lsbOfField] define
+    // the bit position.
+    //
+    STDMETHOD(GetBitField)(
+        THIS_
+        _Out_ ULONG* lsbOfField,
+        _Out_ ULONG* lengthOfField
+        ) PURE;
+
+
+    //*************************************************
+    // Pointer Information (GetKind returns TypePointer):
+    //
+    // The following methods only apply to types which are pointers (or create
+    // derivative types which are pointers)
+    //
+
+    // GetPointerKind():
+    //
+    // Returns what kind of pointer the type is (e.g.: a standard pointer, a pointer to member,
+    // a reference, an r-value reference, a C++/CX hat, etc...)
+    //
+    STDMETHOD(GetPointerKind)(
+        THIS_
+        _Out_ PointerKind* pointerKind
+        ) PURE;
+
+    // GetMemberType():
+    //
+    // If the pointer is a pointer-to-class-member, this returns the type of such class.
+    //
+    STDMETHOD(GetMemberType)(
+        THIS_
+        _Out_ IDebugHostType** memberType
+        ) PURE;
+
+    // CreatePointerTo():
+    //
+    // For any given type, this returns a new IDebugHostType which is a pointer to this type.
+    // The kind of pointer is supplied by the "kind" argument.
+    //
+    STDMETHOD(CreatePointerTo)(
+        THIS_
+        _In_ PointerKind kind,
+        _COM_Outptr_ IDebugHostType** newType
+        ) PURE;
+
+    //*************************************************
+    // Array Information (GetKind returns TypeArray):
+    //
+    // The following methods only apply to types which are arrays (or create
+    // derivative types which are arrays)
+    //
+
+    // GetArrayDimensionality():
+    //
+    // Returns the dimensionality of the array.  There is no guarantee that every array type representable by
+    // these interfaces is a standard zero-based one dimensional array as is standard in C.
+    //
+    STDMETHOD(GetArrayDimensionality)(
+        THIS_
+        _Out_ ULONG64* arrayDimensionality
+        ) PURE;
+
+    // GetArrayDimensions():
+    //
+    // Fills in information about each dimension of the array including its lower bound, length, and stride.
+    // This method should not be called on TypeExtendedArray.  Methods in IDebugHostType4 should be utilized.
+    //
+    STDMETHOD(GetArrayDimensions)(
+        THIS_
+        _In_ ULONG64 dimensions,
+        _Out_writes_(dimensions) ArrayDimension *pDimensions
+        ) PURE;
+
+    // CreateArrayOf():
+    //
+    // For any given type, this returns a new IDebugHostType which is an array of this type.
+    // The dimensions of the array must be supplied via the "dimensions" and "pDimensions" arguments.
+    // This method should not be called on TypeExtendedArray.  Methods in IDebugHostType4 should be utilized.
+    //
+    STDMETHOD(CreateArrayOf)(
+        THIS_
+        _In_ ULONG64 dimensions,
+        _In_reads_(dimensions) ArrayDimension *pDimensions,
+        _COM_Outptr_ IDebugHostType** newType
+        ) PURE;
+
+    //*************************************************
+    // Function Information (GetKind returns TypeFunction):
+    //
+    // The following methods only apply to types which are functions (or create
+    // derivative types which are functions)
+    //
+
+    // GetFunctionCallingConvention():
+    //
+    // Returns the calling convention of the function (e.g.: STDCALL, FASTCALL, etc...)
+    //
+    STDMETHOD(GetFunctionCallingConvention)(
+        THIS_
+        _Out_ CallingConventionKind* conventionKind
+        ) PURE;
+
+    // GetFunctionReturnType():
+    //
+    // Gets the return type of the function as an IDebugHostType.
+    //
+    STDMETHOD(GetFunctionReturnType)(
+        THIS_
+        _COM_Outptr_ IDebugHostType** returnType
+        ) PURE;
+
+    // GetFunctionParameterTypeCount():
+    //
+    // Gets the number of parameter types that the function takes.
+    //
+    STDMETHOD(GetFunctionParameterTypeCount)(
+        THIS_
+        _Out_ ULONG64* count
+        ) PURE;
+
+    // GetFunctionParameterTypeAt():
+    //
+    // Returns the type of the "i"-th argument to the function as a new IDebugHostType.
+    //
+    STDMETHOD(GetFunctionParameterTypeAt)(
+        THIS_
+        _In_ ULONG64 i,
+        _Out_ IDebugHostType** parameterType
+        ) PURE;
+
+    //*************************************************
+    // Template Information:
+    //
+    // The following methods only apply to types which are templates or generics (or create
+    // derivative types which are templates or generics)
+    //
+
+    // IsGeneric():
+    //
+    // Returns whether the type is a generic or template.
+    //
+    STDMETHOD(IsGeneric)(
+        THIS_
+        _Out_ bool* isGeneric
+        ) PURE;
+
+    // GetGenericArgumentCount():
+    //
+    // Returns the number of arguments to the generic/template.  The returned value must be greater
+    // than zero.
+    //
+    STDMETHOD(GetGenericArgumentCount)(
+        THIS_
+        _Out_ ULONG64* argCount
+        ) PURE;
+
+    // GetGenericArgumentAt():
+    //
+    // For the "i"-th generic argument to the generic/template, this returns a new IDebugHostSymbol
+    // which represents that argument.  For templates, this is most often an IDebugHostType; however --
+    // it may be an IDebugHostConstant for non-template type arguments.
+    //
+    // Note that it is possible for some compiler generated generics and templates that this method
+    // will fail.
+    //
+    STDMETHOD(GetGenericArgumentAt)(
+        THIS_
+        _In_ ULONG64 i,
+        _Out_ IDebugHostSymbol** argument
+        ) PURE;
+
+};
+
+//
+// IDebugHostConstant:
+//
+// A specialization of IDebugHostSymbol which represents a constant symbol.
+// Such may be returned as the literal value for some symbol.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostConstant
+DECLARE_INTERFACE_(IDebugHostConstant, IDebugHostSymbol)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostConstant:
+
+    // GetValue():
+    //
+    // Returns the value of the constant in a VARIANT data structure.
+    //
+    STDMETHOD(GetValue)(
+        THIS_
+        _Out_ VARIANT* value
+        ) PURE;
+
+};
+
+//
+// IDebugHostField:
+//
+// A specialization of IDebugHostSymbol which represents a field of a class or struct.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostField
+DECLARE_INTERFACE_(IDebugHostField, IDebugHostSymbol)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostField:
+
+    // GetLocationKind():
+    //
+    // Returns the kind of location the field is at.  Such location may be static, member, constant,
+    // etc...
+    //
+    STDMETHOD(GetLocationKind)(
+        THIS_
+        _Out_ LocationKind *locationKind
+        ) PURE;
+
+    // GetOffset():
+    //
+    // If the location kind indicates that the field is a member, this returns the offset into the class
+    // or struct of which the field is a member.
+    //
+    STDMETHOD(GetOffset)(
+        THIS_
+        _Out_ ULONG64* offset
+        ) PURE;
+
+    // GetLocation():
+    //
+    // If the location kind indicates that the field is static, this returns the location of the field in
+    // the address space of the debug target.
+    //
+    STDMETHOD(GetLocation)(
+        THIS_
+        _Out_ Location* location
+        ) PURE;
+
+    // GetValue():
+    //
+    // If the location kind indicates that the field is constant, this returns the constant value of the field.
+    //
+    STDMETHOD(GetValue)(
+        THIS_
+        _Out_ VARIANT* value
+        ) PURE;
+
+};
+
+//
+// IDebugHostData:
+//
+// A specialization of IDebugHostSymbol which represents data which is unattached to a class or struct
+// (e.g.: a global variable)
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostData
+DECLARE_INTERFACE_(IDebugHostData, IDebugHostSymbol)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostData:
+
+    // GetLocationKind():
+    //
+    // Returns the kind of location the data is at.  Such location may be static, constant, etc...
+    //
+    STDMETHOD(GetLocationKind)(
+        THIS_
+        _Out_ LocationKind *locationKind
+        ) PURE;
+
+    // GetLocation():
+    //
+    // If the location kind indicates that the data is static, this returns the location of the data in
+    // the address space of the debug target.
+    //
+    STDMETHOD(GetLocation)(
+        THIS_
+        _Out_ Location* location
+        ) PURE;
+
+    // GetValue():
+    //
+    // If the location kind indicates that the data is constant, this returns the constant value of the data.
+    //
+    STDMETHOD(GetValue)(
+        THIS_
+        _Out_ VARIANT* value
+        ) PURE;
+};
+
+// IDebugHostPublic:
+//
+// A specialization of IDebugHostSymbol which represents a public symbol entry.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostPublic
+DECLARE_INTERFACE_(IDebugHostPublic, IDebugHostSymbol)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostPublic:
+
+    // GetLocationKind():
+    //
+    // Returns the kind of location the data is at.  Such location may be static, constant, etc...
+    //
+    STDMETHOD(GetLocationKind)(
+        THIS_
+        _Out_ LocationKind *locationKind
+        ) PURE;
+
+    // GetLocation():
+    //
+    // If the location kind indicates that the data is static, this returns the location of the data in
+    // the address space of the debug target.
+    //
+    STDMETHOD(GetLocation)(
+        THIS_
+        _Out_ Location* location
+        ) PURE;
+
+};
+
+//
+// IDebugHostBaseClass:
+//
+// A specialization of IDebugHostSymbol which represents a base class.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostBaseClass
+DECLARE_INTERFACE_(IDebugHostBaseClass, IDebugHostSymbol)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostBaseClass:
+
+    // GetOffset():
+    //
+    // This returns the offset of the base class within the class.
+    //
+    STDMETHOD(GetOffset)(
+        THIS_
+        _Out_ ULONG64* offset
+        ) PURE;
+
+};
+
+//
+// IDebugHostSymbols:
+//
+// The core symbols interface which a debug host presents.  This interface can be QI'd from
+// IDebugHost in order to access global symbols, the module list of the debug target, type
+// signatures, etc...
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostSymbols
+DECLARE_INTERFACE_(IDebugHostSymbols, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbols:
+
+    // CreateModuleSignature()
+    //
+    // Creates a module signature for the given module name and version range.
+    //
+    STDMETHOD(CreateModuleSignature)(
+        THIS_
+        _In_z_ PCWSTR pwszModuleName,
+        _In_opt_z_ PCWSTR pwszMinVersion,
+        _In_opt_z_ PCWSTR pwszMaxVersion,
+        _Out_ IDebugHostModuleSignature** ppModuleSignature
+        ) PURE;
+
+    // CreateTypeSignature():
+    //
+    // Creates a type signature object.  A type signature is a generalization of a type which many
+    // specific instances can match.  The format of type signatures is specific to the host and language
+    // to which they refer.
+    //
+    // For current hosts and C/C++, a type signature here is equivalent to a NatVis type specification.
+    // It is the name of a type with wildcards allowed for template arguments.
+    //
+    // If a specific IDebugHostModule is passed in the "module" argument, the type signature only applies
+    // to types within that specific module as defined by the host.
+    //
+    STDMETHOD(CreateTypeSignature)(
+        THIS_
+        _In_z_ PCWSTR signatureSpecification,
+        _In_opt_ IDebugHostModule* module,
+        _Out_ IDebugHostTypeSignature** typeSignature
+        ) PURE;
+
+    // CreateTypeSignatureForModuleRange():
+    //
+    // Creates a type signature object.  A type signature is a generalization of a type which many
+    // specific instances can match.  The format of type signatures is specific to the host and language
+    // to which they refer.
+    //
+    // For current hosts and C/C++, a type signature here is equivalent to a NatVis type specification.
+    // It is the name of a type with wildcards allowed for template arguments.
+    //
+    // This method allows the type signature to apply to modules with a particular name and in a range
+    // of versions as defined by an "x", "x.y", "x.y.z", or "x.y.z.a" version string.
+    //
+    // moduleName only        - The type signature is restricted to modules with the specified name
+    // moduleName, minVersion - The type signature is restricted to modules with the specified name of at least the specified version
+    // moduleName, maxVersion - The type signature is restricted to modules with the specified name of at most the specified version
+    // moduleName, minVersion,
+    //             maxVersion - The type signature is restricted to modules with the specified name within the range of supplied version numbers
+    //
+    STDMETHOD(CreateTypeSignatureForModuleRange)(
+        THIS_
+        _In_z_ PCWSTR signatureSpecification,
+        _In_z_ PCWSTR moduleName,
+        _In_opt_z_ PCWSTR minVersion,
+        _In_opt_z_ PCWSTR maxVersion,
+        _Out_ IDebugHostTypeSignature** typeSignature
+        ) PURE;
+
+    // EnumerateModules():
+    //
+    // Returns an enumerator which enumerates the module list for a given context.  The context supplied
+    // here may be acquired from IDebugHost::GetCurrentContext or any of the various interfaces which have a
+    // GetContext(...) method.
+    //
+    STDMETHOD(EnumerateModules)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _COM_Outptr_ IDebugHostSymbolEnumerator** moduleEnum
+        ) PURE;
+
+    // FindModuleByName():
+    //
+    // Finds a particular module by name within the given context.  If such module cannot be found, an error occurs.
+    // It is legal to ask for the module with or without the extension.
+    //
+    STDMETHOD(FindModuleByName)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_z_ PCWSTR moduleName,
+        _COM_Outptr_ IDebugHostModule **module
+        ) PURE;
+
+    // FindModuleByLocation():
+    //
+    // Given a location within the address space of the debug target as defined by the given context, this returns
+    // the module to which that location belongs.  If that location is not within the address range of a mapped
+    // module, an error is returned.
+    //
+    STDMETHOD(FindModuleByLocation)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ Location moduleLocation,
+        _COM_Outptr_ IDebugHostModule **module
+        ) PURE;
+
+    // GetMostDerivedObject():
+    //
+    // For an object of a given type at a specified location within the address space of the debug target as defined
+    // by the given context, this will attempt to perform runtime type analysis to determine the runtime type of
+    // the object (as opposed to the passed static type).  If such a runtime type can be found, the location of the
+    // runtime (most derived) type will be returned as well as its type.
+    //
+    // Note that analysis takes place at the type system level only and has nothing to do with the
+    // IPreferredRuntimeTypeConcept concept.
+    //
+    // Note that this method may fail for a variety of reasons.  It may also return the same address and type which
+    // was input.
+    //
+    STDMETHOD(GetMostDerivedObject)(
+        THIS_
+        _In_opt_ IDebugHostContext *pContext,
+        _In_ Location location,
+        _In_ IDebugHostType* objectType,
+        _Out_ Location* derivedLocation,
+        _Out_ IDebugHostType** derivedType
+        ) PURE;
+};
+
+//
+// IDebugHostMemory:
+//
+// The core memory access interface which a debug host presents.  This interface can be QI'd from
+// IDebugHost in order to access memory regions (be they virtual / physical / registers / etc...)
+//
+// Note that the combination of context and "location" in the methods of this interface
+// need not necessarily refer to the virtual address space of the target.  They can refer to the
+// physical address space of the target, an I/O space of the target, a register space of the target, etc...
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostMemory
+DECLARE_INTERFACE_(IDebugHostMemory, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostMemory:
+
+    // ReadBytes():
+    //
+    // Reads a number of bytes from the address space of the target as defined by the inpassed context and location.
+    // The number of bytes read is returned in "bytesRead" upon success.
+    //
+    STDMETHOD(ReadBytes)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _Out_writes_bytes_(bufferSize) void* buffer,
+        _In_ ULONG64 bufferSize,
+        _Out_opt_ ULONG64* bytesRead
+        ) PURE;
+
+    // WriteBytes():
+    //
+    // Writes a number of bytes to the address space of the target as defined by the inpassed context and location.
+    // The number of bytes written is returned in "bytesWritten" upon success.
+    //
+    STDMETHOD(WriteBytes)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _In_reads_bytes_(bufferSize) void* buffer,
+        _In_ ULONG64 bufferSize,
+        _Out_opt_ ULONG64* bytesWritten
+        ) PURE;
+
+    // ReadPointers():
+    //
+    // Reads a number of pointer sized objects from the address space of the target as defined by the inpassed
+    // context and location.
+    //
+    // Each read pointer is, if necessary, zero extended to 64-bits and returned.
+    //
+    STDMETHOD(ReadPointers)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _In_ ULONG64 count,
+        _Out_writes_(count) ULONG64* pointers
+        ) PURE;
+
+    // WritePointers():
+    //
+    // Takes a number of pointers as held in unsigned 64-bit values, truncates them to the native pointer size
+    // of the target, and writes them into the address space of the target as defined by the inpassed
+    // context and location.
+    //
+    STDMETHOD(WritePointers)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _In_ ULONG64 count,
+        _In_reads_(count) ULONG64* pointers
+        ) PURE;
+
+    // GetDisplayStringForLocation():
+    //
+    // For a given location within the address space of the target as defined by context and location,
+    // convert the location to a displayable string (according to whatever format the host chooses).
+    //
+    // If the "verbose" argument is true, the string conversion may be "more verbose"
+    //
+    STDMETHOD(GetDisplayStringForLocation)(
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _In_ bool verbose,
+        _Out_ BSTR* locationName
+        ) PURE;
+};
+
+//
+// IDebugHostEvaluator:
+//
+// The core expression evaluation interface which a debug host presents.  This interface can be QI'd from
+// IDebugHost in order to perform expression evaluation.
+//
+// NOTE: In order to be as compatible as possible across the hosts which support this interface, callers
+// of expression evaluation should either restrict their usage to pure language level semantics or should
+// be prepared to fall back to other means.  Different hosts may extend expression valuation with non-language
+// semantics as they see fit.  Such semantics are not guaranteed to be cross compatible.  Only pure language
+// level semantics are.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostEvaluator
+DECLARE_INTERFACE_(IDebugHostEvaluator, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostEvaluator:
+
+    // EvaluateExpression():
+    //
+    // Causes the host to evaluate an expression.  The input expression will be evaluated with
+    // language syntax.  The underlying expression evaluator will not offer any extensions which
+    // are private to a particular host.  Such expressions can be evaluated via an intentional
+    // choice to call EvaluateExtendedExpression.
+    //
+    // The host context is passed in the "context" argument and
+    // defines what debug target, etc...  the expression evaluation occurs in the context of.
+    //
+    // The "bindingContext" argument supplies an effective "this" pointer for the expression evaluation.
+    // An evaluation of "m_foo" with a bindingContext of "bar" is effectively evaluating "bar.m_foo".
+    // To remove a name in the expression from application of "this", it is necessary to qualify the name
+    // via some form of qualification (e.g.: a global '::', module qualification syntax, etc...)
+    //
+    // If the "bindingContext" argument is nullptr, all names will be bound as if the host were in the state
+    // described by the "context" argument.  This may include local variables of a specified stack frame
+    // of a specified thread, globals (as determined by the host), etc...
+    //
+    // The result of the expression evaluation and, optionally any resultant metadata, are returned from
+    // this method.  If an evaluation error occurs, it is possible for the method to return a failing HRESULT
+    // and still return an error object in the "result" output argument.
+    //
+    STDMETHOD(EvaluateExpression)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ PCWSTR expression,
+        _In_opt_ IModelObject* bindingContext,
+        _COM_Errorptr_ IModelObject** result,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // EvaluateExtendedExpression():
+    //
+    // Evaluates an expression in a similar fashion to EvaluateExpression().  Calling this method turns
+    // on any features that the host's expression evaluator provides on top of language semantics.
+    // These features are host specific and are not generic amongst all hosts which support a particular
+    // language.
+    //
+    // Any extension which calls this method must handle failure of the method in a graceful manner.
+    //
+    STDMETHOD(EvaluateExtendedExpression)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ PCWSTR expression,
+        _In_opt_ IModelObject* bindingContext,
+        _COM_Errorptr_ IModelObject** result,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+};
+
+//
+// SignatureComparison:
+//
+// Describes how a type or two signatures compare.
+//
+enum SignatureComparison
+{
+    // The two signatures/types being compared are unrelated.
+    Unrelated,
+
+    // One signature/type compares ambiguously against the other.  For instance,
+    // std::pair<*, int> versus std::pair<int, *> are ambiguous.  There are types that would
+    // match both of these equally well (e.g.: std::pair<int, int>)
+    Ambiguous,
+
+    // One signature/type is less specific than the other.  For instance, a comparison of
+    // std::vector<*> against std::vector<int> would yield LessSpecific.
+    LessSpecific,
+
+    // One signature/type is more specific than the other.  For instance, a comparison of
+    // std::vector<int> against std::vector<*> would yield MoreSpecific.
+    MoreSpecific,
+
+    // The signatures/types are identical.
+    Identical
+};
+
+//
+// IDebugHostModuleSignature:
+//
+// The interface which represents a module signature: A module name with an optional version range.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostModuleSignature
+DECLARE_INTERFACE_(IDebugHostModuleSignature, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        )PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        )PURE;
+
+    //*************************************************
+    // IDebugHostModuleSignature:
+
+    STDMETHOD(IsMatch)(
+        THIS_
+        _In_ IDebugHostModule* pModule,
+        _Out_ bool* isMatch
+        ) PURE;
+};
+
+//
+// IDebugHostTypeSignature:
+//
+// The interface which represents a type signature: a wildcarded generalization of a set of types.
+// Models can be registered against type signatures so that they are automatically attached to any
+// object instance whose type instance matches the signature.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostTypeSignature
+DECLARE_INTERFACE_(IDebugHostTypeSignature, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostTypeSignature:
+
+    // GetHashCode():
+    //
+    // Gets a 32-bit hash code for this type signature.  Note that any type instance which matches
+    // this particular signature (with the exception of global matches) *MUST* have the same hash code.
+    //
+    STDMETHOD(GetHashCode)(
+        THIS_
+        _Out_ ULONG* hashCode
+        ) PURE;
+
+    // IsMatch():
+    //
+    // Returns whether or not a particular type instance matches this signature.  If it does, true is returned
+    // from "isMatch" and the optional "wildcardMatches" argument will be set to an enumerator which enumerates
+    // all of the wildcard matches between the type instance and the type signature.
+    //
+    STDMETHOD(IsMatch)(
+        THIS_
+        _In_ IDebugHostType* type,
+        _Out_ bool* isMatch,
+        _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches
+        ) PURE;
+
+    // CompareAgainst():
+    //
+    // Evaluates the relationship between two type signatures and returns information about that relationship.
+    // One type signature can be unrelated, less specific, more specific, identical, or ambiguous as compared
+    // to another.
+    //
+    // It is illegal to have ambiguity between two type signatures registered with the data model manager.
+    //
+    STDMETHOD(CompareAgainst)(
+        THIS_
+        _In_ IDebugHostTypeSignature* typeSignature,
+        _Out_ SignatureComparison* result
+        ) PURE;
+
+};
+
+// SymbolSearchOptions:
+//
+enum SymbolSearchOptions
+{
+    // SymbolSearchNone: No options set
+    SymbolSearchNone = 0x00000000,
+
+    // SymbolSearchCompletion: Search for symbols starting with the specified name rather than
+    // symbols of the exact specified name.
+    SymbolSearchCompletion = 0x00000001
+};
+
+// SymbolSearchInfo:
+//
+// The search record passed to EnumerateChildrenEx in order to restrict symbol searches.
+// A given kind of symbol (as indicated by the SymbolKind enumeration) searched may have its own derived type.
+//
+struct SymbolSearchInfo
+{
+#ifdef __cplusplus
+protected:
+    SymbolSearchInfo(_In_ ULONG derivedSize) :
+        HeaderSize(sizeof(SymbolSearchInfo)),
+        InfoSize(derivedSize),
+        SearchOptions(0)
+    {
+    }
+
+public:
+    SymbolSearchInfo() :
+        HeaderSize(sizeof(SymbolSearchInfo)),
+        InfoSize(sizeof(SymbolSearchInfo)),
+        SearchOptions(0)
+    {
+    }
+#endif // __cplusplus
+
+    ULONG HeaderSize; // sizeof(SymbolSearchInfo)
+    ULONG InfoSize;   // sizeof(* by SymbolKind *)
+
+    ULONG SearchOptions;
+
+    //
+    // What follows is per SymbolKind:
+    //
+};
+
+// TypeSearchInfo:
+//
+// The search record passed to EnumerateChildrenEx specifically for SymbolType searches.
+//
+struct TypeSearchInfo : public SymbolSearchInfo
+{
+#ifdef __cplusplus
+    TypeSearchInfo() :
+        SymbolSearchInfo(sizeof(TypeSearchInfo))
+    {
+    }
+
+    TypeSearchInfo(_In_ TypeKind searchType) :
+        SymbolSearchInfo(sizeof(TypeSearchInfo)),
+        SearchType(searchType)
+    {
+    }
+#endif // __cplusplus
+
+    // Defines the type being searched for.
+    TypeKind SearchType;
+};
+
+// LanguageKind:
+//
+// Identifies the language of the compiland containing a given symbol.
+//
+enum LanguageKind
+{
+    // LanguageUnknown: Indicates that the language cannot be identified
+    LanguageUnknown,
+
+    // LanguageC: Indicates the C language
+    LanguageC,
+
+    // LanguageCPP: Indicates the C++ language
+    LanguageCPP,
+
+    // LanguageAssembly: Indicates assembly
+    LanguageAssembly
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugHostSymbol2
+DECLARE_INTERFACE_(IDebugHostSymbol2, IDebugHostSymbol)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    STDMETHOD(CompareAgainst)(
+        THIS_
+        _In_ IDebugHostSymbol *pComparisonSymbol,
+        _In_ ULONG comparisonFlags,
+        _Out_ bool *pMatches
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol2
+
+    // EnumerateChildrenEx():
+    //
+    // Enumerates all child symbols of the given type, name, and extended information which is present.
+    // This behaves identically to EnumerateChildren when searchInfo is nullptr.  SymbolType::Symbol
+    // can be used to search to search for any kind of child.
+    //
+    // Note that if name is nullptr, children of any name will be produced by the resulting enumerator.
+    //
+    STDMETHOD(EnumerateChildrenEx)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _In_opt_ SymbolSearchInfo* searchInfo,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    // GetLanguage():
+    //
+    // If the symbol can identify the language for which it applies, this returns an identifier for such.
+    // Many symbols will *NOT* be able to make this determination.  In such cases, this method will fail.
+    // It is also possible that the host does not understand the language or there is no defined LanguageKind.
+    // In such cases, LanguageUnknown will be returned and the method will succeed.
+    //
+    STDMETHOD(GetLanguage)(
+        THIS_
+        _Out_ LanguageKind *pKind
+        ) PURE;
+
+};
+
+// VarArgsKind:
+//
+// Defines the style of variable arguments that a function definition takes.
+//
+enum VarArgsKind
+{
+    // The function does not take any variable arguments
+    VarArgsNone,
+
+    // The function is a C-style varargs function ( returntype(arg1, arg2, ...) ).  The number of arguments
+    // reported by the function does not include the ellipsis ('...') argument.  Any variable argument
+    // passing occurs after the number of arguments returned by GetFunctionParameterTypeCount(...).
+    //
+    VarArgsCStyle
+};
+
+//
+// IDebugHostType2:
+//
+// Additional type information capabilities provided in addition to those of IDebugHostType.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostType2
+DECLARE_INTERFACE_(IDebugHostType2, IDebugHostType)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostType:
+
+    STDMETHOD(GetTypeKind)(
+        THIS_
+        _Out_ TypeKind *kind
+        ) PURE;
+
+    STDMETHOD(GetSize)(
+        THIS_
+        _Out_ ULONG64* size
+        ) PURE;
+
+    STDMETHOD(GetBaseType)(
+        THIS_
+        _Out_ IDebugHostType** baseType
+        ) PURE;
+
+    STDMETHOD(GetHashCode)(
+        THIS_
+        _Out_ ULONG* hashCode
+        ) PURE;
+
+    STDMETHOD(GetIntrinsicType)(
+        THIS_
+        _Out_opt_ IntrinsicKind *intrinsicKind,
+        _Out_opt_ VARTYPE *carrierType
+        ) PURE;
+
+    //*************************************************
+    // Bitfield Information:
+    //
+    // The following methods only apply to types which are bitfields:
+    //
+
+    STDMETHOD(GetBitField)(
+        THIS_
+        _Out_ ULONG* lsbOfField,
+        _Out_ ULONG* lengthOfField
+        ) PURE;
+
+    //*************************************************
+    // Pointer Information (GetKind returns TypePointer):
+    //
+    // The following methods only apply to types which are pointers (or create
+    // derivative types which are pointers)
+    //
+
+    STDMETHOD(GetPointerKind)(
+        THIS_
+        _Out_ PointerKind* pointerKind
+        ) PURE;
+
+    STDMETHOD(GetMemberType)(
+        THIS_
+        _Out_ IDebugHostType** memberType
+        ) PURE;
+
+    STDMETHOD(CreatePointerTo)(
+        THIS_
+        _In_ PointerKind kind,
+        _COM_Outptr_ IDebugHostType** newType
+        ) PURE;
+
+    //*************************************************
+    // Array Information (GetKind returns TypeArray):
+    //
+    // The following methods only apply to types which are arrays (or create
+    // derivative types which are arrays)
+    //
+
+    STDMETHOD(GetArrayDimensionality)(
+        THIS_
+        _Out_ ULONG64* arrayDimensionality
+        ) PURE;
+
+    STDMETHOD(GetArrayDimensions)(
+        THIS_
+        _In_ ULONG64 dimensions,
+        _Out_writes_(dimensions) ArrayDimension *pDimensions
+        ) PURE;
+
+    STDMETHOD(CreateArrayOf)(
+        THIS_
+        _In_ ULONG64 dimensions,
+        _In_reads_(dimensions) ArrayDimension *pDimensions,
+        _COM_Outptr_ IDebugHostType** newType
+        ) PURE;
+
+    //*************************************************
+    // Function Information (GetKind returns TypeFunction):
+    //
+    // The following methods only apply to types which are functions (or create
+    // derivative types which are functions)
+    //
+
+    STDMETHOD(GetFunctionCallingConvention)(
+        THIS_
+        _Out_ CallingConventionKind* conventionKind
+        ) PURE;
+
+    STDMETHOD(GetFunctionReturnType)(
+        THIS_
+        _COM_Outptr_ IDebugHostType** returnType
+        ) PURE;
+
+    STDMETHOD(GetFunctionParameterTypeCount)(
+        THIS_
+        _Out_ ULONG64* count
+        ) PURE;
+
+    STDMETHOD(GetFunctionParameterTypeAt)(
+        THIS_
+        _In_ ULONG64 i,
+        _Out_ IDebugHostType** parameterType
+        ) PURE;
+
+    //*************************************************
+    // Template Information:
+    //
+    // The following methods only apply to types which are templates or generics (or create
+    // derivative types which are templates or generics)
+    //
+
+    STDMETHOD(IsGeneric)(
+        THIS_
+        _Out_ bool* isGeneric
+        ) PURE;
+
+    STDMETHOD(GetGenericArgumentCount)(
+        THIS_
+        _Out_ ULONG64* argCount
+        ) PURE;
+
+    STDMETHOD(GetGenericArgumentAt)(
+        THIS_
+        _In_ ULONG64 i,
+        _Out_ IDebugHostSymbol** argument
+        ) PURE;
+
+    //**************************************************************************
+    // IDebugHostType2:
+    //
+    // The following methods are only available in the v2 IDebugHostType interface.
+
+    //*************************************************
+    // Typedef Information:
+    //
+    // Typedef types are, for the vast majority of calls, indistinguishable from the types they are definitions
+    // against.  In the event that the true typedef information needs to be known, the following APIs
+    // apply.
+    //
+
+    // IsTypedef():
+    //
+    // Returns whether the type is a typedef for another type or not.
+    //
+    STDMETHOD(IsTypedef)(
+        THIS_
+        _Out_ bool* isTypedef
+        ) PURE;
+
+    // GetTypedefBaseType():
+    //
+    // If IsTypedef returns true, this will return the type that a typedef refers to.  Note that the base
+    // type may be another typedef.  It is entirely possible to have a chain of definitions.  If the caller
+    // wishes to acquire the first non-typedef type of a chain, GetTypedefFinalBaseType is the appropriate call.
+    //
+    STDMETHOD(GetTypedefBaseType)(
+        THIS_
+        _Out_ IDebugHostType2** baseType
+        ) PURE;
+
+    // GetTypedefFinalBaseType():
+    //
+    // If IsTypedef returns true, this will return the bottom-most type of a typedef chain.  That is, the first
+    // type in the chain which is NOT a typedef.  This is the type which is implicitly used for most
+    // non-typedef IDebugHostType::* methods on a typedef type.
+    //
+    STDMETHOD(GetTypedefFinalBaseType)(
+        THIS_
+        _Out_ IDebugHostType2** finalBaseType
+        ) PURE;
+
+    //*************************************************
+    // Extended Function Information:
+    //
+    // The following methods indicate additional information about function types that is only available through
+    // IDebugHostType2.
+    //
+
+    // GetFunctionVarArgsKind():
+    //
+    // Indicates whether and what kind of variable arguments a function takes.
+    //
+    STDMETHOD(GetFunctionVarArgsKind)(
+        THIS_
+        _Out_ VarArgsKind* varArgsKind
+        ) PURE;
+
+    // GetFunctionInstancePointerType():
+    //
+    // Indicates what the type of the instance ("this") pointer passed to the function is.  This method will fail
+    // if the function is not an instance method on a class.
+    //
+    STDMETHOD(GetFunctionInstancePointerType)(
+        THIS_
+        _Out_ IDebugHostType2** instancePointerType
+        ) PURE;
+
+};
+
+
+//
+// IDebugHostStatus
+//
+// This interface exposes the status of the underlying IDebugHost.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostStatus
+DECLARE_INTERFACE_(IDebugHostStatus, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostStatus:
+
+    // PollUserInterrupt():
+    //
+    // Returns whether a user interrupt has been set. Ie: Ctrl+Break
+    //
+    STDMETHOD(PollUserInterrupt)(
+        THIS_
+        _Out_ bool* interruptRequested
+        ) PURE;
+};
+
+//**************************************************************************
+// Script Provider and Scripting Interfaces:
+//
+
+// IDataModelScriptClient:
+//
+// A host or other client which wishes to interface with a scripting extension must have one
+// or more implementations of IDataModelScriptClient in order to receive messages from the script
+// provider.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptClient
+DECLARE_INTERFACE_(IDataModelScriptClient, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptClient:
+
+    // ReportError():
+    //
+    // Called from the provider when there is an error in the execution of the script.  The class of error,
+    // error code, error message, and position of the error within the script are passed.  The client
+    // decides what to do with the error information.
+    //
+    STDMETHOD(ReportError)(
+        THIS_
+        _In_ ErrorClass errClass,
+        _In_ HRESULT hrFail,
+        _In_opt_ PCWSTR message,
+        _In_ ULONG line,
+        _In_ ULONG position
+        ) PURE;
+
+};
+
+// IDataModelScriptTemplate:
+//
+// If a script provider has template content that it wishes to advertise to the host, it implements
+// this interface.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptTemplate
+DECLARE_INTERFACE_(IDataModelScriptTemplate, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptTemplate:
+
+    // GetName():
+    //
+    // Gets the name of the template content.  This may fail with E_NOTIMPL if the template does not
+    // have a name.  A default template is not required to have a name.  All other templates must.
+    //
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR *templateName
+        ) PURE;
+
+    // GetDescription():
+    //
+    // Gets the description for this template content. This may fail with E_NOTIMPL if the template does
+    // not have a description.
+    //
+    STDMETHOD(GetDescription)(
+        THIS_
+        _Out_ BSTR *templateDescription
+        ) PURE;
+
+    // GetContent():
+    //
+    // Returns a stream over the template content.
+    //
+    STDMETHOD(GetContent)(
+        THIS_
+        _COM_Outptr_ IStream **contentStream
+        ) PURE;
+
+
+};
+
+// IDataModelScript:
+//
+// The interface which represents an individual script managed by a script provider.  Each script provider
+// must be capable of creating and managing multiple scripts.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScript
+DECLARE_INTERFACE_(IDataModelScript, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScript:
+
+    // GetName():
+    //
+    // Gets the present "name" of the script.
+    //
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR *scriptName
+        ) PURE;
+
+    // Rename():
+    //
+    // Renames the script and, in so doing, may alter where the host projects the contents of the script
+    // into the debugger namespace.
+    //
+    STDMETHOD(Rename)(
+        THIS_
+        _In_ PCWSTR scriptName
+        ) PURE;
+
+    // Populate():
+    //
+    // Called by the host (or client) in order to change/synchronize the "content" of the script.  This does *NOT*
+    // cause execution of the script of any objects that the script manipulates.  It merely tells the script provider
+    // that the content of the script has changed so that it may synchronize its own internal state.
+    //
+    // The implementer of the Populate method may not hold the content stream between the Populate and Execute calls.
+    // It *MUST* synchronize any internal state and data structures during a Populate.
+    //
+    STDMETHOD(Populate)(
+        THIS_
+        _In_ IStream *contentStream
+        ) PURE;
+
+    // Execute():
+    //
+    // Executes the content of the script.  Note taht execution of the script is a two way communcation between the
+    // script provider and the script client.  Errors, debugging control, and other semantics are passed across the
+    // communication channel between IDataModelScript and IDataModelScriptClient.
+    //
+    // After a successful return, the script provider's projection of the script should be active.  Note that if the
+    // script fails to execute (e.g.: syntax errors, etc...), the prior contents of the projection should *not*
+    // disappear.
+    //
+    // For a properly written script provider and script environment, calling Execute multiple times without an
+    // intervening Populate() or Unlink() call should be idempotent.  Execution of a script should create a bridge
+    // between the object model of the debugger and that of the script.  It should not produce side effecting results
+    // on the state of the debug target.   Utilizing properties, methods, or events on the bridge produced via
+    // Execute may indeed produce side effecting results.
+    //
+    STDMETHOD(Execute)(
+        THIS_
+        _In_ IDataModelScriptClient *client
+        ) PURE;
+
+    // Unlink():
+    //
+    // Undoes the Execute operation.  Any links which were made between the script and the object model are unlinked.
+    // After an Unlink operation, the script may be re-executed via a call to Execute or it may be released.
+    //
+    // It is expected that this is called, for instance, upon the closing of a script window by a UI client.
+    //
+    STDMETHOD(Unlink)(
+        THIS
+        ) PURE;
+
+    // IsInvocable():
+    //
+    // Returns whether or not the script is invocable (e.g.: it has some semblance of a main function as defined by
+    // its provider).  This method may only be called after a successful Execute.
+    //
+    // If this method returns true in its argument, InvokeMain() may be called.
+    //
+    STDMETHOD(IsInvocable)(
+        THIS_
+        _Out_ bool *isInvocable
+        ) PURE;
+
+    // InvokeMain():
+    //
+    // If the script has a main function which is intended to execute from a UI invocation, the provider can indicate
+    // such in metadata and the call to this method will "invoke" the script.  Note that this is distinct from *Execute*
+    // which runs all root code and bridges the script to the namespace of the underlying host.
+    //
+    // This method may fail with E_NOTIMPL if the script does not contain a "named main function" or the provider does
+    // not define a "main" method.
+    //
+    STDMETHOD(InvokeMain)(
+        THIS_
+        _In_ IDataModelScriptClient *client
+        ) PURE;
+
+};
+
+//
+// IDataModelScriptTemplateEnumerator:
+//
+// Core interface which enumerates any and all template content available from the provider for
+// the creation of new prepopulated scripts.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptTemplateEnumerator
+DECLARE_INTERFACE_(IDataModelScriptTemplateEnumerator, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptTemplateEnumerator:
+
+    // Reset():
+    //
+    // Resets the enumerator to the first element.
+    //
+    STDMETHOD(Reset)(
+        THIS
+        ) PURE;
+
+    // GetNext():
+    //
+    // Gets the next script template which is being enumerated and moves the enumerator
+    // to the next position.  E_BOUNDS will be returned at the end of enumeration.
+    //
+    STDMETHOD(GetNext)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptTemplate **templateContent
+        ) PURE;
+};
+
+//
+// IDataModelScriptProvider:
+//
+// The core interface that any extension which wishes to act as a script provider to the underlying host must
+// implement.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptProvider
+DECLARE_INTERFACE_(IDataModelScriptProvider, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptProvider:
+
+    // GetName():
+    //
+    // Returns the name (type) of the script provider (e.g.: "JavaScript", "Python", "NatVis", etc...)
+    //
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR *name
+        ) PURE;
+
+    // GetExtension():
+    //
+    // Returns the extension which the script provider supports (e.g.: "js", "py", "NatVis", etc...).  Loads
+    // of scripts with this extension will automatically be directed to the appropriately registered script
+    // provider.
+    //
+    STDMETHOD(GetExtension)(
+        THIS_
+        _Out_ BSTR *extension
+        ) PURE;
+
+    // CreateScript():
+    //
+    // When the host wishes to create a script based on the provider, it calls this method.
+    //
+    STDMETHOD(CreateScript)(
+        THIS_
+        _COM_Outptr_ IDataModelScript **script
+        ) PURE;
+
+    // GetDefaultTemplateContent():
+    //
+    // Returns an object which represents the "default template" content for the scrtipt.  If the script
+    // provider does not have any default template content, E_NOTIMPL may be returned from this interface.
+    //
+    STDMETHOD(GetDefaultTemplateContent)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptTemplate **templateContent
+        ) PURE;
+
+    // EnumerateTemplates():
+    //
+    // Enumerates all varying templates that are available from the provider.  The default template
+    // will enumerate in this set.  In addition, the provider may enumerate an arbitrary number of "named"
+    // templates which have varying content prepopulated for differing purposes.
+    //
+    STDMETHOD(EnumerateTemplates)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptTemplateEnumerator **enumerator
+        ) PURE;
+
+};
+
+#undef INTERFACE
+#define INTERFACE IDataModelScriptProviderEnumerator
+DECLARE_INTERFACE_(IDataModelScriptProviderEnumerator, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptProviderEnumerator:
+
+    // Reset():
+    //
+    // Resets the enumerator to the first element.
+    //
+    STDMETHOD(Reset)(
+        THIS
+        ) PURE;
+
+    // GetNext():
+    //
+    // Gets the next script provider which is being enumerated and moves the enumerator
+    // to the next position.  E_BOUNDS will be returned at the end of enumeration.
+    //
+    STDMETHOD(GetNext)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptProvider **provider
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDataModelScriptManager
+DECLARE_INTERFACE_(IDataModelScriptManager, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptManager:
+
+    // GetDefaultNameBinder():
+    //
+    // Gets the default name binder for script providers.  This returns an object which
+    // can bind a name in the context of an object and does so according to a default set
+    // of rules.  Script providers can make use of this provider to provide consistency
+    // in name resolution across providers.
+    //
+    STDMETHOD(GetDefaultNameBinder)(
+        THIS_
+        _COM_Outptr_ IDataModelNameBinder **ppNameBinder
+        ) PURE;
+
+    // RegisterScriptProvider():
+    //
+    // An extension which wishes to register itself as a provider of scripting functionality to
+    // the host calls this method in order to register itself.  Once registered, the provider
+    // should work in all contexts that general scripting works in the underlying debugger host.
+    //
+    // Such registration may fail if there is already a provider registered under a particular name
+    // or for a particular script extension.
+    //
+    STDMETHOD(RegisterScriptProvider)(
+        THIS_
+        _In_ IDataModelScriptProvider *provider
+        ) PURE;
+
+    // UnregisterScriptProvider():
+    //
+    // Called by an extension which wishes to remove its registration of being a script provider.  Note
+    // that if scripts are still loaded that reference the provider, they will continue to function.
+    //
+    // This only prevents the creation or loading of new scripts.
+    //
+    STDMETHOD(UnregisterScriptProvider)(
+        THIS_
+        _In_ IDataModelScriptProvider *provider
+        ) PURE;
+
+    // FindProviderForScriptType():
+    //
+    // Finds a provider by its registered name (e.g.: "JavaScript", "Python", "NatVis", etc...).
+    // If no such provider can be found, E_BOUNDS is returned.
+    //
+    // Note that the comparison on 'scriptType' is case insensitive.
+    //
+    STDMETHOD(FindProviderForScriptType)(
+        THIS_
+        _In_ PCWSTR scriptType,
+        _COM_Outptr_ IDataModelScriptProvider **provider
+        ) PURE;
+
+    // FindProviderForScriptExtension():
+    //
+    // Finds a provider by its script extension registration (e.g.: "js", "py", "NatVis", etc...).
+    // If no such provider can be found, E_BOUNDS is returned.
+    //
+    // Note that the comparison on 'scriptExtension' is case insensitive.
+    //
+    STDMETHOD(FindProviderForScriptExtension)(
+        THIS_
+        _In_ PCWSTR scriptExtension,
+        _COM_Outptr_ IDataModelScriptProvider **provider
+        ) PURE;
+
+    // EnumerateScriptProviders():
+    //
+    // Returns an enumerator for all registered script providers in the system.  A client
+    // which wishes to have UI to allow for the creation of arbitrary language scripts can
+    // utilize this to determine which providers are present in the system.
+    //
+    STDMETHOD(EnumerateScriptProviders)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptProviderEnumerator **enumerator
+        ) PURE;
+
+};
+
+//
+// IDynamicKeyProviderConcept
+//
+// Any object which provides a dynamic set of keys and values (e.g.: a bridge to a dynamic scripting language)
+// can be a key provider.
+//
+// Unlike most concepts, a client should not GetConcept(IID_IDynamicKeyProviderConcept).  Doing so returns the **FIRST**
+// dynamic key provider on the object.  The data model will internally use this concept on each model as it enumerates
+// keys.
+//
+#undef INTERFACE
+#define INTERFACE IDynamicKeyProviderConcept
+DECLARE_INTERFACE_(IDynamicKeyProviderConcept, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDynamicKeyProviderConcept:
+
+    // GetKey():
+    //
+    // Returns the key from the dynamic key provider and any metadata associated with that
+    // key.  In the event that key is not present (but no other error occurs), the provider
+    // must return *hasKey = false / S_OK.  A failure of this call is considered a failure
+    // to fetch a key and will explicitly halt the search for the key.  Returning *hasKey = false / S_OK
+    // will not stop the search.
+    //
+    // It is perfectly legal for GetKey to return a boxed property accessor as the key.  This would
+    // be semantically identical to an IModelObject::GetKey returning a property accessor.
+    //
+    STDMETHOD(GetKey)(
+        THIS_
+        _In_ IModelObject *contextObject,
+        _In_ PCWSTR key,
+        _COM_Outptr_opt_result_maybenull_ IModelObject** keyValue,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata,
+        _Out_opt_ bool *hasKey
+        ) PURE;
+
+    // SetKey():
+    //
+    // Sets a key in the dynamic provider.  This is considered the creation of a new property on the
+    // provider.  Note that a provider which does not support any notion of something like the creation
+    // of expand properties should return E_NOTIMPL here.
+    //
+    STDMETHOD(SetKey)(
+        THIS_
+        _In_ IModelObject *contextObject,
+        _In_ PCWSTR key,
+        _In_ IModelObject *keyValue,
+        _In_ IKeyStore *metadata
+        ) PURE;
+
+    // EnumerateKeys():
+    //
+    // Enumerates the keys within the dynamic key provider.  The returned enumerator must behave as per an
+    // EnumerateKeys(...) call on IModelObject and not as EnumerateKeyValues or any of the other enumeration
+    // variants.
+    //
+    // Note that from the perspective of a single dynamic key provider, it is illegal to enumerate multiple keys
+    // of the same name that are physically distinct keys.
+    //
+    STDMETHOD(EnumerateKeys)(
+        THIS_
+        _In_ IModelObject *contextObject,
+        _COM_Outptr_ IKeyEnumerator **ppEnumerator
+        ) PURE;
+
+};
+
+//
+// IDynamicConceptProviderConcept
+//
+// Any object which provides a dynamic set of concepts and implementations (e.g.: a bridge to a dynamic scripting language)
+// can be a concept provider.  There are consequences and limitations of being a dynamic concept provider:
+//
+//     - An object can only be declared to be a dynamic concept provider **BEFORE** any other non IDynamic* concepts are
+//       added to the object.
+//
+//     - Once you declare that an object is a dynamic concept provider, that fact can *NEVER* be changed!
+//
+//     - An object which is a dynamic concept provider only has a single parent model.  That parent model is presented
+//       to the dynamic concept provider to utilize.  All calls to query/change parents affect this single parent model
+//       and *NOT* the object itself.
+//
+//     - The provider must decide how to deal with parent models that are added dynamically based on concepts.
+//
+// Unlike most concepts, a client should not GetConcept(IID_IDynamicConceptProviderConcept).  Doing so returns the **FIRST**
+// dynamic concept provider on the object.  The data model will internally use this concept on each model as it looks up
+// concepts.
+//
+// A dynamic concept provider can **NEVER** return any IDynamic*Concept interface!  You cannot have a dynamic concept provider
+// say that it is a dynamic key provider, for instance.
+//
+#undef INTERFACE
+#define INTERFACE IDynamicConceptProviderConcept
+DECLARE_INTERFACE_(IDynamicConceptProviderConcept, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDynamicConceptProviderConcept:
+
+    // GetConcept():
+    //
+    // Returns the concept from the dynamic concept provider and any metadata associated with that
+    // concept.  In the event that the concept is not present (but no other error occurs), the provider
+    // must return *hasConcept = false / S_OK.  A failure of this call is considered a failure
+    // to fetch a concept and will explicitly halt the search for the concept.  Returning *hasConcept = false / S_OK
+    // will not stop the search.
+    //
+    STDMETHOD(GetConcept)(
+        THIS_
+        _In_ IModelObject *contextObject,
+        _In_ REFIID conceptId,
+        _COM_Outptr_result_maybenull_ IUnknown **conceptInterface,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore **conceptMetadata,
+        _Out_ bool *hasConcept
+        ) PURE;
+
+    // SetConcept():
+    //
+    // Sets a concept in the dynamic provider.  Note that a provider which does not allow the creation
+    // of the concept shoiuld return E_NOTIMPL here.
+    //
+    STDMETHOD(SetConcept)(
+        THIS_
+        _In_ IModelObject *contextObject,
+        _In_ REFIID conceptId,
+        _In_ IUnknown *conceptInterface,
+        _In_opt_ IKeyStore *conceptMetadata
+        ) PURE;
+
+    // NotifyParent():
+    //
+    // Notifies the concept provider of the **SINGLE** parent model which is present on the provider.
+    //
+    STDMETHOD(NotifyParent)(
+        THIS_
+        _In_ IModelObject *parentModel
+        ) PURE;
+
+    // NotifyParentChange():
+    //
+    // Notifies the concept provider that a static change has been made to the set of parents.
+    //
+    STDMETHOD(NotifyParentChange)(
+        THIS_
+        _In_ IModelObject *parentModel
+        ) PURE;
+
+    // NotifyDestruct():
+    //
+    // Notifies that the object which houses the dynamic concept provider is destructing.  This allows
+    // a dynamic concept provider to clear caches if need be.
+    //
+    STDMETHOD(NotifyDestruct)(
+        THIS
+        ) PURE;
+
+};
+
+// ScriptChangeKind:
+//
+// Indicates the type of notification firing to the host.
+//
+enum ScriptChangeKind
+{
+    // The script has been renamed
+    ScriptRename
+};
+
+// IDataModelScriptHostContext:
+//
+// A host context for a given script.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptHostContext
+DECLARE_INTERFACE_(IDataModelScriptHostContext, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptHostContext:
+
+    // NotifyScriptChange():
+    //
+    // Notifies the host of a change to the script.
+    //
+    STDMETHOD(NotifyScriptChange)(
+        THIS_
+        _In_ IDataModelScript* script,
+        _In_ ScriptChangeKind changeKind
+        ) PURE;
+
+    // GetNamespaceObject():
+    //
+    // Gets the namespace object that the host has provided for the script.
+    //
+    STDMETHOD(GetNamespaceObject)(
+        THIS_
+        _COM_Outptr_ IModelObject** namespaceObject
+        ) PURE;
+
+};
+
+//
+// IDebugHostScriptHost:
+//
+// Any host which supports the data model's notion of scripting must provide an implementation of this interface.
+// Script providers utilize this to bridge to the namespace of the host.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostScripthost
+DECLARE_INTERFACE_(IDebugHostScriptHost, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostScriptHost:
+
+    // CreateContext():
+    //
+    // Called in order to create a context for a script.  A context from the host includes
+    // a namespace object where the contents of the script can be bridged.
+    //
+    STDMETHOD(CreateContext)(
+        THIS_
+        _In_ IDataModelScript* script,
+        _COM_Outptr_ IDataModelScriptHostContext** scriptContext
+        ) PURE;
+
+};
+
+//
+// IDataModelNameBinder:
+//
+// The default name binder for script providers.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelNameBinder
+DECLARE_INTERFACE_(IDataModelNameBinder, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelNameBinder:
+
+    // BindValue():
+    //
+    // Performs the equivalent of "contextObject . 'name'" on the given object according
+    // to a default set of binding rules.  Such a default binder provides consistency between
+    // script providers.
+    //
+    // The binding result is the result by value.
+    //
+    STDMETHOD(BindValue)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _In_ PCWSTR name,
+        _COM_Errorptr_ IModelObject** value,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // BindReference():
+    //
+    // Performs the equivalent of "contextObject . 'name'" on the given object according
+    // to a default set of binding rules.  Such a default binder provides consistency between
+    // script providers.
+    //
+    // The binding result is the result by reference.
+    //
+    STDMETHOD(BindReference)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _In_ PCWSTR name,
+        _COM_Errorptr_ IModelObject** reference,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    // EnumerateValues():
+    //
+    // Enumerates the set of names and values which will bind against the object according
+    // to BindValue(...).
+    //
+    // Unlike the standard "EnumerateKeys" and "EnumerateRawValues" and the like which may
+    // return multiple names with the same value (for base classes, parent models, and the like),
+    // this enumerator will *ONLY* return the specific set of names which will bind with
+    // BindValue and BindReference.  Names will never be duplicated.
+    //
+    // There is a significantly higher cost in providing this functionality.
+    //
+    STDMETHOD(EnumerateValues)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _COM_Outptr_ IKeyEnumerator** enumerator
+        ) PURE;
+
+    // EnumerateReferences():
+    //
+    // Enumerates the set of names and values which will bind against the object according
+    // to BindReference(...).
+    //
+    // Unlike the standard "EnumerateKeys" and "EnumerateRawValues" and the like which may
+    // return multiple names with the same value (for base classes, parent models, and the like),
+    // this enumerator will *ONLY* return the specific set of names which will bind with
+    // BindValue and BindReference.  Names will never be duplicated.
+    //
+    // There is a significantly higher cost in providing this functionality.
+    //
+    STDMETHOD(EnumerateReferences)(
+        THIS_
+        _In_ IModelObject* contextObject,
+        _COM_Outptr_ IKeyEnumerator** enumerator
+        ) PURE;
+
+};
+
+//
+// IModelKeyReference2:
+//
+// Second version of IModelKeyReference
+// Represents a reference to a key which can be resolved (dereferenced) to get the underlying key.
+//
+// This interface is never directly implemented by a client.
+//
+#undef INTERFACE
+#define INTERFACE IModelKeyReference2
+DECLARE_INTERFACE_(IModelKeyReference2, IModelKeyReference)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IModelKeyReference:
+
+    STDMETHOD(GetKeyName)(
+        THIS_
+        _Out_ BSTR* keyName
+        ) PURE;
+
+    STDMETHOD(GetOriginalObject)(
+        THIS_
+        _COM_Outptr_ IModelObject** originalObject
+        ) PURE;
+
+    STDMETHOD(GetContextObject)(
+        THIS_
+        _COM_Outptr_ IModelObject** containingObject
+        ) PURE;
+
+    //*************************************************
+    // Accessors:
+    //
+
+    STDMETHOD(GetKey)(
+        THIS_
+        _COM_Errorptr_opt_ IModelObject** object,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    STDMETHOD(GetKeyValue)(
+        THIS_
+        _COM_Errorptr_opt_ IModelObject** object,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    STDMETHOD(SetKey)(
+        THIS_
+        _In_opt_ IModelObject* object,
+        _In_opt_ IKeyStore* metadata
+        ) PURE;
+
+    STDMETHOD(SetKeyValue)(
+        THIS_
+        _In_ IModelObject* object
+        ) PURE;
+
+    //*************************************************
+    // IModelKeyReference2:
+
+    // OverrideContextObject:
+    //
+    // Changes the context object which is used to resolve the key reference.  If the key reference
+    // refers to a key which is a property (or to a dynamic key provider), 'newContextObject' as indicated
+    // by a call to this method will be passed to the property getter or the dynamic key provider in
+    // lieu of the context object from the key fetch.
+    //
+    // This is useful to certain script providers when building cross-language inheritence chains.
+    //
+    STDMETHOD(OverrideContextObject)(
+        THIS_
+        _In_ IModelObject* newContextObject
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugHostEvaluator2
+DECLARE_INTERFACE_(IDebugHostEvaluator2, IDebugHostEvaluator)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostEvaluator:
+
+    STDMETHOD(EvaluateExpression)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ PCWSTR expression,
+        _In_opt_ IModelObject* bindingContext,
+        _COM_Errorptr_ IModelObject** result,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    STDMETHOD(EvaluateExtendedExpression)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ PCWSTR expression,
+        _In_opt_ IModelObject* bindingContext,
+        _COM_Errorptr_ IModelObject** result,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostEvaluator2:
+
+    // AssignTo():
+    //
+    // For a caller which has a model based reference to a *language* value, evaluate
+    // (assignmentReference = assignmentValue) and return the result of the assignment
+    // according to the underlying language semantics.
+    //
+    STDMETHOD(AssignTo)(
+        THIS_
+        _In_ IModelObject* assignmentReference,
+        _In_ IModelObject* assignmentValue,
+        _COM_Errorptr_ IModelObject** assignmentResult,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore** assignmentMetadata
+        ) PURE;
+
+};
+
+//
+// IDataModelManager2:
+//
+// The second version of the interface for the data model manager.  This is the interface by which new objects are created,
+// intrinsic values are boxed and unboxed, and models are registered for types.
+//
+// This interface is never directly implemented by a client.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelManager2
+DECLARE_INTERFACE_(IDataModelManager2, IDataModelManager)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelManager
+
+    STDMETHOD(Close)(
+        THIS
+        ) PURE;
+
+
+    STDMETHOD(CreateNoValue)(
+        THIS_
+        _Out_ IModelObject** object
+        ) PURE;
+
+    STDMETHOD(CreateErrorObject)(
+        THIS_
+        _In_ HRESULT hrError,
+        _In_opt_ PCWSTR pwszMessage,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    STDMETHOD(CreateTypedObject)(
+        THIS_
+        _In_opt_ IDebugHostContext* context,
+        _In_ Location objectLocation,
+        _In_ IDebugHostType* objectType,
+        _COM_Errorptr_ IModelObject** object
+        ) PURE;
+
+    STDMETHOD(CreateTypedObjectReference)(
+        THIS_
+        _In_opt_ IDebugHostContext* context,
+        _In_ Location objectLocation,
+        _In_ IDebugHostType* objectType,
+        _COM_Errorptr_ IModelObject** object
+        ) PURE;
+
+    STDMETHOD(CreateSyntheticObject)(
+        THIS_
+        _In_opt_ IDebugHostContext* context,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    STDMETHOD(CreateDataModelObject)(
+        THIS_
+        _In_ IDataModelConcept* dataModel,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    STDMETHOD(CreateIntrinsicObject)(
+        THIS_
+        _In_ ModelObjectKind objectKind,
+        _In_ VARIANT* intrinsicData,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    STDMETHOD(CreateTypedIntrinsicObject)(
+        THIS_
+        _In_ VARIANT* intrinsicData,
+        _In_ IDebugHostType* type,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+    STDMETHOD(GetModelForTypeSignature)(
+        THIS_
+        _In_ IDebugHostTypeSignature* typeSignature,
+        _Out_ IModelObject** dataModel
+        ) PURE;
+
+    STDMETHOD(GetModelForType)(
+        THIS_
+        _In_ IDebugHostType* type,
+        _COM_Outptr_ IModelObject** dataModel,
+        _COM_Outptr_opt_ IDebugHostTypeSignature** typeSignature,
+        _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches
+        ) PURE;
+
+    STDMETHOD(RegisterModelForTypeSignature)(
+        THIS_
+        _In_ IDebugHostTypeSignature* typeSignature,
+        _In_ IModelObject* dataModel
+        ) PURE;
+
+    STDMETHOD(UnregisterModelForTypeSignature)(
+        THIS_
+        _In_ IModelObject* dataModel,
+        _In_opt_ IDebugHostTypeSignature* typeSignature
+        ) PURE;
+
+    STDMETHOD(RegisterExtensionForTypeSignature)(
+        THIS_
+        _In_ IDebugHostTypeSignature* typeSignature,
+        _In_ IModelObject* dataModel
+        ) PURE;
+
+    STDMETHOD(UnregisterExtensionForTypeSignature)(
+        THIS_
+        _In_ IModelObject* dataModel,
+        _In_opt_ IDebugHostTypeSignature* typeSignature
+        ) PURE;
+
+    STDMETHOD(CreateMetadataStore)(
+        THIS_
+        _In_opt_ IKeyStore* parentStore,
+        _COM_Outptr_ IKeyStore** metadataStore
+        ) PURE;
+
+    STDMETHOD(GetRootNamespace)(
+        THIS_
+        _COM_Outptr_ IModelObject** rootNamespace
+        ) PURE;
+
+    STDMETHOD(RegisterNamedModel)(
+        THIS_
+        _In_ PCWSTR modelName,
+        _In_ IModelObject *modeObject
+        ) PURE;
+
+    STDMETHOD(UnregisterNamedModel)(
+        THIS_
+        _In_ PCWSTR modelName
+        ) PURE;
+
+    STDMETHOD(AcquireNamedModel)(
+        THIS_
+        _In_ PCWSTR modelName,
+        _COM_Outptr_ IModelObject **modelObject
+        ) PURE;
+
+    //*************************************************
+    // IDataModelManager2
+    //
+
+    // AcquireSubNamespace():
+    //
+    // A convenience method for acquiring (and registering if necessary) a sub-namespace on an object.
+    //
+    // modelName
+    //     the name of the model which is being extended with a namespace (e.g.: "Debugger.Models.Process")
+    //
+    // subNamespaceModelName
+    //     the name of the model which is being added (e.g.: "Debugger.Models.Process.Io")
+    //
+    // accessName
+    //     the name used to access the namespace from the parent object (e.g.: "Io")
+    //
+    // metadata
+    //     the metadata store used on the accessor for the namespace (e.g.: the help on "Io" if it is newly created)
+    //
+    // namespaceModelObject
+    //     the namespace model returned is placed here
+    //
+    STDMETHOD(AcquireSubNamespace)(
+        THIS_
+        _In_ PCWSTR modelName,
+        _In_ PCWSTR subNamespaceModelName,
+        _In_ PCWSTR accessName,
+        _In_opt_ IKeyStore *metadata,
+        _COM_Outptr_ IModelObject **namespaceModelObject
+        ) PURE;
+
+    // CreateTypedIntrinsicObjectEx():
+    //
+    // A version of CreateTypedIntrinsicObject which allows for the passing of an explicit context.  Such is only
+    // useful for intrinsics which represent addresses in the target (such as pointers).
+    //
+    STDMETHOD(CreateTypedIntrinsicObjectEx)(
+        THIS_
+        _In_opt_ IDebugHostContext* context,
+        _In_ VARIANT* intrinsicData,
+        _In_ IDebugHostType* type,
+        _COM_Outptr_ IModelObject** object
+        ) PURE;
+
+};
+
+//
+// IDebugHostMemory2:
+//
+// The second version of the core memory access interface which a debug host presents.
+// This interface can be QI'd from IDebugHost in order to access memory regions (be they
+// virtual / physical / registers / etc...)
+//
+// Note that the combination of context and "location" in the methods of this interface
+// need not necessarily refer to the virtual address space of the target.  They can refer to the
+// physical address space of the target, an I/O space of the target, a register space of the target, etc...
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostMemory2
+DECLARE_INTERFACE_(IDebugHostMemory2, IDebugHostMemory)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostMemory:
+
+    STDMETHOD(ReadBytes)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _Out_writes_bytes_(bufferSize) void* buffer,
+        _In_ ULONG64 bufferSize,
+        _Out_opt_ ULONG64* bytesRead
+        ) PURE;
+
+    STDMETHOD(WriteBytes)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _In_reads_bytes_(bufferSize) void* buffer,
+        _In_ ULONG64 bufferSize,
+        _Out_opt_ ULONG64* bytesWritten
+        ) PURE;
+
+    STDMETHOD(ReadPointers)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _In_ ULONG64 count,
+        _Out_writes_(count) ULONG64* pointers
+        ) PURE;
+
+    STDMETHOD(WritePointers)(
+        THIS_
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _In_ ULONG64 count,
+        _In_reads_(count) ULONG64* pointers
+        ) PURE;
+
+    STDMETHOD(GetDisplayStringForLocation)(
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _In_ bool verbose,
+        _Out_ BSTR* locationName
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostMemory2:
+
+    // LinearizeLocation():
+    //
+    // Takes a location which may represent something other than a virtual memory address and attempts
+    // to linearize the location into a virtual memory address within the given context.  This operation may fail
+    // if the location cannot be represented by a virtual address (e.g.: it's a register).
+    //
+    STDMETHOD(LinearizeLocation)(
+        _In_ IDebugHostContext* context,
+        _In_ Location location,
+        _Out_ Location *pLinearizedLocation
+        ) PURE;
+
+};
+
+// IDebugHostExtensibility:
+//
+// An interface which allows the callers to extend capabilities of the host based on the data model.
+// This interface and all its methods are optional for the host to implement.
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostExtensibility
+DECLARE_INTERFACE_(IDebugHostExtensibility, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostExtensibility:
+
+    // CreateFunctionAlias():
+    //
+    // For a function that the script wants to make a "quick alias" for, allow the host to create
+    // such an alias.  The meaning of such an alias is host specific.  It may, for instance, mean
+    // that the alias name is available as a root function in the host's expression evaluator.  It
+    // may mean that calling the function can be done through "!alias" at a command line.
+    //
+    STDMETHOD(CreateFunctionAlias)(
+        THIS_
+        _In_ PCWSTR aliasName,
+        _In_ IModelObject *functionObject
+        ) PURE;
+
+    // DestroyFunctionAlias():
+    //
+    // Destroys a previously created function alias.
+    //
+    STDMETHOD(DestroyFunctionAlias)(
+        THIS_
+        _In_ PCWSTR aliasName
+        ) PURE;
+
+};
+// enum ScriptDebugState:
+//
+// Defines the current debugging state of a script
+//
+enum ScriptDebugState
+{
+    // ScriptDebugNoDebugger: indicates that debugging is not active on the script
+    ScriptDebugNoDebugger,
+
+    // ScriptDebugNotExecuting: indicates that no code within the script is actively executing
+    ScriptDebugNotExecuting,
+
+    // ScriptDebugExecuting: indicates that the script is executing code
+    ScriptDebugExecuting,
+
+    // ScriptDebugBreak: the script status is that it is broken into the script debugger
+    ScriptDebugBreak
+};
+
+// enum ScriptDebugEventFilter:
+//
+// Defines the set of debug events / exceptions which the script debugger can (potentially) auto-break
+// on
+//
+enum ScriptDebugEventFilter
+{
+       // ScriptDebugEventFilterEntry: Indicates that a break on *EVERY ENTRY* into the script from outside should break into the debugger
+    ScriptDebugEventFilterEntry,
+
+    // ScriptDebugEventFilterException: Indicates that any first chance exception should immediately break into the debugger
+    ScriptDebugEventFilterException,
+
+    // ScriptDebugEventFilterUnhandledException: Indicates that unhandled exceptions should immediately break into the debugger
+    ScriptDebugEventFilterUnhandledException,
+
+    // ScriptDebugEventFilterAbort: Indicates that an abort (core debugger BREAK/STOP this action) should break into the script
+    //                              debugger rather than aborting the script execution
+    ScriptDebugEventFilterAbort
+};
+
+// enum ScriptDebugEvent:
+//
+// Defines what debug event occurred.
+//
+enum ScriptDebugEvent
+{
+    // ScriptDebugBreakpoint: indicates that a breakpoint was hit
+    ScriptDebugBreakpoint,
+
+    // ScriptDebugStep: indicates that a step event occurred
+    ScriptDebugStep,
+
+    // ScriptDebugException: indicates that an exception occurred.  The ScriptDebugEventInformation will fill in .u.ExceptionInformation
+    //                       and the outpassed object is a data model conversion of the actual exception
+    ScriptDebugException,
+
+    // ScriptDebugAsyncBreak: indicates that a break into the script occurred (either because of something like break on entry, break on abort,
+    //                        etc...)
+    ScriptDebugAsyncBreak
+
+};
+
+// enum ScriptExecutionKind
+//
+// Defines the kind of execution to do.
+//
+enum ScriptExecutionKind
+{
+    // ScriptExecutionNormal: indicates that you would like the script to execute normally
+    ScriptExecutionNormal,
+
+    // ScriptExecutionStepIn: indicates that you want to perform a "step in" operation
+    ScriptExecutionStepIn,
+
+    // ScriptExecutionStepOut: indicates that you want to perform a "step out" operation
+    ScriptExecutionStepOut,
+
+    // ScriptExecutionStepOver: indicates that you want to perform a "step over" operation
+    ScriptExecutionStepOver,
+
+};
+
+// ScriptDebugPosition:
+//
+// Defines a position within a script.
+//
+struct ScriptDebugPosition
+{
+    ULONG Line;                 // A zero value indicates that the line cannot be determined
+    ULONG Column;               // A zero value indicates that the column cannot be determined
+};
+
+// ScriptDebugEventInformation:
+//
+// A simple struct containing information about a particular debug event.
+//
+struct ScriptDebugEventInformation
+{
+    ScriptDebugEvent DebugEvent;
+    ScriptDebugPosition EventPosition;          // The line/column of script at which the debug event occurred (0 values : cannot determine)
+    ScriptDebugPosition EventSpanEnd;           // The ending line/column of script at which the debug event occurred (0 values : cannot determine)
+
+    union
+    {
+        struct
+        {
+            bool IsUncaught;
+        } ExceptionInformation;
+
+        struct
+        {
+            ULONG64 BreakpointId;
+        } BreakpointInformation;
+
+    } u;
+};
+
+// IDataModelScriptDebugClient:
+//
+// Any client utilizing the debugger for a particular script must implement this interface.  The interface
+// will be called back to process any debug events.  Such callback will happen synchronously during the execution
+// of any script content.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptDebugClient
+DECLARE_INTERFACE_(IDataModelScriptDebugClient, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptDebugClient
+
+    //
+    // The debug client gets notified about any debug event which occurs.  The resume kind is normally
+    // a ScriptExecutionNormal but it can be changed by returning a different resume kind.
+    //
+    STDMETHOD(NotifyDebugEvent)(
+        _In_ ScriptDebugEventInformation *pEventInfo,
+        _In_ IDataModelScript *pScript,
+        _In_opt_ IModelObject *pEventDataObject,
+        _Inout_ ScriptExecutionKind *resumeEventKind
+        ) PURE;
+
+};
+
+// IDataModelScriptDebugVariableSetEnumerator:
+//
+// Enumerates a set of variables (arguments, parameters, locals, etc...)
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptDebugVariableSetEnumerator
+DECLARE_INTERFACE_(IDataModelScriptDebugVariableSetEnumerator, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptDebugVariableSetEnumerator:
+
+    // Reset():
+    //
+    // Resets the enumerator to the first variable in the set.
+    //
+    STDMETHOD(Reset)(
+        THIS
+        ) PURE;
+
+    // GetNext():
+    //
+    // Gets the next element in the set.  In certain cases, the variable "name" may be null
+    // on output (e.g.: for arguments which are not named)
+    //
+    STDMETHOD(GetNext)(
+        THIS_
+        _Out_ BSTR *variableName,
+        _COM_Outptr_opt_ IModelObject **variableValue,
+        _COM_Outptr_opt_result_maybenull_ IKeyStore **variableMetadata
+        ) PURE;
+
+};
+
+// IDataModelScriptDebugStackFrame:
+//
+// Represents a stack frame from the script provider.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptDebugStackFrame
+DECLARE_INTERFACE_(IDataModelScriptDebugStackFrame, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptDebugStackFrame:
+
+    // GetName():
+    //
+    // Gets the display name (e.g.: function name) of the frame.
+    //
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR *name
+        ) PURE;
+
+    // GetPosition():
+    //
+    // Gets the position of the execution within this frame in the script.  This may **ONLY** be called when the script is within a break
+    // represented by this stack.
+    //
+    // The position of the execution within this frame is always returned.  If the particular debugger is capable of returning the span
+    // of the "execution position" within the script, an ending position can be returned in positionSpanEnd.  If the debugger
+    // is not capable of this, the line and column values in the span end (if requested) should be set to zero.
+    //
+    // The line text can optionally be passed back by debug engines which support it.  There is no requirement that a script
+    // debugger be able to return more than line and column position.  If this is not supported, nullptr can be returned.
+    //
+    STDMETHOD(GetPosition)(
+        THIS_
+        _Out_ ScriptDebugPosition *position,
+        _Out_opt_ ScriptDebugPosition *positionSpanEnd,
+        _Out_opt_ BSTR *lineText
+        ) PURE;
+
+    // IsTransitionPoint():
+    //
+    // Returns whether this stack frame is a transition point into another script.  It is perfectly legal to E_NOTIMPL this
+    // particular method.
+    //
+    STDMETHOD(IsTransitionPoint)(
+        THIS_
+        _Out_ bool *isTransitionPoint
+        ) PURE;
+
+    // GetTransition():
+    //
+    // Returns the script that this frame was transitioned into from.  Note that a particular script debugger may not be able to
+    // detect discontinuity outside its own context.
+    //
+    // If the script debugger can detect whether the call came from the script passed, isTransitionContiguous should be set to true.
+    // If it is not (or cannot detect), isTransitionContiguous should be set to false.
+    //
+    // It is perfectly legal to E_NOTIMPL this particular method.
+    //
+    STDMETHOD(GetTransition)(
+        THIS_
+        _COM_Outptr_ IDataModelScript **transitionScript,
+        _Out_ bool *isTransitionContiguous
+        ) PURE;
+
+    // Evaluate():
+    //
+    // Evaluates an expression in the context of this stack frame and returns the result as a model object.
+    //
+    STDMETHOD(Evaluate)(
+        THIS_
+        _In_ PCWSTR pwszExpression,
+        _COM_Outptr_ IModelObject **ppResult
+        ) PURE;
+
+    // EnumerateLocals():
+    //
+    // Enumerates locals in the frame.
+    //
+    STDMETHOD(EnumerateLocals)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptDebugVariableSetEnumerator **variablesEnum
+        ) PURE;
+
+    // EnumerateArguments():
+    //
+    // Enumerates arguments to the function in this frame.
+    //
+    STDMETHOD(EnumerateArguments)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptDebugVariableSetEnumerator **variablesEnum
+        ) PURE;
+};
+
+// IDataModelScriptDebugStack:
+//
+// Represents a stack from the script provider.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptDebugStack
+DECLARE_INTERFACE_(IDataModelScriptDebugStack, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptDebugStack:
+
+    // GetFrameCount():
+    //
+    // Gets the number of stack frames within this stack.
+    //
+    STDMETHOD_(ULONG64, GetFrameCount)(
+        THIS
+        ) PURE;
+
+    // GetStackFrame():
+    //
+    // Gets a stack frame within the stack.
+    //
+    STDMETHOD(GetStackFrame)(
+        THIS_
+        _In_ ULONG64 frameNumber,
+        _COM_Outptr_ IDataModelScriptDebugStackFrame **stackFrame
+        ) PURE;
+};
+
+// IDataModelScriptDebugBreakpoint:
+//
+// Represents a breakpoint within the script.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptDebugBreakpoint
+DECLARE_INTERFACE_(IDataModelScriptDebugBreakpoint, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptDebugBreakpoint:
+
+    // GetId():
+    //
+    // Gets a unique identifier for this breakpoint **WITHIN THE CONTEXT** of this script.  The breakpoint ID may
+    // be unique beyond that depending on the provider but the only requirement is that it be unique within
+    // its script.
+    //
+    STDMETHOD_(ULONG64, GetId)(
+        THIS
+        ) PURE;
+
+    // IsEnabled():
+    //
+    // Indicates whether or not the breakpoint is enabled.
+    //
+    STDMETHOD_(bool, IsEnabled)(
+        THIS
+        ) PURE;
+
+    // Enable():
+    //
+    // Enables the breakpoint.
+    //
+    STDMETHOD_(void, Enable)(
+        THIS
+        ) PURE;
+
+    // Disable():
+    //
+    // Disables the breakpoint.
+    //
+    STDMETHOD_(void, Disable)(
+        THIS
+        ) PURE;
+
+    // Remove():
+    //
+    // Removes the breakpoint from its containing list.
+    //
+    STDMETHOD_(void, Remove)(
+        THIS
+        ) PURE;
+
+    // GetPosition():
+    //
+    // Gets the position of the breakpoint within the script.
+    //
+    STDMETHOD(GetPosition)(
+        _Out_ ScriptDebugPosition *position,
+        _Out_opt_ ScriptDebugPosition *positionSpanEnd,
+        _Out_opt_ BSTR *lineText
+        ) PURE;
+
+};
+
+// IDataModelScriptDebugBreakpointEnumerator:
+//
+// An enumeration of a set of breakpoints.
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptDebugBreakpointEnumerator
+DECLARE_INTERFACE_(IDataModelScriptDebugBreakpointEnumerator, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptDebugBreakpointEnumerator:
+
+    // Reset():
+    //
+    // Resets the enumerator
+    //
+    STDMETHOD(Reset)(
+        THIS
+        ) PURE;
+
+    // GetNext():
+    //
+    // Gets the next breakpoint.
+    //
+    STDMETHOD(GetNext)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint
+        ) PURE;
+
+};
+
+// IDataModelScriptDebug:
+//
+// An optional interface on scripts (objects which implement IDataModelScript).  If this interface is supported,
+// the script provider has a debug engine capable of some limited form of 'script debugging'.  This may include
+// stepping, setting breakpoints, inspecting data, etc...
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptDebug
+DECLARE_INTERFACE_(IDataModelScriptDebug, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptDebug:
+
+    // GetDebugState():
+    //
+    //
+    STDMETHOD_(ScriptDebugState, GetDebugState)(
+        THIS
+        ) PURE;
+
+    // GetCurrentPosition():
+    //
+    // Gets the current position of the script.  This may **ONLY** be called when the script is broken into the debugger.
+    // A call otherwise will fail.
+    //
+    // The current position of the script is always returned.  If the particular debugger is capable of returning the span
+    // of the "current position" within the script, an ending position can be returned in positionSpanEnd.  If the debugger
+    // is not capable of this, the line and column values in the span end (if requested) should be set to zero.
+    //
+    // The line text can optionally be passed back by debug engines which support it.  There is no requirement that a script
+    // debugger be able to return more than line and column position.  If this is not supported, nullptr can be returned.
+    //
+    STDMETHOD(GetCurrentPosition)(
+        THIS_
+        _Out_ ScriptDebugPosition *currentPosition,
+        _Out_opt_ ScriptDebugPosition *positionSpanEnd,
+        _Out_opt_ BSTR *lineText
+        ) PURE;
+
+    // GetStack():
+    //
+    // Gets the current stack at the break position.  This may **ONLY** be called when the script is broken into the debugger.
+    //
+    STDMETHOD(GetStack)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptDebugStack **stack
+        ) PURE;
+
+    // SetBreakpoint():
+    //
+    // Sets a breakpoint within the script.
+    //
+    STDMETHOD(SetBreakpoint)(
+        THIS_
+        _In_ ULONG linePosition,
+        _In_ ULONG columnPosition,
+        _COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint
+        ) PURE;
+
+    // FindBreakpointById():
+    //
+    // Finds a breakpoint by its identifier.
+    //
+    STDMETHOD(FindBreakpointById)(
+        THIS_
+        _In_ ULONG64 breakpointId,
+        _COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint
+        ) PURE;
+
+    // EnumerateBreakpoints():
+    //
+    // Enumerates all breakpoints on the script in question.
+    //
+    STDMETHOD(EnumerateBreakpoints)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptDebugBreakpointEnumerator **breakpointEnum
+        ) PURE;
+
+    // GetEventFilter():
+    //
+    // Gets the event filter (break on event) status for a particular event.
+    //
+    STDMETHOD(GetEventFilter)(
+        THIS_
+        _In_ ScriptDebugEventFilter eventFilter,
+        _Out_ bool *isBreakEnabled
+        ) PURE;
+
+    // SetEventFilter():
+    //
+    // Sets the current event filter (break on event) status for a particular event.  Some script engines may return
+    // E_NOTIMPL for particular events to indicate that the particular debug engine does not support the particular
+    // event.
+    //
+    STDMETHOD(SetEventFilter)(
+        THIS_
+        _In_ ScriptDebugEventFilter eventFilter,
+        _In_ bool isBreakEnabled
+        ) PURE;
+
+    // StartDebugging():
+    //
+    // Called by a client which wishes to start debugging a script.  The act of starting debugging does not actively
+    // cause any execution break or stepping.  It merely makes the script debuggable and provides a set of interfaces
+    // for the client to communicate with the script debugger.
+    //
+    STDMETHOD(StartDebugging)(
+        THIS_
+        _In_ IDataModelScriptDebugClient *debugClient
+        ) PURE;
+
+    // StopDebugging():
+    //
+    // Called by a client which wishes to stop debugging a script.  This may be called from a break status or
+    // a running status of the script.  It immediately ceases all debugging activity and resets the state back to before
+    // StartDebugging was called.
+    //
+    STDMETHOD(StopDebugging)(
+        THIS_
+        _In_ IDataModelScriptDebugClient *debugClient
+        ) PURE;
+
+};
+
+// IDataModelScriptDebug2:
+//
+// An optional interface on scripts (objects which implement IDataModelScript).  If this interface is supported,
+// the script provider has a debug engine capable of some limited form of 'script debugging'.  This may include
+// stepping, setting breakpoints, inspecting data, etc...
+//
+#undef INTERFACE
+#define INTERFACE IDataModelScriptDebug2
+DECLARE_INTERFACE_(IDataModelScriptDebug2, IDataModelScriptDebug)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptDebug:
+
+    STDMETHOD_(ScriptDebugState, GetDebugState)(
+        THIS
+        ) PURE;
+
+    STDMETHOD(GetCurrentPosition)(
+        THIS_
+        _Out_ ScriptDebugPosition *currentPosition,
+        _Out_opt_ ScriptDebugPosition *positionSpanEnd,
+        _Out_opt_ BSTR *lineText
+        ) PURE;
+
+    STDMETHOD(GetStack)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptDebugStack **stack
+        ) PURE;
+
+    STDMETHOD(SetBreakpoint)(
+        THIS_
+        _In_ ULONG linePosition,
+        _In_ ULONG columnPosition,
+        _COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint
+        ) PURE;
+
+    STDMETHOD(FindBreakpointById)(
+        THIS_
+        _In_ ULONG64 breakpointId,
+        _COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint
+        ) PURE;
+
+    STDMETHOD(EnumerateBreakpoints)(
+        THIS_
+        _COM_Outptr_ IDataModelScriptDebugBreakpointEnumerator **breakpointEnum
+        ) PURE;
+
+    STDMETHOD(GetEventFilter)(
+        THIS_
+        _In_ ScriptDebugEventFilter eventFilter,
+        _Out_ bool *isBreakEnabled
+        ) PURE;
+
+    STDMETHOD(SetEventFilter)(
+        THIS_
+        _In_ ScriptDebugEventFilter eventFilter,
+        _In_ bool isBreakEnabled
+        ) PURE;
+
+    STDMETHOD(StartDebugging)(
+        THIS_
+        _In_ IDataModelScriptDebugClient *debugClient
+        ) PURE;
+
+    STDMETHOD(StopDebugging)(
+        THIS_
+        _In_ IDataModelScriptDebugClient *debugClient
+        ) PURE;
+
+    //*************************************************
+    // IDataModelScriptDebug2
+
+    // SetBreakpointAtFunction():
+    //
+    // Sets a breakpoint on the function given by the supplied name.
+    //
+    STDMETHOD(SetBreakpointAtFunction)(
+        THIS_
+        _In_ PCWSTR functionName,
+        _COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint
+        ) PURE;
+};
+
+//
+// IDebugHostModule2:
+//
+// A specialization of IDebugHostSymbol representing a module (e.g.: a DLL or executable).
+//
+#undef INTERFACE
+#define INTERFACE IDebugHostModule2
+DECLARE_INTERFACE_(IDebugHostModule2, IDebugHostModule)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostSymbol:
+
+    STDMETHOD(GetContext)(
+        THIS_
+        _COM_Outptr_ IDebugHostContext** context
+        ) PURE;
+
+    STDMETHOD(EnumerateChildren)(
+        THIS_
+        _In_ SymbolKind kind,
+        _In_opt_z_ PCWSTR name,
+        _Out_ IDebugHostSymbolEnumerator **ppEnum
+        ) PURE;
+
+    STDMETHOD(GetSymbolKind)(
+        THIS_
+        _Out_ SymbolKind *kind
+        ) PURE;
+
+    STDMETHOD(GetName)(
+        THIS_
+        _Out_ BSTR* symbolName
+        ) PURE;
+
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(GetContainingModule)(
+        THIS_
+        _Out_ IDebugHostModule **containingModule
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostModule:
+
+    STDMETHOD(GetImageName)(
+        THIS_
+        _In_ bool allowPath,
+        _Out_ BSTR* imageName
+        ) PURE;
+
+    STDMETHOD(GetBaseLocation)(
+        THIS_
+        _Out_ Location* moduleBaseLocation
+        ) PURE;
+
+    STDMETHOD(GetVersion)(
+        THIS_
+        _Out_opt_ ULONG64* fileVersion,
+        _Out_opt_ ULONG64* productVersion
+        ) PURE;
+
+    STDMETHOD(FindTypeByName)(
+        THIS_
+        _In_z_ PCWSTR typeName,
+        _Out_ IDebugHostType** type
+        ) PURE;
+
+    STDMETHOD(FindSymbolByRVA)(
+        THIS_
+        _In_ ULONG64 rva,
+        _Out_ IDebugHostSymbol** symbol
+        ) PURE;
+
+    STDMETHOD(FindSymbolByName)(
+        THIS_
+        _In_z_ PCWSTR symbolName,
+        _Out_ IDebugHostSymbol** symbol
+        ) PURE;
+
+    //*************************************************
+    // IDebugHostModule2:
+
+    // FindContainingSymbolByRVA():
+    //
+    // Finds a single symbol whose size indicates that the given relative virtual address is contained within it.  If there is not a single
+    // symbol at the supplied RVA, an error will be returned.
+    //
+    // The offset to the symbol will be returned as well.
+    //
+    STDMETHOD(FindContainingSymbolByRVA)(
+        THIS_
+        _In_ ULONG64 rva,
+        _Out_ IDebugHostSymbol** symbol,
+        _Out_ ULONG64 *offset
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IComparableConcept
+DECLARE_INTERFACE_(IComparableConcept, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IComparableConcept:
+
+    // CompareObjects():
+    //
+    // Compares this object to another (of arbitrary type).  If the comparison
+    // cannot be performed, E_NOT_SET should be returned.
+    //
+    // The return value passed in comparison result has the following meaning:
+    //
+    //    < 0 : contextObject < otherObject
+    //      0 : contextObject == otherObject
+    //    > 0 : contextObject > otherObject
+    //
+    STDMETHOD(CompareObjects)(
+        THIS_
+        _In_ IModelObject *contextObject,
+        _In_ IModelObject *otherObject,
+        _Out_ int *comparisonResult
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IEquatableConcept
+DECLARE_INTERFACE_(IEquatableConcept, IUnknown)
+{
+    //*************************************************
+    // IUnknown:
+
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID iid,
+        _COM_Outptr_ PVOID* iface
+        ) PURE;
+
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    //*************************************************
+    // IEquatableConcept:
+
+    // AreObjectsEqual():
+    //
+    // Compares this object to another (of arbitrary type) for equality.  If
+    // the comparison cannot be performed, E_NOT_SET should be returned.
+    //
+    STDMETHOD(AreObjectsEqual)(
+        THIS_
+        _In_ IModelObject *contextObject,
+        _In_ IModelObject *otherObject,
+        _Out_ bool *isEqual
+        ) PURE;
+};
+
+//*************************************************
+// Public APIs:
+
+//
+// CreateDataModelManager():
+//
+// The initial call a host performs to create and initialize the data model.
+//
+STDAPI CreateDataModelManager(
+    _In_ IDebugHost* debugHost,
+    _COM_Outptr_ IDataModelManager** manager
+    );
+
+//*************************************************
+// C++ Specific API Helpers
+
+#if defined(__cplusplus)
+}; // extern "C"
+
+namespace Debugger
+{
+namespace DataModel
+{
+
+//
+// ConvertException():
+//
+// Trap and convert all exceptions coming out of a functor to an appropriate HRESULT
+//
+template<typename FN>
+HRESULT ConvertException(const FN& fn)
+{
+    HRESULT hr;
+    try
+    {
+        hr = fn();
+    }
+    catch(const std::bad_alloc&)
+    {
+        hr = E_OUTOFMEMORY;
+    }
+    catch(...)
+    {
+        hr = E_FAIL;
+    }
+
+    return hr;
+}
+
+#ifdef _WRL_CLIENT_H_
+
+//
+// BindProperty:
+//
+// A binder which converts two instance methods on a class to a read/write property accessor.  The class must be IUnknown derived.
+// The returned binder will hold reference on the class object.
+//
+// Usage: BindProperty(this, &MyClass::GetMyProperty, &MyClass::SetMyProperty)
+//
+template<typename T>
+Microsoft::WRL::ComPtr<IModelPropertyAccessor>
+BindProperty(
+    T* classObject,
+    HRESULT (T::* getMethod)(PCWSTR key, IModelObject* contextObject, IModelObject** value),
+    HRESULT (T::* setMethod)(PCWSTR key, IModelObject* contextObject, IModelObject** value)
+    )
+{
+    //
+    // PropertyAccessor:
+    //
+
+    struct PropertyAccessor : Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::ClassicCom>, IModelPropertyAccessor>
+    {
+        PropertyAccessor(
+            T* classObject,
+            HRESULT(T::* getMethod)(PCWSTR, IModelObject*, IModelObject**),
+            HRESULT(T::* setMethod)(PCWSTR, IModelObject*, IModelObject**)
+            ) :
+            _classObject(classObject),
+            _getMethod(getMethod),
+            _setMethod(setMethod)
+        {
+        }
+
+        //*************************************************
+        // IModelPropertyAccessor:
+
+        STDMETHOD(GetValue)(
+            _In_ PCWSTR key,
+            _In_opt_ IModelObject* contextObject,
+            _COM_Outptr_opt_ IModelObject** value
+            )
+        {
+            return ConvertException( [&](){
+                return (_classObject->*_getMethod)(key, contextObject, value);
+            });
+        }
+
+        STDMETHOD(SetValue)(
+            _In_ PCWSTR key,
+            _In_opt_ IModelObject* contextObject,
+            _In_ IModelObject* value
+            )
+        {
+            return ConvertException( [&](){
+                if (_setMethod != nullptr)
+                {
+                    return (_classObject->*_setMethod)(key, contextObject, value);
+                }
+
+                //
+                // It's a read-only property.
+                //
+                return E_NOTIMPL;
+            });
+        }
+
+        Microsoft::WRL::ComPtr<T> _classObject;
+        HRESULT(T::* _getMethod)(PCWSTR, IModelObject*, IModelObject**);
+        HRESULT(T::* _setMethod)(PCWSTR, IModelObject*, IModelObject**);
+
+    };
+
+    Microsoft::WRL::ComPtr<PropertyAccessor> spPropertyAccessor = Microsoft::WRL::Make<PropertyAccessor>(classObject, getMethod, setMethod);
+    return spPropertyAccessor.Detach();
+}
+
+//
+// BindProperty:
+//
+// A binder which converts two lambdas to a read/write property accessor.  The lambdas must hold reference on outer objects they
+// reference through a by value capture.
+//
+// Usage: BindProperty(get_lambda, set_lambda)
+//
+template<typename TGet, typename TSet>
+Microsoft::WRL::ComPtr<IModelPropertyAccessor>
+BindProperty(
+    const TGet& getFunctor,
+    const TSet& setFunctor
+    )
+{
+    //
+    // PropertyAccessor:
+    //
+
+    struct PropertyAccessor : Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::ClassicCom>, IModelPropertyAccessor>
+    {
+        PropertyAccessor(
+            const TGet& getFunctor,
+            const TSet& setFunctor
+            ) :
+            _getFunctor(getFunctor),
+            _setFunctor(setFunctor)
+        {
+        }
+
+        //*************************************************
+        // IModelPropertyAccessor:
+
+        STDMETHOD(GetValue)(
+            _In_ PCWSTR key,
+            _In_opt_ IModelObject* contextObject,
+            _COM_Outptr_opt_ IModelObject** value
+            )
+        {
+            return ConvertException( [&](){
+                return _getFunctor(key, contextObject, value);
+            });
+        }
+
+        STDMETHOD(SetValue)(
+            _In_ PCWSTR key,
+            _In_opt_ IModelObject* contextObject,
+            _In_ IModelObject* value
+            )
+        {
+            return ConvertException( [&](){
+                return _setFunctor(key, contextObject, value);
+            });
+        }
+
+        TGet _getFunctor;
+        TSet _setFunctor;
+    };
+
+    Microsoft::WRL::ComPtr<PropertyAccessor> spPropertyAccessor = Microsoft::WRL::Make<PropertyAccessor>(getFunctor, setFunctor);
+    return spPropertyAccessor;
+}
+
+//
+// BindReadOnlyProperty:
+//
+// A binder which converts one instance method on a class to a read-only property accessor.  The class must be IUnknown derived.
+// The returned binder will hold reference on the class object.
+//
+template<typename T>
+Microsoft::WRL::ComPtr<IModelPropertyAccessor>
+BindReadOnlyProperty(
+    T* classObject,
+    HRESULT (T::* getMethod)(PCWSTR key, IModelObject* contextObject, IModelObject** value)
+    )
+{
+    return BindProperty<T>(classObject, getMethod, nullptr);
+}
+
+//
+// BindReadOnlyProperty:
+//
+// A binder which converts one lambda to a read-only property accessor.  The lambda must hold reference on outer objects through
+// a by value capture.
+//
+// Usage: BindProperty(get_lambda)
+//
+template<typename TGet>
+Microsoft::WRL::ComPtr<IModelPropertyAccessor>
+BindReadOnlyProperty(
+    const TGet& getFunctor
+    )
+{
+    //
+    // PropertyAccessor:
+    //
+
+    struct PropertyAccessor : Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::ClassicCom>, IModelPropertyAccessor>
+    {
+        PropertyAccessor(
+            const TGet& getFunctor
+            ) :
+            _getFunctor(getFunctor)
+        {
+        }
+
+        //*************************************************
+        // IModelPropertyAccessor:
+
+        STDMETHOD(GetValue)(
+            _In_ PCWSTR key,
+            _In_opt_ IModelObject* contextObject,
+            _COM_Outptr_opt_ IModelObject** value
+            )
+        {
+            return ConvertException( [&](){
+                return _getFunctor(key, contextObject, value);
+            });
+        }
+
+        STDMETHOD(SetValue)(
+            _In_ PCWSTR /*key*/,
+            _In_opt_ IModelObject* /*contextObject*/,
+            _In_ IModelObject* /*value*/
+            )
+        {
+            return E_NOTIMPL;
+        }
+
+        TGet _getFunctor;
+    };
+
+    Microsoft::WRL::ComPtr<PropertyAccessor> spPropertyAccessor = Microsoft::WRL::Make<PropertyAccessor>(getFunctor);
+    return spPropertyAccessor;
+}
+
+#endif // _WRL_CLIENT_H_
+
+} // namespace: DataModel
+
+} // namespace: Debugger
+
+#endif // __cplusplus
+
+#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PKG_WER) */
+#pragma endregion
+
+#endif // __DBGMODEL_H__
+
diff --git a/src/SOS/inc/dbgeng/dbgeng.h b/src/SOS/inc/dbgeng/dbgeng.h
new file mode 100644 (file)
index 0000000..ef98001
--- /dev/null
@@ -0,0 +1,25589 @@
+//----------------------------------------------------------------------------
+//
+// Debugger engine interfaces.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+//----------------------------------------------------------------------------
+
+#ifndef __DBGENG_H__
+#define __DBGENG_H__
+
+#include <winapifamily.h>
+
+#pragma region Desktop Family or WER Package
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PKG_WER)
+
+#include <stdarg.h>
+#include <objbase.h>
+
+#ifndef _WDBGEXTS_
+typedef struct _WINDBG_EXTENSION_APIS32* PWINDBG_EXTENSION_APIS32;
+typedef struct _WINDBG_EXTENSION_APIS64* PWINDBG_EXTENSION_APIS64;
+#endif
+
+#ifndef _CRASHLIB_
+typedef struct _MEMORY_BASIC_INFORMATION64* PMEMORY_BASIC_INFORMATION64;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//----------------------------------------------------------------------------
+//
+// Special exception code extensions could throw
+//
+//----------------------------------------------------------------------------
+#define ERROR_DBG_CANCELLED 0xC00004C7 // 0xC0000000 + ERROR_CANCELLED
+#define ERROR_DBG_TIMEOUT   0xC00005B4 // 0xC0000000 + ERROR_TIMEOUT
+
+//----------------------------------------------------------------------------
+//
+// GUIDs and interface forward declarations.
+//
+//----------------------------------------------------------------------------
+
+/* f2df5f53-071f-47bd-9de6-5734c3fed689 */
+DEFINE_GUID(IID_IDebugAdvanced, 0xf2df5f53, 0x071f, 0x47bd,
+            0x9d, 0xe6, 0x57, 0x34, 0xc3, 0xfe, 0xd6, 0x89);
+/* 716d14c9-119b-4ba5-af1f-0890e672416a */
+DEFINE_GUID(IID_IDebugAdvanced2, 0x716d14c9, 0x119b, 0x4ba5,
+            0xaf, 0x1f, 0x08, 0x90, 0xe6, 0x72, 0x41, 0x6a);
+/* cba4abb4-84c4-444d-87ca-a04e13286739 */
+DEFINE_GUID(IID_IDebugAdvanced3, 0xcba4abb4, 0x84c4, 0x444d,
+            0x87, 0xca, 0xa0, 0x4e, 0x13, 0x28, 0x67, 0x39);
+/* d1069067-2a65-4bf0-ae97-76184b67856b */
+DEFINE_GUID(IID_IDebugAdvanced4, 0xd1069067, 0x2a65, 0x4bf0,
+            0xae, 0x97, 0x76, 0x18, 0x4b, 0x67, 0x85, 0x6b);
+/* 5bd9d474-5975-423a-b88b-65a8e7110e65 */
+DEFINE_GUID(IID_IDebugBreakpoint, 0x5bd9d474, 0x5975, 0x423a,
+            0xb8, 0x8b, 0x65, 0xa8, 0xe7, 0x11, 0x0e, 0x65);
+/* 1b278d20-79f2-426e-a3f9-c1ddf375d48e */
+DEFINE_GUID(IID_IDebugBreakpoint2, 0x1b278d20, 0x79f2, 0x426e,
+            0xa3, 0xf9, 0xc1, 0xdd, 0xf3, 0x75, 0xd4, 0x8e);
+/* 38f5c249-b448-43bb-9835-579d4ec02249 */
+DEFINE_GUID(IID_IDebugBreakpoint3, 0x38f5c249, 0xb448, 0x43bb, 
+            0x98, 0x35, 0x57, 0x9d, 0x4e, 0xc0, 0x22, 0x49);
+/* 27fe5639-8407-4f47-8364-ee118fb08ac8 */
+DEFINE_GUID(IID_IDebugClient, 0x27fe5639, 0x8407, 0x4f47,
+            0x83, 0x64, 0xee, 0x11, 0x8f, 0xb0, 0x8a, 0xc8);
+/* edbed635-372e-4dab-bbfe-ed0d2f63be81 */
+DEFINE_GUID(IID_IDebugClient2, 0xedbed635, 0x372e, 0x4dab,
+        0xbb, 0xfe, 0xed, 0x0d, 0x2f, 0x63, 0xbe, 0x81);
+/* dd492d7f-71b8-4ad6-a8dc-1c887479ff91 */
+DEFINE_GUID(IID_IDebugClient3, 0xdd492d7f, 0x71b8, 0x4ad6,
+            0xa8, 0xdc, 0x1c, 0x88, 0x74, 0x79, 0xff, 0x91);
+/* ca83c3de-5089-4cf8-93c8-d892387f2a5e */
+DEFINE_GUID(IID_IDebugClient4, 0xca83c3de, 0x5089, 0x4cf8,
+            0x93, 0xc8, 0xd8, 0x92, 0x38, 0x7f, 0x2a, 0x5e);
+/* e3acb9d7-7ec2-4f0c-a0da-e81e0cbbe628 */
+DEFINE_GUID(IID_IDebugClient5, 0xe3acb9d7, 0x7ec2, 0x4f0c,
+            0xa0, 0xda, 0xe8, 0x1e, 0x0c, 0xbb, 0xe6, 0x28);
+/* fd28b4c5-c498-4686-a28e-62cad2154eb3 */
+DEFINE_GUID(IID_IDebugClient6, 0xfd28b4c5, 0xc498, 0x4686,
+            0xa2, 0x8e, 0x62, 0xca, 0xd2, 0x15, 0x4e, 0xb3);
+/* 13586be3-542e-481e-b1f2-8497ba74f9a9 */
+DEFINE_GUID(IID_IDebugClient7, 0x13586be3, 0x542e, 0x481e,
+            0xb1, 0xf2, 0x84, 0x97, 0xba, 0x74, 0xf9, 0xa9);
+/* a02b66c4-aea3-4234-a9f7-fe4c383d4e29 */
+DEFINE_GUID(IID_IDebugPlmClient, 0xa02b66c4, 0xaea3, 0x4234,
+            0xa9, 0xf7, 0xfe, 0x4c, 0x38, 0x3d, 0x4e, 0x29);
+/* 597c980d-e7bd-4309-962c-9d9b69a7372c */
+DEFINE_GUID(IID_IDebugPlmClient2, 0x597c980d, 0xe7bd, 0x4309,
+            0x96, 0x2c, 0x9d, 0x9b, 0x69, 0xa7, 0x37, 0x2c);
+/* cdf48669-901f-4791-b868-7d2cb3a2d7fc */
+DEFINE_GUID(IID_IDebugPlmClient3, 0xcdf48669, 0x901f, 0x4791,
+            0xb8, 0x68, 0x7d, 0x2c, 0xb3, 0xa2, 0xd7, 0xfc);
+/* 7782d8f2-2b85-4059-ab88-28ceddca1c80 */
+DEFINE_GUID(IID_IDebugOutputStream, 0x7782d8f2, 0x2b85, 0x4059,
+            0xab, 0x88, 0x28, 0xce, 0xdd, 0xca, 0x1c, 0x80);
+/* 5182e668-105e-416e-ad92-24ef800424ba */
+DEFINE_GUID(IID_IDebugControl, 0x5182e668, 0x105e, 0x416e,
+            0xad, 0x92, 0x24, 0xef, 0x80, 0x04, 0x24, 0xba);
+/* d4366723-44df-4bed-8c7e-4c05424f4588 */
+DEFINE_GUID(IID_IDebugControl2, 0xd4366723, 0x44df, 0x4bed,
+            0x8c, 0x7e, 0x4c, 0x05, 0x42, 0x4f, 0x45, 0x88);
+/* 7df74a86-b03f-407f-90ab-a20dadcead08 */
+DEFINE_GUID(IID_IDebugControl3, 0x7df74a86, 0xb03f, 0x407f,
+            0x90, 0xab, 0xa2, 0x0d, 0xad, 0xce, 0xad, 0x08);
+/* 94e60ce9-9b41-4b19-9fc0-6d9eb35272b3 */
+DEFINE_GUID(IID_IDebugControl4, 0x94e60ce9, 0x9b41, 0x4b19,
+            0x9f, 0xc0, 0x6d, 0x9e, 0xb3, 0x52, 0x72, 0xb3);
+/* b2ffe162-2412-429f-8d1d-5bf6dd824696 */
+DEFINE_GUID(IID_IDebugControl5, 0xb2ffe162, 0x2412, 0x429f,
+            0x8d, 0x1d, 0x5b, 0xf6, 0xdd, 0x82, 0x46, 0x96);
+/* bc0d583f-126d-43a1-9cc4-a860ab1d537b */
+DEFINE_GUID(IID_IDebugControl6, 0xbc0d583f, 0x126d, 0x43a1,
+            0x9c, 0xc4, 0xa8, 0x60, 0xab, 0x1d, 0x53, 0x7b);
+/* b86fb3b1-80d4-475b-aea3-cf06539cf63a */
+DEFINE_GUID(IID_IDebugControl7, 0xb86fb3b1, 0x80d4, 0x475b,
+            0xae, 0xa3, 0xcf, 0x06, 0x53, 0x9c, 0xf6, 0x3a);
+/* 88f7dfab-3ea7-4c3a-aefb-c4e8106173aa */
+DEFINE_GUID(IID_IDebugDataSpaces, 0x88f7dfab, 0x3ea7, 0x4c3a,
+            0xae, 0xfb, 0xc4, 0xe8, 0x10, 0x61, 0x73, 0xaa);
+/* 7a5e852f-96e9-468f-ac1b-0b3addc4a049 */
+DEFINE_GUID(IID_IDebugDataSpaces2, 0x7a5e852f, 0x96e9, 0x468f,
+            0xac, 0x1b, 0x0b, 0x3a, 0xdd, 0xc4, 0xa0, 0x49);
+/* 23f79d6c-8aaf-4f7c-a607-9995f5407e63 */
+DEFINE_GUID(IID_IDebugDataSpaces3, 0x23f79d6c, 0x8aaf, 0x4f7c,
+            0xa6, 0x07, 0x99, 0x95, 0xf5, 0x40, 0x7e, 0x63);
+/* d98ada1f-29e9-4ef5-a6c0-e53349883212 */
+DEFINE_GUID(IID_IDebugDataSpaces4, 0xd98ada1f, 0x29e9, 0x4ef5,
+            0xa6, 0xc0, 0xe5, 0x33, 0x49, 0x88, 0x32, 0x12);
+/* 337be28b-5036-4d72-b6bf-c45fbb9f2eaa */
+DEFINE_GUID(IID_IDebugEventCallbacks, 0x337be28b, 0x5036, 0x4d72,
+            0xb6, 0xbf, 0xc4, 0x5f, 0xbb, 0x9f, 0x2e, 0xaa);
+/* 0690e046-9c23-45ac-a04f-987ac29ad0d3 */
+DEFINE_GUID(IID_IDebugEventCallbacksWide, 0x0690e046, 0x9c23, 0x45ac,
+            0xa0, 0x4f, 0x98, 0x7a, 0xc2, 0x9a, 0xd0, 0xd3);
+/* 61a4905b-23f9-4247-b3c5-53d087529ab7 */
+DEFINE_GUID(IID_IDebugEventContextCallbacks, 0x61a4905b, 0x23f9, 0x4247,
+            0xb3, 0xc5, 0x53, 0xd0, 0x87, 0x52, 0x9a, 0xb7);
+/* 9f50e42c-f136-499e-9a97-73036c94ed2d */
+DEFINE_GUID(IID_IDebugInputCallbacks, 0x9f50e42c, 0xf136, 0x499e,
+            0x9a, 0x97, 0x73, 0x03, 0x6c, 0x94, 0xed, 0x2d);
+/* 4bf58045-d654-4c40-b0af-683090f356dc */
+DEFINE_GUID(IID_IDebugOutputCallbacks, 0x4bf58045, 0xd654, 0x4c40,
+            0xb0, 0xaf, 0x68, 0x30, 0x90, 0xf3, 0x56, 0xdc);
+/* 4c7fd663-c394-4e26-8ef1-34ad5ed3764c */
+DEFINE_GUID(IID_IDebugOutputCallbacksWide, 0x4c7fd663, 0xc394, 0x4e26,
+            0x8e, 0xf1, 0x34, 0xad, 0x5e, 0xd3, 0x76, 0x4c);
+/* 67721fe9-56d2-4a44-a325-2b65513ce6eb */
+DEFINE_GUID(IID_IDebugOutputCallbacks2, 0x67721fe9, 0x56d2, 0x4a44,
+            0xa3, 0x25, 0x2b, 0x65, 0x51, 0x3c, 0xe6, 0xeb);
+/* ce289126-9e84-45a7-937e-67bb18691493 */
+DEFINE_GUID(IID_IDebugRegisters, 0xce289126, 0x9e84, 0x45a7,
+            0x93, 0x7e, 0x67, 0xbb, 0x18, 0x69, 0x14, 0x93);
+/* 1656afa9-19c6-4e3a-97e7-5dc9160cf9c4 */
+DEFINE_GUID(IID_IDebugRegisters2, 0x1656afa9, 0x19c6, 0x4e3a,
+            0x97, 0xe7, 0x5d, 0xc9, 0x16, 0x0c, 0xf9, 0xc4);
+/* f2528316-0f1a-4431-aeed-11d096e1e2ab */
+DEFINE_GUID(IID_IDebugSymbolGroup, 0xf2528316, 0x0f1a, 0x4431,
+            0xae, 0xed, 0x11, 0xd0, 0x96, 0xe1, 0xe2, 0xab);
+/* 6a7ccc5f-fb5e-4dcc-b41c-6c20307bccc7 */
+DEFINE_GUID(IID_IDebugSymbolGroup2, 0x6a7ccc5f, 0xfb5e, 0x4dcc,
+            0xb4, 0x1c, 0x6c, 0x20, 0x30, 0x7b, 0xcc, 0xc7);
+/* 8c31e98c-983a-48a5-9016-6fe5d667a950 */
+DEFINE_GUID(IID_IDebugSymbols, 0x8c31e98c, 0x983a, 0x48a5,
+            0x90, 0x16, 0x6f, 0xe5, 0xd6, 0x67, 0xa9, 0x50);
+/* 3a707211-afdd-4495-ad4f-56fecdf8163f */
+DEFINE_GUID(IID_IDebugSymbols2, 0x3a707211, 0xafdd, 0x4495,
+            0xad, 0x4f, 0x56, 0xfe, 0xcd, 0xf8, 0x16, 0x3f);
+/* f02fbecc-50ac-4f36-9ad9-c975e8f32ff8 */
+DEFINE_GUID(IID_IDebugSymbols3, 0xf02fbecc, 0x50ac, 0x4f36,
+            0x9a, 0xd9, 0xc9, 0x75, 0xe8, 0xf3, 0x2f, 0xf8);
+/* e391bbd8-9d8c-4418-840b-c006592a1752 */
+DEFINE_GUID(IID_IDebugSymbols4, 0xe391bbd8, 0x9d8c, 0x4418,
+            0x84, 0x0b, 0xc0, 0x06, 0x59, 0x2a, 0x17, 0x52);
+/* c65fa83e-1e69-475e-8e0e-b5d79e9cc17e */
+DEFINE_GUID(IID_IDebugSymbols5, 0xc65fa83e, 0x1e69, 0x475e,
+            0x8e, 0x0e, 0xb5, 0xd7, 0x9e, 0x9c, 0xc1, 0x7e);
+/* 6b86fe2c-2c4f-4f0c-9da2-174311acc327 */
+DEFINE_GUID(IID_IDebugSystemObjects, 0x6b86fe2c, 0x2c4f, 0x4f0c,
+            0x9d, 0xa2, 0x17, 0x43, 0x11, 0xac, 0xc3, 0x27);
+/* 0ae9f5ff-1852-4679-b055-494bee6407ee */
+DEFINE_GUID(IID_IDebugSystemObjects2, 0x0ae9f5ff, 0x1852, 0x4679,
+            0xb0, 0x55, 0x49, 0x4b, 0xee, 0x64, 0x07, 0xee);
+/* e9676e2f-e286-4ea3-b0f9-dfe5d9fc330e */
+DEFINE_GUID(IID_IDebugSystemObjects3, 0xe9676e2f, 0xe286, 0x4ea3,
+            0xb0, 0xf9, 0xdf, 0xe5, 0xd9, 0xfc, 0x33, 0x0e);
+/* 489468e6-7d0f-4af5-87ab-25207454d553 */
+DEFINE_GUID(IID_IDebugSystemObjects4, 0x489468e6, 0x7d0f, 0x4af5,
+            0x87, 0xab, 0x25, 0x20, 0x74, 0x54, 0xd5, 0x53);
+
+typedef interface DECLSPEC_UUID("f2df5f53-071f-47bd-9de6-5734c3fed689")
+    IDebugAdvanced* PDEBUG_ADVANCED;
+typedef interface DECLSPEC_UUID("716d14c9-119b-4ba5-af1f-0890e672416a")
+    IDebugAdvanced2* PDEBUG_ADVANCED2;
+typedef interface DECLSPEC_UUID("cba4abb4-84c4-444d-87ca-a04e13286739")
+    IDebugAdvanced3* PDEBUG_ADVANCED3;
+typedef interface DECLSPEC_UUID("d1069067-2a65-4bf0-ae97-76184b67856b")
+    IDebugAdvanced4* PDEBUG_ADVANCED4;
+typedef interface DECLSPEC_UUID("5bd9d474-5975-423a-b88b-65a8e7110e65")
+    IDebugBreakpoint* PDEBUG_BREAKPOINT;
+typedef interface DECLSPEC_UUID("1b278d20-79f2-426e-a3f9-c1ddf375d48e")
+    IDebugBreakpoint2* PDEBUG_BREAKPOINT2;
+typedef interface DECLSPEC_UUID("38f5c249-b448-43bb-9835-579d4ec02249")
+    IDebugBreakpoint3* PDEBUG_BREAKPOINT3;
+typedef interface DECLSPEC_UUID("27fe5639-8407-4f47-8364-ee118fb08ac8")
+    IDebugClient* PDEBUG_CLIENT;
+typedef interface DECLSPEC_UUID("edbed635-372e-4dab-bbfe-ed0d2f63be81")
+    IDebugClient2* PDEBUG_CLIENT2;
+typedef interface DECLSPEC_UUID("dd492d7f-71b8-4ad6-a8dc-1c887479ff91")
+    IDebugClient3* PDEBUG_CLIENT3;
+typedef interface DECLSPEC_UUID("ca83c3de-5089-4cf8-93c8-d892387f2a5e")
+    IDebugClient4* PDEBUG_CLIENT4;
+typedef interface DECLSPEC_UUID("e3acb9d7-7ec2-4f0c-a0da-e81e0cbbe628")
+    IDebugClient5* PDEBUG_CLIENT5;
+typedef interface DECLSPEC_UUID("fd28b4c5-c498-4686-a28e-62cad2154eb3")
+    IDebugClient6* PDEBUG_CLIENT6;
+typedef interface DECLSPEC_UUID("13586be3-542e-481e-b1f2-8497ba74f9a9")
+    IDebugClient7* PDEBUG_CLIENT7;
+typedef interface DECLSPEC_UUID("a02b66c4-aea3-4234-a9f7-fe4c383d4e29")
+    IDebugPlmClient* PIDEBUG_PLMCLIENT;
+typedef interface DECLSPEC_UUID("597c980d-e7bd-4309-962c-9d9b69a7372c")
+    IDebugPlmClient2* PIDEBUG_PLMCLIENT2;
+typedef interface DECLSPEC_UUID("d4a5dbd1-ca02-4d90-856a-2a92bfd0f20f")
+    IDebugPlmClient3* PIDEBUG_PLMCLIENT3;
+typedef interface DECLSPEC_UUID("7782d8f2-2b85-4059-ab88-28ceddca1c80")
+    IDebugOutputStream* PDEBUG_OUTPUT_STREAM;
+typedef interface DECLSPEC_UUID("5182e668-105e-416e-ad92-24ef800424ba")
+    IDebugControl* PDEBUG_CONTROL;
+typedef interface DECLSPEC_UUID("d4366723-44df-4bed-8c7e-4c05424f4588")
+    IDebugControl2* PDEBUG_CONTROL2;
+typedef interface DECLSPEC_UUID("7df74a86-b03f-407f-90ab-a20dadcead08")
+    IDebugControl3* PDEBUG_CONTROL3;
+typedef interface DECLSPEC_UUID("94e60ce9-9b41-4b19-9fc0-6d9eb35272b3")
+    IDebugControl4* PDEBUG_CONTROL4;
+typedef interface DECLSPEC_UUID("b2ffe162-2412-429f-8d1d-5bf6dd824696")
+    IDebugControl5* PDEBUG_CONTROL5;
+typedef interface DECLSPEC_UUID("bc0d583f-126d-43a1-9cc4-a860ab1d537b")
+    IDebugControl6* PDEBUG_CONTROL6;
+typedef interface DECLSPEC_UUID("b86fb3b1-80d4-475b-aea3-cf06539cf63a")
+    IDebugControl7* PDEBUG_CONTROL7;
+
+typedef interface DECLSPEC_UUID("88f7dfab-3ea7-4c3a-aefb-c4e8106173aa")
+    IDebugDataSpaces* PDEBUG_DATA_SPACES;
+typedef interface DECLSPEC_UUID("7a5e852f-96e9-468f-ac1b-0b3addc4a049")
+    IDebugDataSpaces2* PDEBUG_DATA_SPACES2;
+typedef interface DECLSPEC_UUID("23f79d6c-8aaf-4f7c-a607-9995f5407e63")
+    IDebugDataSpaces3* PDEBUG_DATA_SPACES3;
+typedef interface DECLSPEC_UUID("d98ada1f-29e9-4ef5-a6c0-e53349883212")
+    IDebugDataSpaces4* PDEBUG_DATA_SPACES4;
+typedef interface DECLSPEC_UUID("337be28b-5036-4d72-b6bf-c45fbb9f2eaa")
+    IDebugEventCallbacks* PDEBUG_EVENT_CALLBACKS;
+typedef interface DECLSPEC_UUID("0690e046-9c23-45ac-a04f-987ac29ad0d3")
+    IDebugEventCallbacksWide* PDEBUG_EVENT_CALLBACKS_WIDE;
+typedef interface DECLSPEC_UUID("61a4905b-23f9-4247-b3c5-53d087529ab7")
+    IDebugEventContextCallbacks* PDEBUG_EVENT_CONTEXT_CALLBACKS;
+typedef interface DECLSPEC_UUID("9f50e42c-f136-499e-9a97-73036c94ed2d")
+    IDebugInputCallbacks* PDEBUG_INPUT_CALLBACKS;
+typedef interface DECLSPEC_UUID("4bf58045-d654-4c40-b0af-683090f356dc")
+    IDebugOutputCallbacks* PDEBUG_OUTPUT_CALLBACKS;
+typedef interface DECLSPEC_UUID("4c7fd663-c394-4e26-8ef1-34ad5ed3764c")
+    IDebugOutputCallbacksWide* PDEBUG_OUTPUT_CALLBACKS_WIDE;
+typedef interface DECLSPEC_UUID("67721fe9-56d2-4a44-a325-2b65513ce6eb")
+    IDebugOutputCallbacks2* PDEBUG_OUTPUT_CALLBACKS2;
+typedef interface DECLSPEC_UUID("ce289126-9e84-45a7-937e-67bb18691493")
+    IDebugRegisters* PDEBUG_REGISTERS;
+typedef interface DECLSPEC_UUID("1656afa9-19c6-4e3a-97e7-5dc9160cf9c4")
+    IDebugRegisters2* PDEBUG_REGISTERS2;
+typedef interface DECLSPEC_UUID("f2528316-0f1a-4431-aeed-11d096e1e2ab")
+    IDebugSymbolGroup* PDEBUG_SYMBOL_GROUP;
+typedef interface DECLSPEC_UUID("6a7ccc5f-fb5e-4dcc-b41c-6c20307bccc7")
+    IDebugSymbolGroup2* PDEBUG_SYMBOL_GROUP2;
+typedef interface DECLSPEC_UUID("8c31e98c-983a-48a5-9016-6fe5d667a950")
+    IDebugSymbols* PDEBUG_SYMBOLS;
+typedef interface DECLSPEC_UUID("3a707211-afdd-4495-ad4f-56fecdf8163f")
+    IDebugSymbols2* PDEBUG_SYMBOLS2;
+typedef interface DECLSPEC_UUID("f02fbecc-50ac-4f36-9ad9-c975e8f32ff8")
+    IDebugSymbols3* PDEBUG_SYMBOLS3;
+typedef interface DECLSPEC_UUID("e391bbd8-9d8c-4418-840b-c006592a1752")
+    IDebugSymbols4* PDEBUG_SYMBOLS4;
+typedef interface DECLSPEC_UUID("c65fa83e-1e69-475e-8e0e-b5d79e9cc17e")
+    IDebugSymbols5* PDEBUG_SYMBOLS5;
+typedef interface DECLSPEC_UUID("6b86fe2c-2c4f-4f0c-9da2-174311acc327")
+    IDebugSystemObjects* PDEBUG_SYSTEM_OBJECTS;
+typedef interface DECLSPEC_UUID("0ae9f5ff-1852-4679-b055-494bee6407ee")
+    IDebugSystemObjects2* PDEBUG_SYSTEM_OBJECTS2;
+typedef interface DECLSPEC_UUID("e9676e2f-e286-4ea3-b0f9-dfe5d9fc330e")
+    IDebugSystemObjects3* PDEBUG_SYSTEM_OBJECTS3;
+typedef interface DECLSPEC_UUID("489468e6-7d0f-4af5-87ab-25207454d553")
+    IDebugSystemObjects4* PDEBUG_SYSTEM_OBJECTS4;
+
+//----------------------------------------------------------------------------
+//
+// Macros.
+//
+//----------------------------------------------------------------------------
+
+// Extends a 32-bit address into a 64-bit address.
+#define DEBUG_EXTEND64(Addr) ((ULONG64)(LONG64)(LONG)(Addr))
+
+//----------------------------------------------------------------------------
+//
+// Client creation functions.
+//
+//----------------------------------------------------------------------------
+
+// RemoteOptions specifies connection types and
+// their parameters.  Supported strings are:
+//    npipe:Server=<Machine>,Pipe=<Pipe name>
+//    tcp:Server=<Machine>,Port=<IP port>
+STDAPI
+DebugConnect(
+    _In_ PCSTR RemoteOptions,
+    _In_ REFIID InterfaceId,
+    _Out_ PVOID* Interface
+    );
+
+STDAPI
+DebugConnectWide(
+    _In_ PCWSTR RemoteOptions,
+    _In_ REFIID InterfaceId,
+    _Out_ PVOID* Interface
+    );
+
+STDAPI
+DebugCreate(
+    _In_ REFIID InterfaceId,
+    _Out_ PVOID* Interface
+    );
+
+STDAPI
+DebugCreateEx(
+    _In_ REFIID InterfaceId,
+    _In_ DWORD  DbgEngOptions,
+    _Out_ PVOID* Interface
+    );
+
+//----------------------------------------------------------------------------
+//
+// IDebugAdvanced.
+//
+//----------------------------------------------------------------------------
+
+typedef struct _DEBUG_OFFSET_REGION
+{
+    ULONG64 Base;
+    ULONG64 Size;
+} DEBUG_OFFSET_REGION, *PDEBUG_OFFSET_REGION;
+
+#undef INTERFACE
+#define INTERFACE IDebugAdvanced
+DECLARE_INTERFACE_(IDebugAdvanced, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugAdvanced.
+
+    // Get/SetThreadContext offer control over
+    // the full processor context for a thread.
+    // Higher-level functions, such as the
+    // IDebugRegisters interface, allow similar
+    // access in simpler and more generic ways.
+    // Get/SetThreadContext are useful when
+    // large amounts of thread context must
+    // be changed and processor-specific code
+    // is not a problem.
+    STDMETHOD(GetThreadContext)(
+        THIS_
+        _Out_writes_bytes_(ContextSize) /* align_is(16) */ PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+    STDMETHOD(SetThreadContext)(
+        THIS_
+        _In_reads_bytes_(ContextSize) /* align_is(16) */ PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+};
+
+typedef struct _DEBUG_READ_USER_MINIDUMP_STREAM
+{
+    IN ULONG StreamType;
+    IN ULONG Flags;
+    IN ULONG64 Offset;
+    OUT PVOID Buffer;
+    IN ULONG BufferSize;
+    OUT ULONG BufferUsed;
+} DEBUG_READ_USER_MINIDUMP_STREAM, *PDEBUG_READ_USER_MINIDUMP_STREAM;
+
+#define DEBUG_GET_TEXT_COMPLETIONS_NO_DOT_COMMANDS       0x00000001
+#define DEBUG_GET_TEXT_COMPLETIONS_NO_EXTENSION_COMMANDS 0x00000002
+#define DEBUG_GET_TEXT_COMPLETIONS_NO_SYMBOLS            0x00000004
+
+typedef struct _DEBUG_GET_TEXT_COMPLETIONS_IN
+{
+    ULONG Flags;
+    ULONG MatchCountLimit;
+    ULONG64 Reserved[3];
+    // Input text string follows.
+} DEBUG_GET_TEXT_COMPLETIONS_IN, *PDEBUG_GET_TEXT_COMPLETIONS_IN;
+
+#define DEBUG_GET_TEXT_COMPLETIONS_IS_DOT_COMMAND       0x00000001
+#define DEBUG_GET_TEXT_COMPLETIONS_IS_EXTENSION_COMMAND 0x00000002
+#define DEBUG_GET_TEXT_COMPLETIONS_IS_SYMBOL            0x00000004
+
+typedef struct _DEBUG_GET_TEXT_COMPLETIONS_OUT
+{
+    ULONG Flags;
+    // Char index in input string where completions start.
+    ULONG ReplaceIndex;
+    ULONG MatchCount;
+    ULONG Reserved1;
+    ULONG64 Reserved2[2];
+    // Completions follow.
+    // Completion data is zero-terminated strings ended
+    // by a final zero double-terminator.
+} DEBUG_GET_TEXT_COMPLETIONS_OUT, *PDEBUG_GET_TEXT_COMPLETIONS_OUT;
+
+typedef struct _DEBUG_CACHED_SYMBOL_INFO
+{
+    ULONG64 ModBase;
+    ULONG64 Arg1;
+    ULONG64 Arg2;
+    ULONG Id;
+    ULONG Arg3;
+} DEBUG_CACHED_SYMBOL_INFO, *PDEBUG_CACHED_SYMBOL_INFO;
+
+typedef struct _PROCESS_NAME_ENTRY
+{
+    ULONG ProcessId;
+    ULONG NameOffset;  // offset for the process name string.
+    ULONG NameSize;    // ProcessName will always be NULL terminated, NameSize is for struct align and safeguard.
+    ULONG NextEntry;   // offset for next entry, 0 if the last.
+} PROCESS_NAME_ENTRY, *PPROCESS_NAME_ENTRY;
+
+//
+// Request requests.
+//
+
+// InBuffer - Unused.
+// OutBuffer - Unused.
+#define DEBUG_REQUEST_SOURCE_PATH_HAS_SOURCE_SERVER 0
+
+// InBuffer - Unused.
+// OutBuffer - Machine-specific CONTEXT.
+#define DEBUG_REQUEST_TARGET_EXCEPTION_CONTEXT 1
+
+// InBuffer - Unused.
+// OutBuffer - ULONG system ID of thread.
+#define DEBUG_REQUEST_TARGET_EXCEPTION_THREAD 2
+
+// InBuffer - Unused.
+// OutBuffer - EXCEPTION_RECORD64.
+#define DEBUG_REQUEST_TARGET_EXCEPTION_RECORD 3
+
+// InBuffer - Unused.
+// OutBuffer - DEBUG_CREATE_PROCESS_OPTIONS.
+#define DEBUG_REQUEST_GET_ADDITIONAL_CREATE_OPTIONS 4
+
+// InBuffer - DEBUG_CREATE_PROCESS_OPTIONS.
+// OutBuffer - Unused.
+#define DEBUG_REQUEST_SET_ADDITIONAL_CREATE_OPTIONS 5
+
+// InBuffer - Unused.
+// OutBuffer - ULONG[2] major/minor.
+#define DEBUG_REQUEST_GET_WIN32_MAJOR_MINOR_VERSIONS 6
+
+// InBuffer - DEBUG_READ_USER_MINIDUMP_STREAM.
+// OutBuffer - Unused.
+#define DEBUG_REQUEST_READ_USER_MINIDUMP_STREAM 7
+
+// InBuffer - Unused.
+// OutBuffer - Unused.
+#define DEBUG_REQUEST_TARGET_CAN_DETACH 8
+
+// InBuffer - PTSTR.
+// OutBuffer - Unused.
+#define DEBUG_REQUEST_SET_LOCAL_IMPLICIT_COMMAND_LINE 9
+
+// InBuffer - Unused.
+// OutBuffer - Event code stream offset.
+#define DEBUG_REQUEST_GET_CAPTURED_EVENT_CODE_OFFSET 10
+
+// InBuffer - Unused.
+// OutBuffer - Event code stream information.
+#define DEBUG_REQUEST_READ_CAPTURED_EVENT_CODE_STREAM 11
+
+// InBuffer - Input data block.
+// OutBuffer - Processed data block.
+#define DEBUG_REQUEST_EXT_TYPED_DATA_ANSI 12
+
+// InBuffer - Unused.
+// OutBuffer - Returned path.
+#define DEBUG_REQUEST_GET_EXTENSION_SEARCH_PATH_WIDE 13
+
+// InBuffer - DEBUG_GET_TEXT_COMPLETIONS_IN.
+// OutBuffer - DEBUG_GET_TEXT_COMPLETIONS_OUT.
+#define DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE 14
+
+// InBuffer - ULONG64 cookie.
+// OutBuffer - DEBUG_CACHED_SYMBOL_INFO.
+#define DEBUG_REQUEST_GET_CACHED_SYMBOL_INFO 15
+
+// InBuffer - DEBUG_CACHED_SYMBOL_INFO.
+// OutBuffer - ULONG64 cookie.
+#define DEBUG_REQUEST_ADD_CACHED_SYMBOL_INFO 16
+
+// InBuffer - ULONG64 cookie.
+// OutBuffer - Unused.
+#define DEBUG_REQUEST_REMOVE_CACHED_SYMBOL_INFO 17
+
+// InBuffer - DEBUG_GET_TEXT_COMPLETIONS_IN.
+// OutBuffer - DEBUG_GET_TEXT_COMPLETIONS_OUT.
+#define DEBUG_REQUEST_GET_TEXT_COMPLETIONS_ANSI 18
+
+// InBuffer - Unused.
+// OutBuffer - Unused.
+#define DEBUG_REQUEST_CURRENT_OUTPUT_CALLBACKS_ARE_DML_AWARE 19
+
+// InBuffer - ULONG64 offset.
+// OutBuffer - Unwind information.
+#define DEBUG_REQUEST_GET_OFFSET_UNWIND_INFORMATION 20
+
+// InBuffer - Unused
+// OutBuffer - returned DUMP_HEADER32/DUMP_HEADER64 structure.
+#define DEBUG_REQUEST_GET_DUMP_HEADER 21
+
+// InBuffer - DUMP_HEADER32/DUMP_HEADER64 structure.
+// OutBuffer - Unused
+#define DEBUG_REQUEST_SET_DUMP_HEADER 22
+
+// InBuffer - Midori specific
+// OutBuffer - Midori specific
+#define DEBUG_REQUEST_MIDORI 23
+
+// InBuffer - Unused
+// OutBuffer - PROCESS_NAME_ENTRY blocks
+#define DEBUG_REQUEST_PROCESS_DESCRIPTORS 24
+
+// InBuffer - Unused
+// OutBuffer - MINIDUMP_MISC_INFO_N blocks
+#define DEBUG_REQUEST_MISC_INFORMATION 25
+
+// InBuffer - Unused
+// OutBuffer - ULONG64 as TokenHandle value
+#define DEBUG_REQUEST_OPEN_PROCESS_TOKEN 26
+
+// InBuffer - Unused
+// OutBuffer - ULONG64 as TokenHandle value
+#define DEBUG_REQUEST_OPEN_THREAD_TOKEN 27
+
+// InBuffer -  ULONG64 as TokenHandle being duplicated
+// OutBuffer - ULONG64 as new duplicated TokenHandle
+#define DEBUG_REQUEST_DUPLICATE_TOKEN 28
+
+// InBuffer - a ULONG64 as TokenHandle and a ULONG as NtQueryInformationToken() request code
+// OutBuffer - NtQueryInformationToken() return
+#define DEBUG_REQUEST_QUERY_INFO_TOKEN 29
+
+// InBuffer - ULONG64 as TokenHandle
+// OutBuffer - Unused
+#define DEBUG_REQUEST_CLOSE_TOKEN 30
+
+// InBuffer - ULONG64 for process server identification and ULONG as PID
+// OutBuffer - Unused
+#define DEBUG_REQUEST_WOW_PROCESS 31
+
+// InBuffer - ULONG64 for process server identification and PWSTR as module path
+// OutBuffer - Unused
+#define DEBUG_REQUEST_WOW_MODULE 32
+
+// InBuffer - Unused
+// OutBuffer - Unused
+// return - S_OK if non-invasive user-mode attach, S_FALSE if not (but still live user-mode), E_FAIL otherwise.
+#define DEBUG_LIVE_USER_NON_INVASIVE 33
+
+// InBuffer - TID
+// OutBuffer - Unused
+// return - ResumeThreads() return.
+#define DEBUG_REQUEST_RESUME_THREAD 34
+
+// InBuffer - LONG32 - 0:query current state; >0:enable inline queries; <0: disable inline queries
+// OutBuffer - Unused
+// return - S_OK: inline queries are enabled; S_FALSE: inline queries are disabled; others: errors.
+#define DEBUG_REQUEST_INLINE_QUERY 35
+
+// InBuffer - Unused
+// OutBuffer - Unused
+// return - S_OK.
+#define DEBUG_REQUEST_TL_INSTRUMENTATION_AWARE 36
+
+// InBuffer - Unused
+// OutBuffer - ULONG for version number supported
+// return - S_OK.
+#define DEBUG_REQUEST_GET_INSTRUMENTATION_VERSION 37
+
+// InBuffer - ULONG for module index
+// OutBuffer - ULONG for architecture
+// return - S_OK
+#define DEBUG_REQUEST_GET_MODULE_ARCHITECTURE 38
+
+//
+// GetSourceFileInformation requests.
+//
+
+// Arg64 - Module base.
+// Arg32 - Unused.
+#define DEBUG_SRCFILE_SYMBOL_TOKEN 0
+
+// Arg64 - Module base.
+// Arg32 - Unused.
+#define DEBUG_SRCFILE_SYMBOL_TOKEN_SOURCE_COMMAND_WIDE 1
+
+// Arg64 - Module base.
+// Arg32 - Unused
+#define DEBUG_SRCFILE_SYMBOL_CHECKSUMINFO 2
+
+//
+// GetSymbolInformation requests.
+//
+
+// Arg64 - Unused.
+// Arg32 - Breakpoint ID.
+// Buffer - ULONG line number.
+// String - File name.
+#define DEBUG_SYMINFO_BREAKPOINT_SOURCE_LINE 0
+
+// Arg64 - Module base.
+// Arg32 - Unused.
+// Buffer - IMAGEHLP_MODULEW64.
+// String - Unused.
+#define DEBUG_SYMINFO_IMAGEHLP_MODULEW64 1
+
+// Arg64 - Offset.
+// Arg32 - Symbol tag.
+// Buffer - Unicode symbol name strings.  Could have multiple strings.
+// String - Unused, strings are returned in Buffer as there
+//          may be more than one.
+#define DEBUG_SYMINFO_GET_SYMBOL_NAME_BY_OFFSET_AND_TAG_WIDE 2
+
+// Arg64 - Module base.
+// Arg32 - Symbol tag.
+// Buffer - Array of symbol addresses.
+// String - Concatenated symbol strings.  Individual symbol
+//          strings are zero-terminated and the final string in
+//          a symbol is double-zero-terminated.
+#define DEBUG_SYMINFO_GET_MODULE_SYMBOL_NAMES_AND_OFFSETS 3
+
+//
+// GetSystemObjectInformation requests.
+//
+
+// Arg64 - Unused.
+// Arg32 - Debugger thread ID.
+// Buffer - DEBUG_THREAD_BASIC_INFORMATION.
+#define DEBUG_SYSOBJINFO_THREAD_BASIC_INFORMATION 0
+
+// Arg64 - Unused.
+// Arg32 - Debugger thread ID.
+// Buffer - Unicode name string.
+#define DEBUG_SYSOBJINFO_THREAD_NAME_WIDE 1
+
+// Arg64 - Unused.
+// Arg32 - Unused.
+// Buffer - ULONG cookie value.
+#define DEBUG_SYSOBJINFO_CURRENT_PROCESS_COOKIE 2
+
+#define DEBUG_TBINFO_EXIT_STATUS    0x00000001
+#define DEBUG_TBINFO_PRIORITY_CLASS 0x00000002
+#define DEBUG_TBINFO_PRIORITY       0x00000004
+#define DEBUG_TBINFO_TIMES          0x00000008
+#define DEBUG_TBINFO_START_OFFSET   0x00000010
+#define DEBUG_TBINFO_AFFINITY       0x00000020
+#define DEBUG_TBINFO_ALL            0x0000003f
+
+typedef struct _DEBUG_THREAD_BASIC_INFORMATION
+{
+    // Valid members have a DEBUG_TBINFO bit set in Valid.
+    ULONG Valid;
+    ULONG ExitStatus;
+    ULONG PriorityClass;
+    ULONG Priority;
+    ULONG64 CreateTime;
+    ULONG64 ExitTime;
+    ULONG64 KernelTime;
+    ULONG64 UserTime;
+    ULONG64 StartOffset;
+    ULONG64 Affinity;
+} DEBUG_THREAD_BASIC_INFORMATION, *PDEBUG_THREAD_BASIC_INFORMATION;
+
+#undef INTERFACE
+#define INTERFACE IDebugAdvanced2
+DECLARE_INTERFACE_(IDebugAdvanced2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugAdvanced.
+
+    // Get/SetThreadContext offer control over
+    // the full processor context for a thread.
+    // Higher-level functions, such as the
+    // IDebugRegisters interface, allow similar
+    // access in simpler and more generic ways.
+    // Get/SetThreadContext are useful when
+    // large amounts of thread context must
+    // be changed and processor-specific code
+    // is not a problem.
+    STDMETHOD(GetThreadContext)(
+        THIS_
+        _Out_writes_bytes_(ContextSize) /* align_is(16) */ PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+    STDMETHOD(SetThreadContext)(
+        THIS_
+        _In_reads_bytes_(ContextSize) /* align_is(16) */ PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+
+    // IDebugAdvanced2.
+
+    //
+    // Generalized open-ended methods for querying
+    // and manipulation.  The open-ended nature of
+    // these methods makes it easy to add new requests,
+    // although at a cost in convenience of calling.
+    // Sufficiently common requests may have more specific,
+    // simpler methods elsewhere.
+    //
+
+    STDMETHOD(Request)(
+        THIS_
+        _In_ ULONG Request,
+        _In_reads_bytes_opt_(InBufferSize) PVOID InBuffer,
+        _In_ ULONG InBufferSize,
+        _Out_writes_bytes_opt_(OutBufferSize) PVOID OutBuffer,
+        _In_ ULONG OutBufferSize,
+        _Out_opt_ PULONG OutSize
+        ) PURE;
+
+    STDMETHOD(GetSourceFileInformation)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ PSTR SourceFile,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize
+        ) PURE;
+    STDMETHOD(FindSourceFileAndToken)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ ULONG64 ModAddr,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _In_reads_bytes_opt_(FileTokenSize) PVOID FileToken,
+        _In_ ULONG FileTokenSize,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+
+    STDMETHOD(GetSymbolInformation)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize,
+        _Out_writes_opt_(StringBufferSize) PSTR StringBuffer,
+        _In_ ULONG StringBufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+
+    STDMETHOD(GetSystemObjectInformation)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugAdvanced3
+DECLARE_INTERFACE_(IDebugAdvanced3, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugAdvanced.
+
+    // Get/SetThreadContext offer control over
+    // the full processor context for a thread.
+    // Higher-level functions, such as the
+    // IDebugRegisters interface, allow similar
+    // access in simpler and more generic ways.
+    // Get/SetThreadContext are useful when
+    // large amounts of thread context must
+    // be changed and processor-specific code
+    // is not a problem.
+    STDMETHOD(GetThreadContext)(
+        THIS_
+        _Out_writes_bytes_(ContextSize) /* align_is(16) */ PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+    STDMETHOD(SetThreadContext)(
+        THIS_
+        _In_reads_bytes_(ContextSize) /* align_is(16) */ PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+
+    // IDebugAdvanced2.
+
+    //
+    // Generalized open-ended methods for querying
+    // and manipulation.  The open-ended nature of
+    // these methods makes it easy to add new requests,
+    // although at a cost in convenience of calling.
+    // Sufficiently common requests may have more specific,
+    // simpler methods elsewhere.
+    //
+
+    STDMETHOD(Request)(
+        THIS_
+        _In_ ULONG Request,
+        _In_reads_bytes_opt_(InBufferSize) PVOID InBuffer,
+        _In_ ULONG InBufferSize,
+        _Out_writes_bytes_opt_(OutBufferSize) PVOID OutBuffer,
+        _In_ ULONG OutBufferSize,
+        _Out_opt_ PULONG OutSize
+        ) PURE;
+
+    STDMETHOD(GetSourceFileInformation)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ PSTR SourceFile,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize
+        ) PURE;
+    STDMETHOD(FindSourceFileAndToken)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ ULONG64 ModAddr,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _In_reads_bytes_opt_(FileTokenSize) PVOID FileToken,
+        _In_ ULONG FileTokenSize,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+
+    STDMETHOD(GetSymbolInformation)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize,
+        _Out_writes_opt_(StringBufferSize) PSTR StringBuffer,
+        _In_ ULONG StringBufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+
+    STDMETHOD(GetSystemObjectInformation)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize
+        ) PURE;
+
+    // IDebugAdvanced3.
+
+    STDMETHOD(GetSourceFileInformationWide)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ PWSTR SourceFile,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize
+        ) PURE;
+    STDMETHOD(FindSourceFileAndTokenWide)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ ULONG64 ModAddr,
+        _In_ PCWSTR File,
+        _In_ ULONG Flags,
+        _In_reads_bytes_opt_(FileTokenSize) PVOID FileToken,
+        _In_ ULONG FileTokenSize,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+
+    STDMETHOD(GetSymbolInformationWide)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize,
+        _Out_writes_opt_(StringBufferSize) PWSTR StringBuffer,
+        _In_ ULONG StringBufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+};
+
+//
+//  Extended line symbol information.
+//
+typedef struct _SYMBOL_INFO_EX
+{
+    ULONG   SizeOfStruct;       // Set to sizeof(SYMBOL_INFO_EX).
+    ULONG   TypeOfInfo;         // Type of the symbol information stored (Ex. DEBUG_SYMINFO_BREAKPOINT_SOURCE_LINE)
+    ULONG64 Offset;             // Address of the line.
+    ULONG   Line;               // First line number that does not correspond to a compiler added glue lines.
+    ULONG   Displacement;       // Line displacement: Offset between given address and the first instruction of the line.
+    ULONG   Reserved[4];
+} SYMBOL_INFO_EX, *PSYMBOL_INFO_EX;
+
+#undef INTERFACE
+#define INTERFACE IDebugAdvanced4
+DECLARE_INTERFACE_(IDebugAdvanced4, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugAdvanced.
+
+    // Get/SetThreadContext offer control over
+    // the full processor context for a thread.
+    // Higher-level functions, such as the
+    // IDebugRegisters interface, allow similar
+    // access in simpler and more generic ways.
+    // Get/SetThreadContext are useful when
+    // large amounts of thread context must
+    // be changed and processor-specific code
+    // is not a problem.
+    STDMETHOD(GetThreadContext)(
+        THIS_
+        _Out_writes_bytes_(ContextSize) /* align_is(16) */ PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+    STDMETHOD(SetThreadContext)(
+        THIS_
+        _In_reads_bytes_(ContextSize) /* align_is(16) */ PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+
+    // IDebugAdvanced2.
+
+    //
+    // Generalized open-ended methods for querying
+    // and manipulation.  The open-ended nature of
+    // these methods makes it easy to add new requests,
+    // although at a cost in convenience of calling.
+    // Sufficiently common requests may have more specific,
+    // simpler methods elsewhere.
+    //
+
+    STDMETHOD(Request)(
+        THIS_
+        _In_ ULONG Request,
+        _In_reads_bytes_opt_(InBufferSize) PVOID InBuffer,
+        _In_ ULONG InBufferSize,
+        _Out_writes_bytes_opt_(OutBufferSize) PVOID OutBuffer,
+        _In_ ULONG OutBufferSize,
+        _Out_opt_ PULONG OutSize
+        ) PURE;
+
+    STDMETHOD(GetSourceFileInformation)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ PSTR SourceFile,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize
+        ) PURE;
+    STDMETHOD(FindSourceFileAndToken)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ ULONG64 ModAddr,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _In_reads_bytes_opt_(FileTokenSize) PVOID FileToken,
+        _In_ ULONG FileTokenSize,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+
+    STDMETHOD(GetSymbolInformation)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize,
+        _Out_writes_opt_(StringBufferSize) PSTR StringBuffer,
+        _In_ ULONG StringBufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+
+    STDMETHOD(GetSystemObjectInformation)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize
+        ) PURE;
+
+    // IDebugAdvanced3.
+
+    STDMETHOD(GetSourceFileInformationWide)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ PWSTR SourceFile,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize
+        ) PURE;
+    STDMETHOD(FindSourceFileAndTokenWide)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ ULONG64 ModAddr,
+        _In_ PCWSTR File,
+        _In_ ULONG Flags,
+        _In_reads_bytes_opt_(FileTokenSize) PVOID FileToken,
+        _In_ ULONG FileTokenSize,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+
+    STDMETHOD(GetSymbolInformationWide)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize,
+        _Out_writes_opt_(StringBufferSize) PWSTR StringBuffer,
+        _In_ ULONG StringBufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+
+    // IDebugAdvanced4.
+
+    STDMETHOD(GetSymbolInformationWideEx)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG64 Arg64,
+        _In_ ULONG Arg32,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize,
+        _Out_writes_opt_(StringBufferSize) PWSTR StringBuffer,
+        _In_ ULONG StringBufferSize,
+        _Out_opt_ PULONG StringSize,
+        _Out_opt_ PSYMBOL_INFO_EX pInfoEx
+        ) PURE;
+
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugBreakpoint.
+//
+//----------------------------------------------------------------------------
+
+// Types of breakpoints.
+#define DEBUG_BREAKPOINT_CODE 0
+#define DEBUG_BREAKPOINT_DATA 1
+#define DEBUG_BREAKPOINT_TIME 2
+#define DEBUG_BREAKPOINT_INLINE 3
+
+// Breakpoint flags.
+// Go-only breakpoints are only active when
+// the engine is in unrestricted execution
+// mode.  They do not fire when the engine
+// is stepping.
+#define DEBUG_BREAKPOINT_GO_ONLY    0x00000001
+// A breakpoint is flagged as deferred as long as
+// its offset expression cannot be evaluated.
+// A deferred breakpoint is not active.
+#define DEBUG_BREAKPOINT_DEFERRED   0x00000002
+#define DEBUG_BREAKPOINT_ENABLED    0x00000004
+// The adder-only flag does not affect breakpoint
+// operation.  It is just a marker to restrict
+// output and notifications for the breakpoint to
+// the client that added the breakpoint.  Breakpoint
+// callbacks for adder-only breaks will only be delivered
+// to the adding client.  The breakpoint can not
+// be enumerated and accessed by other clients.
+#define DEBUG_BREAKPOINT_ADDER_ONLY 0x00000008
+// One-shot breakpoints automatically clear themselves
+// the first time they are hit.
+#define DEBUG_BREAKPOINT_ONE_SHOT   0x00000010
+
+// Data breakpoint access types.
+// Different architectures support different
+// sets of these bits.
+#define DEBUG_BREAK_READ    0x00000001
+#define DEBUG_BREAK_WRITE   0x00000002
+#define DEBUG_BREAK_EXECUTE 0x00000004
+#define DEBUG_BREAK_IO      0x00000008
+
+// Structure for querying breakpoint information
+// all at once.
+typedef struct _DEBUG_BREAKPOINT_PARAMETERS
+{
+    ULONG64 Offset;
+    ULONG Id;
+    ULONG BreakType;
+    ULONG ProcType;
+    ULONG Flags;
+    ULONG DataSize;
+    ULONG DataAccessType;
+    ULONG PassCount;
+    ULONG CurrentPassCount;
+    ULONG MatchThread;
+    ULONG CommandSize;
+    ULONG OffsetExpressionSize;
+} DEBUG_BREAKPOINT_PARAMETERS, *PDEBUG_BREAKPOINT_PARAMETERS;
+
+#undef INTERFACE
+#define INTERFACE IDebugBreakpoint
+DECLARE_INTERFACE_(IDebugBreakpoint, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugBreakpoint.
+
+    // Retrieves debugger engine unique ID
+    // for the breakpoint.  This ID is
+    // fixed as long as the breakpoint exists
+    // but after that may be reused.
+    STDMETHOD(GetId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    // Retrieves the type of break and
+    // processor type for the breakpoint.
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ PULONG BreakType,
+        _Out_ PULONG ProcType
+        ) PURE;
+    // Returns the client that called AddBreakpoint.
+    STDMETHOD(GetAdder)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Adder
+        ) PURE;
+
+    STDMETHOD(GetFlags)(
+        THIS_
+        _Out_ PULONG Flags
+        ) PURE;
+    // Only certain flags can be changed.  Flags
+    // are: GO_ONLY, ENABLE.
+    // Sets the given flags.
+    STDMETHOD(AddFlags)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Clears the given flags.
+    STDMETHOD(RemoveFlags)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Sets the flags.
+    STDMETHOD(SetFlags)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Controls the offset of the breakpoint.  The
+    // interpretation of the offset value depends on
+    // the type of breakpoint and its settings.  It
+    // may be a code address, a data address, an
+    // I/O port, etc.
+    STDMETHOD(GetOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(SetOffset)(
+        THIS_
+        _In_ ULONG64 Offset
+        ) PURE;
+
+    // Data breakpoint methods will fail if the
+    // target platform does not support the
+    // parameters used.
+    // These methods only function for breakpoints
+    // created as data breakpoints.
+    STDMETHOD(GetDataParameters)(
+        THIS_
+        _Out_ PULONG Size,
+        _Out_ PULONG AccessType
+        ) PURE;
+    STDMETHOD(SetDataParameters)(
+        THIS_
+        _In_ ULONG Size,
+        _In_ ULONG AccessType
+        ) PURE;
+
+    // Pass count defaults to one.
+    STDMETHOD(GetPassCount)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+    STDMETHOD(SetPassCount)(
+        THIS_
+        _In_ ULONG Count
+        ) PURE;
+    // Gets the current number of times
+    // the breakpoint has been hit since
+    // it was last triggered.
+    STDMETHOD(GetCurrentPassCount)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+
+    // If a match thread is set this breakpoint will
+    // only trigger if it occurs on the match thread.
+    // Otherwise it triggers for all threads.
+    // Thread restrictions are not currently supported
+    // in kernel mode.
+    STDMETHOD(GetMatchThreadId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(SetMatchThreadId)(
+        THIS_
+        _In_ ULONG Thread
+        ) PURE;
+
+    // The command for a breakpoint is automatically
+    // executed by the engine before the event
+    // is propagated.  If the breakpoint continues
+    // execution the event will begin with a continue
+    // status.  If the breakpoint does not continue
+    // the event will begin with a break status.
+    // This allows breakpoint commands to participate
+    // in the normal event status voting.
+    // Breakpoint commands are only executed until
+    // the first command that alters the execution
+    // status, such as g, p and t.
+    STDMETHOD(GetCommand)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetCommand)(
+        THIS_
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Offset expressions are evaluated immediately
+    // and at module load and unload events.  If the
+    // evaluation is successful the breakpoints
+    // offset is updated and the breakpoint is
+    // handled normally.  If the expression cannot
+    // be evaluated the breakpoint is deferred.
+    // Currently the only offset expression
+    // supported is a module-relative symbol
+    // of the form <Module>!<Symbol>.
+    STDMETHOD(GetOffsetExpression)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExpressionSize
+        ) PURE;
+    STDMETHOD(SetOffsetExpression)(
+        THIS_
+        _In_ PCSTR Expression
+        ) PURE;
+
+    STDMETHOD(GetParameters)(
+        THIS_
+        _Out_ PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugBreakpoint2
+DECLARE_INTERFACE_(IDebugBreakpoint2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugBreakpoint.
+
+    // Retrieves debugger engine unique ID
+    // for the breakpoint.  This ID is
+    // fixed as long as the breakpoint exists
+    // but after that may be reused.
+    STDMETHOD(GetId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    // Retrieves the type of break and
+    // processor type for the breakpoint.
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ PULONG BreakType,
+        _Out_ PULONG ProcType
+        ) PURE;
+    // Returns the client that called AddBreakpoint.
+    STDMETHOD(GetAdder)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Adder
+        ) PURE;
+
+    STDMETHOD(GetFlags)(
+        THIS_
+        _Out_ PULONG Flags
+        ) PURE;
+    // Only certain flags can be changed.  Flags
+    // are: GO_ONLY, ENABLE.
+    // Sets the given flags.
+    STDMETHOD(AddFlags)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Clears the given flags.
+    STDMETHOD(RemoveFlags)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Sets the flags.
+    STDMETHOD(SetFlags)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Controls the offset of the breakpoint.  The
+    // interpretation of the offset value depends on
+    // the type of breakpoint and its settings.  It
+    // may be a code address, a data address, an
+    // I/O port, etc.
+    STDMETHOD(GetOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(SetOffset)(
+        THIS_
+        _In_ ULONG64 Offset
+        ) PURE;
+
+    // Data breakpoint methods will fail if the
+    // target platform does not support the
+    // parameters used.
+    // These methods only function for breakpoints
+    // created as data breakpoints.
+    STDMETHOD(GetDataParameters)(
+        THIS_
+        _Out_ PULONG Size,
+        _Out_ PULONG AccessType
+        ) PURE;
+    STDMETHOD(SetDataParameters)(
+        THIS_
+        _In_ ULONG Size,
+        _In_ ULONG AccessType
+        ) PURE;
+
+    // Pass count defaults to one.
+    STDMETHOD(GetPassCount)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+    STDMETHOD(SetPassCount)(
+        THIS_
+        _In_ ULONG Count
+        ) PURE;
+    // Gets the current number of times
+    // the breakpoint has been hit since
+    // it was last triggered.
+    STDMETHOD(GetCurrentPassCount)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+
+    // If a match thread is set this breakpoint will
+    // only trigger if it occurs on the match thread.
+    // Otherwise it triggers for all threads.
+    // Thread restrictions are not currently supported
+    // in kernel mode.
+    STDMETHOD(GetMatchThreadId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(SetMatchThreadId)(
+        THIS_
+        _In_ ULONG Thread
+        ) PURE;
+
+    // The command for a breakpoint is automatically
+    // executed by the engine before the event
+    // is propagated.  If the breakpoint continues
+    // execution the event will begin with a continue
+    // status.  If the breakpoint does not continue
+    // the event will begin with a break status.
+    // This allows breakpoint commands to participate
+    // in the normal event status voting.
+    // Breakpoint commands are only executed until
+    // the first command that alters the execution
+    // status, such as g, p and t.
+    STDMETHOD(GetCommand)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetCommand)(
+        THIS_
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Offset expressions are evaluated immediately
+    // and at module load and unload events.  If the
+    // evaluation is successful the breakpoints
+    // offset is updated and the breakpoint is
+    // handled normally.  If the expression cannot
+    // be evaluated the breakpoint is deferred.
+    // Currently the only offset expression
+    // supported is a module-relative symbol
+    // of the form <Module>!<Symbol>.
+    STDMETHOD(GetOffsetExpression)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExpressionSize
+        ) PURE;
+    STDMETHOD(SetOffsetExpression)(
+        THIS_
+        _In_ PCSTR Expression
+        ) PURE;
+
+    STDMETHOD(GetParameters)(
+        THIS_
+        _Out_ PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+
+    // IDebugBreakpoint2.
+
+    STDMETHOD(GetCommandWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetCommandWide)(
+        THIS_
+        _In_ PCWSTR Command
+        ) PURE;
+
+    STDMETHOD(GetOffsetExpressionWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExpressionSize
+        ) PURE;
+    STDMETHOD(SetOffsetExpressionWide)(
+        THIS_
+        _In_ PCWSTR Expression
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugBreakpoint3
+DECLARE_INTERFACE_(IDebugBreakpoint3, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugBreakpoint.
+
+    // Retrieves debugger engine unique ID
+    // for the breakpoint.  This ID is
+    // fixed as long as the breakpoint exists
+    // but after that may be reused.
+    STDMETHOD(GetId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    // Retrieves the type of break and
+    // processor type for the breakpoint.
+    STDMETHOD(GetType)(
+        THIS_
+        _Out_ PULONG BreakType,
+        _Out_ PULONG ProcType
+        ) PURE;
+    // Returns the client that called AddBreakpoint.
+    STDMETHOD(GetAdder)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Adder
+        ) PURE;
+
+    STDMETHOD(GetFlags)(
+        THIS_
+        _Out_ PULONG Flags
+        ) PURE;
+    // Only certain flags can be changed.  Flags
+    // are: GO_ONLY, ENABLE.
+    // Sets the given flags.
+    STDMETHOD(AddFlags)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Clears the given flags.
+    STDMETHOD(RemoveFlags)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Sets the flags.
+    STDMETHOD(SetFlags)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Controls the offset of the breakpoint.  The
+    // interpretation of the offset value depends on
+    // the type of breakpoint and its settings.  It
+    // may be a code address, a data address, an
+    // I/O port, etc.
+    STDMETHOD(GetOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(SetOffset)(
+        THIS_
+        _In_ ULONG64 Offset
+        ) PURE;
+
+    // Data breakpoint methods will fail if the
+    // target platform does not support the
+    // parameters used.
+    // These methods only function for breakpoints
+    // created as data breakpoints.
+    STDMETHOD(GetDataParameters)(
+        THIS_
+        _Out_ PULONG Size,
+        _Out_ PULONG AccessType
+        ) PURE;
+    STDMETHOD(SetDataParameters)(
+        THIS_
+        _In_ ULONG Size,
+        _In_ ULONG AccessType
+        ) PURE;
+
+    // Pass count defaults to one.
+    STDMETHOD(GetPassCount)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+    STDMETHOD(SetPassCount)(
+        THIS_
+        _In_ ULONG Count
+        ) PURE;
+    // Gets the current number of times
+    // the breakpoint has been hit since
+    // it was last triggered.
+    STDMETHOD(GetCurrentPassCount)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+
+    // If a match thread is set this breakpoint will
+    // only trigger if it occurs on the match thread.
+    // Otherwise it triggers for all threads.
+    // Thread restrictions are not currently supported
+    // in kernel mode.
+    STDMETHOD(GetMatchThreadId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(SetMatchThreadId)(
+        THIS_
+        _In_ ULONG Thread
+        ) PURE;
+
+    // The command for a breakpoint is automatically
+    // executed by the engine before the event
+    // is propagated.  If the breakpoint continues
+    // execution the event will begin with a continue
+    // status.  If the breakpoint does not continue
+    // the event will begin with a break status.
+    // This allows breakpoint commands to participate
+    // in the normal event status voting.
+    // Breakpoint commands are only executed until
+    // the first command that alters the execution
+    // status, such as g, p and t.
+    STDMETHOD(GetCommand)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetCommand)(
+        THIS_
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Offset expressions are evaluated immediately
+    // and at module load and unload events.  If the
+    // evaluation is successful the breakpoints
+    // offset is updated and the breakpoint is
+    // handled normally.  If the expression cannot
+    // be evaluated the breakpoint is deferred.
+    // Currently the only offset expression
+    // supported is a module-relative symbol
+    // of the form <Module>!<Symbol>.
+    STDMETHOD(GetOffsetExpression)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExpressionSize
+        ) PURE;
+    STDMETHOD(SetOffsetExpression)(
+        THIS_
+        _In_ PCSTR Expression
+        ) PURE;
+
+    STDMETHOD(GetParameters)(
+        THIS_
+        _Out_ PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+
+    // IDebugBreakpoint2.
+
+    STDMETHOD(GetCommandWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetCommandWide)(
+        THIS_
+        _In_ PCWSTR Command
+        ) PURE;
+
+    STDMETHOD(GetOffsetExpressionWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExpressionSize
+        ) PURE;
+    STDMETHOD(SetOffsetExpressionWide)(
+        THIS_
+        _In_ PCWSTR Expression
+        ) PURE;
+        
+    // IDebugBreakpoint3.
+
+    STDMETHOD(GetGuid)(
+        THIS_
+        _Out_ LPGUID Guid
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugClient.
+//
+//----------------------------------------------------------------------------
+
+// Kernel attach flags.
+#define DEBUG_ATTACH_KERNEL_CONNECTION 0x00000000
+// Attach to the local machine.  If this flag is not set
+// a connection is made to a separate target machine using
+// the given connection options.
+#define DEBUG_ATTACH_LOCAL_KERNEL      0x00000001
+// Attach to an eXDI driver.
+#define DEBUG_ATTACH_EXDI_DRIVER       0x00000002
+// Just install client-side transpotr drivers
+#define DEBUG_ATTACH_INSTALL_DRIVER    0x00000004
+
+// GetRunningProcessSystemIdByExecutableName flags.
+// By default the match allows a tail match on
+// just the filename.  The match returns the first hit
+// even if multiple matches exist.
+#define DEBUG_GET_PROC_DEFAULT      0x00000000
+// The name must match fully.
+#define DEBUG_GET_PROC_FULL_MATCH   0x00000001
+// The match must be the only match.
+#define DEBUG_GET_PROC_ONLY_MATCH   0x00000002
+// The name is a service name instead of an executable name.
+#define DEBUG_GET_PROC_SERVICE_NAME 0x00000004
+
+// GetRunningProcessDescription flags.
+#define DEBUG_PROC_DESC_DEFAULT         0x00000000
+// Return only filenames, not full paths.
+#define DEBUG_PROC_DESC_NO_PATHS        0x00000001
+// Dont look up service names.
+#define DEBUG_PROC_DESC_NO_SERVICES     0x00000002
+// Dont look up MTS package names.
+#define DEBUG_PROC_DESC_NO_MTS_PACKAGES 0x00000004
+// Dont retrieve the command line.
+#define DEBUG_PROC_DESC_NO_COMMAND_LINE 0x00000008
+// Dont retrieve the session ID.
+#define DEBUG_PROC_DESC_NO_SESSION_ID   0x00000010
+// Dont retrieve the process's user name.
+#define DEBUG_PROC_DESC_NO_USER_NAME    0x00000020
+
+//
+// Attach flags.
+//
+
+// Call DebugActiveProcess when attaching.
+#define DEBUG_ATTACH_DEFAULT                   0x00000000
+// When attaching to a process just examine
+// the process state and suspend the threads.
+// DebugActiveProcess is not called so the process
+// is not actually being debugged.  This is useful
+// for debugging processes holding locks which
+// interfere with the operation of DebugActiveProcess
+// or in situations where it is not desirable to
+// actually set up as a debugger.
+#define DEBUG_ATTACH_NONINVASIVE               0x00000001
+// Attempt to attach to a process that was abandoned
+// when being debugged.  This is only supported in
+// some system versions.
+// This flag also allows multiple debuggers to
+// attach to the same process, which can result
+// in numerous problems unless very carefully
+// managed.
+#define DEBUG_ATTACH_EXISTING                  0x00000002
+// When attaching non-invasively, do not suspend
+// threads.  It is the callers responsibility
+// to either suspend the threads itself or be
+// aware that the attach state may not reflect
+// the current state of the process if threads
+// are still running.
+#define DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND    0x00000004
+// When doing an invasive attach do not inject
+// a break-in thread to generate the initial break-in
+// event.  This can be useful to save resources when
+// an initial break is not necessary or when injecting
+// a thread might affect the debuggee's state.  This
+// option is only supported on Windows XP and above.
+#define DEBUG_ATTACH_INVASIVE_NO_INITIAL_BREAK 0x00000008
+// When doing an invasive attach resume all threads at the
+// time of attach.  This makes it possible to attach
+// to a process created suspended and cause it to start running.
+#define DEBUG_ATTACH_INVASIVE_RESUME_PROCESS   0x00000010
+// When doing a non-invasive attach the engine must
+// recover information for all debuggee elements.  The
+// engine may not have permissions for all elements,
+// for example it may not be able to open all threads,
+// and that would ordinarily block the attach.  This
+// flag allows unusable elements to be ignored.
+#define DEBUG_ATTACH_NONINVASIVE_ALLOW_PARTIAL 0x00000020
+
+
+//
+// Process creation flags to merge with Win32 flags.
+//
+
+// On Windows XP this flag prevents the debug
+// heap from being used in the new process.
+#define DEBUG_CREATE_PROCESS_NO_DEBUG_HEAP CREATE_UNICODE_ENVIRONMENT
+// Indicates that the native NT RTL process creation
+// routines should be used instead of Win32.  This
+// is only meaningful for special processes that run
+// as NT native processes.
+#define DEBUG_CREATE_PROCESS_THROUGH_RTL   STACK_SIZE_PARAM_IS_A_RESERVATION
+
+//
+// Process creation flags specific to the debugger engine.
+//
+
+#define DEBUG_ECREATE_PROCESS_DEFAULT                   0x00000000
+#define DEBUG_ECREATE_PROCESS_INHERIT_HANDLES           0x00000001
+#define DEBUG_ECREATE_PROCESS_USE_VERIFIER_FLAGS        0x00000002
+#define DEBUG_ECREATE_PROCESS_USE_IMPLICIT_COMMAND_LINE 0x00000004
+
+typedef struct _DEBUG_CREATE_PROCESS_OPTIONS
+{
+    // Win32 create flags.
+    ULONG CreateFlags;
+    // DEBUG_ECREATE_PROCESS_* flags.
+    ULONG EngCreateFlags;
+    // Application Verifier flags,
+    // if DEBUG_ECREATE_PROCESS_USE_VERIFIER_FLAGS is set.
+    ULONG VerifierFlags;
+    // Must be zero.
+    ULONG Reserved;
+} DEBUG_CREATE_PROCESS_OPTIONS, *PDEBUG_CREATE_PROCESS_OPTIONS;
+
+//
+// Process options.
+//
+
+// Indicates that the debuggee process should be
+// automatically detached when the debugger exits.
+// A debugger can explicitly detach on exit or this
+// flag can be set so that detach occurs regardless
+// of how the debugger exits.
+// This is only supported on some system versions.
+#define DEBUG_PROCESS_DETACH_ON_EXIT    0x00000001
+// Indicates that processes created by the current
+// process should not be debugged.
+// Modifying this flag is only supported on some
+// system versions.
+#define DEBUG_PROCESS_ONLY_THIS_PROCESS 0x00000002
+
+// ConnectSession flags.
+// Default connect.
+#define DEBUG_CONNECT_SESSION_DEFAULT     0x00000000
+// Do not output the debugger version.
+#define DEBUG_CONNECT_SESSION_NO_VERSION  0x00000001
+// Do not announce the connection.
+#define DEBUG_CONNECT_SESSION_NO_ANNOUNCE 0x00000002
+
+// OutputServers flags.
+// Debugger servers from StartSever.
+#define DEBUG_SERVERS_DEBUGGER 0x00000001
+// Process servers from StartProcessServer.
+#define DEBUG_SERVERS_PROCESS  0x00000002
+#define DEBUG_SERVERS_ALL      0x00000003
+
+// EndSession flags.
+// Perform cleanup for the session.
+#define DEBUG_END_PASSIVE          0x00000000
+// Actively terminate the session and then perform cleanup.
+#define DEBUG_END_ACTIVE_TERMINATE 0x00000001
+// If possible, detach from all processes and then perform cleanup.
+#define DEBUG_END_ACTIVE_DETACH    0x00000002
+// Perform whatever cleanup is possible that doesn't require
+// acquiring any locks.  This is useful for situations where
+// a thread is currently using the engine but the application
+// needs to exit and still wants to give the engine
+// the opportunity to clean up as much as possible.
+// This may leave the engine in an indeterminate state so
+// further engine calls should not be made.
+// When making a reentrant EndSession call from a remote
+// client it is the callers responsibility to ensure
+// that the server can process the request.  It is best
+// to avoid making such calls.
+#define DEBUG_END_REENTRANT        0x00000003
+// Notify a server that a remote client is disconnecting.
+// This isnt required but if it isnt called then
+// no disconnect messages will be generated by the server.
+#define DEBUG_END_DISCONNECT       0x00000004
+
+// Output mask bits.
+// Normal output.
+#define DEBUG_OUTPUT_NORMAL            0x00000001
+// Error output.
+#define DEBUG_OUTPUT_ERROR             0x00000002
+// Warnings.
+#define DEBUG_OUTPUT_WARNING           0x00000004
+// Additional output.
+#define DEBUG_OUTPUT_VERBOSE           0x00000008
+// Prompt output.
+#define DEBUG_OUTPUT_PROMPT            0x00000010
+// Register dump before prompt.
+#define DEBUG_OUTPUT_PROMPT_REGISTERS  0x00000020
+// Warnings specific to extension operation.
+#define DEBUG_OUTPUT_EXTENSION_WARNING 0x00000040
+// Debuggee debug output, such as from OutputDebugString.
+#define DEBUG_OUTPUT_DEBUGGEE          0x00000080
+// Debuggee-generated prompt, such as from DbgPrompt.
+#define DEBUG_OUTPUT_DEBUGGEE_PROMPT   0x00000100
+// Symbol messages, such as for !sym noisy.
+#define DEBUG_OUTPUT_SYMBOLS           0x00000200
+// Output which modifies the status bar
+#define DEBUG_OUTPUT_STATUS            0x00000400
+// Structured XML status messages
+#define DEBUG_OUTPUT_XML               0x00000800
+
+// Internal debugger output, used mainly
+// for debugging the debugger.  Output
+// may only occur in debug builds.
+// KD protocol output.
+#define DEBUG_IOUTPUT_KD_PROTOCOL      0x80000000
+// Remoting output.
+#define DEBUG_IOUTPUT_REMOTING         0x40000000
+// Breakpoint output.
+#define DEBUG_IOUTPUT_BREAKPOINT       0x20000000
+// Event output.
+#define DEBUG_IOUTPUT_EVENT            0x10000000
+// Virtual/Physical address translation
+#define DEBUG_IOUTPUT_ADDR_TRANSLATE   0x08000000
+
+// OutputIdentity flags.
+#define DEBUG_OUTPUT_IDENTITY_DEFAULT 0x00000000
+
+// Client identification constants
+#define DEBUG_CLIENT_UNKNOWN            0x0
+#define DEBUG_CLIENT_VSINT              0x1
+#define DEBUG_CLIENT_NTSD               0x2
+#define DEBUG_CLIENT_NTKD               0x3
+#define DEBUG_CLIENT_CDB                0x4
+#define DEBUG_CLIENT_KD                 0x5
+#define DEBUG_CLIENT_WINDBG             0x6
+#define DEBUG_CLIENT_WINIDE             0x7
+
+typedef struct _DEBUG_CLIENT_CONTEXT 
+{
+    UINT cbSize;
+    UINT eClient;
+} DEBUG_CLIENT_CONTEXT, *PDEBUG_CLIENT_CONTEXT;
+
+#undef INTERFACE
+#define INTERFACE IDebugClient
+DECLARE_INTERFACE_(IDebugClient, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugClient.
+
+    // The following set of methods start
+    // the different kinds of debuggees.
+
+    // Begins a debug session using the kernel
+    // debugging protocol.  This method selects
+    // the protocol as the debuggee communication
+    // mechanism but does not initiate the communication
+    // itself.
+    STDMETHOD(AttachKernel)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptions)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    // Updates the connection options for a live
+    // kernel connection.  This can only be used
+    // to modify parameters for the connection, not
+    // to switch to a completely different kind of
+    // connection.
+    // This method is reentrant.
+    STDMETHOD(SetKernelConnectionOptions)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+
+    // Starts a process server for remote
+    // user-mode process control.
+    // The local process server is server zero.
+    STDMETHOD(StartProcessServer)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServer)(
+        THIS_
+        _In_ PCSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+    STDMETHOD(DisconnectProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+
+    // Enumerates and describes processes
+    // accessible through the given process server.
+    STDMETHOD(GetRunningProcessSystemIds)(
+        THIS_
+        _In_ ULONG64 Server,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _In_ ULONG Count,
+        _Out_opt_ PULONG ActualCount
+        ) PURE;
+    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescription)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    // Attaches to a running user-mode process.
+    STDMETHOD(AttachProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Creates a new user-mode process for debugging.
+    // CreateFlags are as given to Win32s CreateProcess.
+    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
+    // must be specified.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    // Creates or attaches to a user-mode process, or both.
+    // If CommandLine is NULL this method operates as
+    // AttachProcess does.  If ProcessId is zero it
+    // operates as CreateProcess does.  If CommandLine is
+    // non-NULL and ProcessId is non-zero the method first
+    // starts a process with the given information but
+    // in a suspended state.  The engine then attaches to
+    // the indicated process.  Once the attach is successful
+    // the suspended process is resumed.  This provides
+    // synchronization between the new process and the
+    // attachment.
+    STDMETHOD(CreateProcessAndAttach)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Gets and sets process control flags.
+    STDMETHOD(GetProcessOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Opens any kind of user- or kernel-mode dump file
+    // and begins a debug session with the information
+    // contained within it.
+    STDMETHOD(OpenDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile
+        ) PURE;
+    // Writes a dump file from the current session information.
+    // The kind of dump file written is determined by the
+    // kind of session and the type qualifier given.
+    // For example, if the current session is a kernel
+    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
+    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
+    STDMETHOD(WriteDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier
+        ) PURE;
+
+    // Indicates that a remote client is ready to
+    // begin participating in the current session.
+    // HistoryLimit gives a character limit on
+    // the amount of output history to be sent.
+    STDMETHOD(ConnectSession)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG HistoryLimit
+        ) PURE;
+    // Indicates that the engine should start accepting
+    // remote connections. Options specifies connection types
+    // and their parameters.  Supported strings are:
+    //    npipe:Pipe=<Pipe name>
+    //    tcp:Port=<IP port>
+    STDMETHOD(StartServer)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+    // List the servers running on the given machine.
+    // Uses the line prefix.
+    STDMETHOD(OutputServers)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Attempts to terminate all processes in the debuggers list.
+    STDMETHOD(TerminateProcesses)(
+        THIS
+        ) PURE;
+    // Attempts to detach from all processes in the debuggers list.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachProcesses)(
+        THIS
+        ) PURE;
+    // Stops the current debug session.  If a process
+    // was created or attached an active EndSession can
+    // terminate or detach from it.
+    // If a kernel connection was opened it will be closed but the
+    // target machine is otherwise unaffected.
+    STDMETHOD(EndSession)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // If a process was started and ran to completion
+    // this method can be used to retrieve its exit code.
+    STDMETHOD(GetExitCode)(
+        THIS_
+        _Out_ PULONG Code
+        ) PURE;
+
+    // Client event callbacks are called on the thread
+    // of the client.  In order to give thread
+    // execution to the engine for callbacks all
+    // client threads should call DispatchCallbacks
+    // when they are idle.  Callbacks are only
+    // received when a thread calls DispatchCallbacks
+    // or WaitForEvent.  WaitForEvent can only be
+    // called by the thread that started the debug
+    // session so all other client threads should
+    // call DispatchCallbacks when possible.
+    // DispatchCallbacks returns when ExitDispatch is used
+    // to interrupt dispatch or when the timeout expires.
+    // DispatchCallbacks dispatches callbacks for all
+    // clients associated with the thread calling
+    // DispatchCallbacks.
+    // DispatchCallbacks returns S_FALSE when the
+    // timeout expires.
+    STDMETHOD(DispatchCallbacks)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+    // ExitDispatch can be used to interrupt callback
+    // dispatch when a client thread is needed by the
+    // client.  This method is reentrant and can
+    // be called from any thread.
+    STDMETHOD(ExitDispatch)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client
+        ) PURE;
+
+    // Clients are specific to the thread that
+    // created them.  Calls from other threads
+    // fail immediately.  The CreateClient method
+    // is a notable exception; it allows creation
+    // of a new client for a new thread.
+    STDMETHOD(CreateClient)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Client
+        ) PURE;
+
+    STDMETHOD(GetInputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_INPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetInputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_INPUT_CALLBACKS Callbacks
+        ) PURE;
+
+    // Output callback interfaces are described separately.
+    STDMETHOD(GetOutputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_OUTPUT_CALLBACKS Callbacks
+        ) PURE;
+    // Output flags provide control over
+    // the distribution of output among clients.
+    // Output masks select which output streams
+    // should be sent to the output callbacks.
+    // Only Output calls with a mask that
+    // contains one of the output mask bits
+    // will be sent to the output callbacks.
+    // These methods are reentrant.
+    // If such access is not synchronized
+    // disruptions in output may occur.
+    STDMETHOD(GetOutputMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOutputMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+    // These methods allow access to another clients
+    // output mask.  They are necessary for changing
+    // a clients output mask when it is
+    // waiting for events.  These methods are reentrant
+    // and can be called from any thread.
+    STDMETHOD(GetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _In_ ULONG Mask
+        ) PURE;
+    // Control the width of an output line for
+    // commands which produce formatted output.
+    // This setting is just a suggestion.
+    STDMETHOD(GetOutputWidth)(
+        THIS_
+        _Out_ PULONG Columns
+        ) PURE;
+    STDMETHOD(SetOutputWidth)(
+        THIS_
+        _In_ ULONG Columns
+        ) PURE;
+    // Some of the engines output commands produce
+    // multiple lines of output.  A prefix can be
+    // set that the engine will automatically output
+    // for each line in that case, allowing a caller
+    // to control indentation or identifying marks.
+    // This is not a general setting for any output
+    // with a newline in it.  Methods which use
+    // the line prefix are marked in their documentation.
+    STDMETHOD(GetOutputLinePrefix)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR Prefix
+        ) PURE;
+
+    // Returns a string describing the machine
+    // and user this client represents.  The
+    // specific content of the string varies
+    // with operating system.  If the client is
+    // remotely connected some network information
+    // may also be present.
+    STDMETHOD(GetIdentity)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    // Format is a printf-like format string
+    // with one %s where the identity string should go.
+    STDMETHOD(OutputIdentity)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCSTR Format
+        ) PURE;
+
+    // Event callbacks allow a client to
+    // receive notification about changes
+    // during the debug session.
+    STDMETHOD(GetEventCallbacks)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_EVENT_CALLBACKS Callbacks
+        ) PURE;
+
+    // The engine sometimes merges compatible callback
+    // requests to reduce callback overhead.  This is
+    // most noticeable with output as small pieces of
+    // output are collected into larger groups to
+    // reduce the overall number of output callback calls.
+    // A client can use this method to force all pending
+    // callbacks to be delivered.  This is rarely necessary.
+    STDMETHOD(FlushCallbacks)(
+        THIS
+        ) PURE;
+};
+
+// Per-dump-format control flags.
+#define DEBUG_FORMAT_DEFAULT                  0x00000000
+// When creating a CAB with secondary images do searches
+// for all image files, regardless of whether they're
+// needed for the current session or not.
+#define DEBUG_FORMAT_CAB_SECONDARY_ALL_IMAGES 0x10000000
+// Write dump to a temporary file, then package it
+// into a CAB file and delete the temporary file.
+#define DEBUG_FORMAT_WRITE_CAB                0x20000000
+// When creating a CAB add secondary files such as
+// current symbols and mapped images.
+#define DEBUG_FORMAT_CAB_SECONDARY_FILES      0x40000000
+// Don't overwrite existing files.
+#define DEBUG_FORMAT_NO_OVERWRITE             0x80000000
+
+#define DEBUG_FORMAT_USER_SMALL_FULL_MEMORY               0x00000001
+#define DEBUG_FORMAT_USER_SMALL_HANDLE_DATA               0x00000002
+#define DEBUG_FORMAT_USER_SMALL_UNLOADED_MODULES          0x00000004
+#define DEBUG_FORMAT_USER_SMALL_INDIRECT_MEMORY           0x00000008
+#define DEBUG_FORMAT_USER_SMALL_DATA_SEGMENTS             0x00000010
+#define DEBUG_FORMAT_USER_SMALL_FILTER_MEMORY             0x00000020
+#define DEBUG_FORMAT_USER_SMALL_FILTER_PATHS              0x00000040
+#define DEBUG_FORMAT_USER_SMALL_PROCESS_THREAD_DATA       0x00000080
+#define DEBUG_FORMAT_USER_SMALL_PRIVATE_READ_WRITE_MEMORY 0x00000100
+#define DEBUG_FORMAT_USER_SMALL_NO_OPTIONAL_DATA          0x00000200
+#define DEBUG_FORMAT_USER_SMALL_FULL_MEMORY_INFO          0x00000400
+#define DEBUG_FORMAT_USER_SMALL_THREAD_INFO               0x00000800
+#define DEBUG_FORMAT_USER_SMALL_CODE_SEGMENTS             0x00001000
+#define DEBUG_FORMAT_USER_SMALL_NO_AUXILIARY_STATE        0x00002000
+#define DEBUG_FORMAT_USER_SMALL_FULL_AUXILIARY_STATE      0x00004000
+#define DEBUG_FORMAT_USER_SMALL_MODULE_HEADERS            0x00008000
+#define DEBUG_FORMAT_USER_SMALL_FILTER_TRIAGE             0x00010000
+#define DEBUG_FORMAT_USER_SMALL_ADD_AVX_XSTATE_CONTEXT    0x00020000
+#define DEBUG_FORMAT_USER_SMALL_IPT_TRACE                 0x00040000
+#define DEBUG_FORMAT_USER_SMALL_IGNORE_INACCESSIBLE_MEM   0x08000000
+#define DEBUG_FORMAT_USER_SMALL_SCAN_PARTIAL_PAGES        0x10000000
+
+
+//
+// Dump information file types.
+//
+
+// Base dump file, returned when querying for dump files.
+#define DEBUG_DUMP_FILE_BASE           0xffffffff
+// Single file containing packed page file information.
+#define DEBUG_DUMP_FILE_PAGE_FILE_DUMP 0x00000000
+
+#undef INTERFACE
+#define INTERFACE IDebugClient2
+DECLARE_INTERFACE_(IDebugClient2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugClient.
+
+    // The following set of methods start
+    // the different kinds of debuggees.
+
+    // Begins a debug session using the kernel
+    // debugging protocol.  This method selects
+    // the protocol as the debuggee communication
+    // mechanism but does not initiate the communication
+    // itself.
+    STDMETHOD(AttachKernel)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptions)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    // Updates the connection options for a live
+    // kernel connection.  This can only be used
+    // to modify parameters for the connection, not
+    // to switch to a completely different kind of
+    // connection.
+    // This method is reentrant.
+    STDMETHOD(SetKernelConnectionOptions)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+
+    // Starts a process server for remote
+    // user-mode process control.
+    // The local process server is server zero.
+    STDMETHOD(StartProcessServer)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServer)(
+        THIS_
+        _In_ PCSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+    STDMETHOD(DisconnectProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+
+    // Enumerates and describes processes
+    // accessible through the given process server.
+    STDMETHOD(GetRunningProcessSystemIds)(
+        THIS_
+        _In_ ULONG64 Server,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _In_ ULONG Count,
+        _Out_opt_ PULONG ActualCount
+        ) PURE;
+    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescription)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    // Attaches to a running user-mode process.
+    STDMETHOD(AttachProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Creates a new user-mode process for debugging.
+    // CreateFlags are as given to Win32s CreateProcess.
+    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
+    // must be specified.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    // Creates or attaches to a user-mode process, or both.
+    // If CommandLine is NULL this method operates as
+    // AttachProcess does.  If ProcessId is zero it
+    // operates as CreateProcess does.  If CommandLine is
+    // non-NULL and ProcessId is non-zero the method first
+    // starts a process with the given information but
+    // in a suspended state.  The engine then attaches to
+    // the indicated process.  Once the attach is successful
+    // the suspended process is resumed.  This provides
+    // synchronization between the new process and the
+    // attachment.
+    STDMETHOD(CreateProcessAndAttach)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Gets and sets process control flags.
+    STDMETHOD(GetProcessOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Opens any kind of user- or kernel-mode dump file
+    // and begins a debug session with the information
+    // contained within it.
+    STDMETHOD(OpenDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile
+        ) PURE;
+    // Writes a dump file from the current session information.
+    // The kind of dump file written is determined by the
+    // kind of session and the type qualifier given.
+    // For example, if the current session is a kernel
+    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
+    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
+    STDMETHOD(WriteDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier
+        ) PURE;
+
+    // Indicates that a remote client is ready to
+    // begin participating in the current session.
+    // HistoryLimit gives a character limit on
+    // the amount of output history to be sent.
+    STDMETHOD(ConnectSession)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG HistoryLimit
+        ) PURE;
+    // Indicates that the engine should start accepting
+    // remote connections. Options specifies connection types
+    // and their parameters.  Supported strings are:
+    //    npipe:Pipe=<Pipe name>
+    //    tcp:Port=<IP port>
+    STDMETHOD(StartServer)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+    // List the servers running on the given machine.
+    // Uses the line prefix.
+    STDMETHOD(OutputServers)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Attempts to terminate all processes in the debuggers list.
+    STDMETHOD(TerminateProcesses)(
+        THIS
+        ) PURE;
+    // Attempts to detach from all processes in the debuggers list.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachProcesses)(
+        THIS
+        ) PURE;
+    // Stops the current debug session.  If a process
+    // was created or attached an active EndSession can
+    // terminate or detach from it.
+    // If a kernel connection was opened it will be closed but the
+    // target machine is otherwise unaffected.
+    STDMETHOD(EndSession)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // If a process was started and ran to completion
+    // this method can be used to retrieve its exit code.
+    STDMETHOD(GetExitCode)(
+        THIS_
+        _Out_ PULONG Code
+        ) PURE;
+
+    // Client event callbacks are called on the thread
+    // of the client.  In order to give thread
+    // execution to the engine for callbacks all
+    // client threads should call DispatchCallbacks
+    // when they are idle.  Callbacks are only
+    // received when a thread calls DispatchCallbacks
+    // or WaitForEvent.  WaitForEvent can only be
+    // called by the thread that started the debug
+    // session so all other client threads should
+    // call DispatchCallbacks when possible.
+    // DispatchCallbacks returns when ExitDispatch is used
+    // to interrupt dispatch or when the timeout expires.
+    // DispatchCallbacks dispatches callbacks for all
+    // clients associated with the thread calling
+    // DispatchCallbacks.
+    // DispatchCallbacks returns S_FALSE when the
+    // timeout expires.
+    STDMETHOD(DispatchCallbacks)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+    // ExitDispatch can be used to interrupt callback
+    // dispatch when a client thread is needed by the
+    // client.  This method is reentrant and can
+    // be called from any thread.
+    STDMETHOD(ExitDispatch)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client
+        ) PURE;
+
+    // Clients are specific to the thread that
+    // created them.  Calls from other threads
+    // fail immediately.  The CreateClient method
+    // is a notable exception; it allows creation
+    // of a new client for a new thread.
+    STDMETHOD(CreateClient)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Client
+        ) PURE;
+
+    STDMETHOD(GetInputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_INPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetInputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_INPUT_CALLBACKS Callbacks
+        ) PURE;
+
+    // Output callback interfaces are described separately.
+    STDMETHOD(GetOutputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_OUTPUT_CALLBACKS Callbacks
+        ) PURE;
+    // Output flags provide control over
+    // the distribution of output among clients.
+    // Output masks select which output streams
+    // should be sent to the output callbacks.
+    // Only Output calls with a mask that
+    // contains one of the output mask bits
+    // will be sent to the output callbacks.
+    // These methods are reentrant.
+    // If such access is not synchronized
+    // disruptions in output may occur.
+    STDMETHOD(GetOutputMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOutputMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+    // These methods allow access to another clients
+    // output mask.  They are necessary for changing
+    // a clients output mask when it is
+    // waiting for events.  These methods are reentrant
+    // and can be called from any thread.
+    STDMETHOD(GetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _In_ ULONG Mask
+        ) PURE;
+    // Control the width of an output line for
+    // commands which produce formatted output.
+    // This setting is just a suggestion.
+    STDMETHOD(GetOutputWidth)(
+        THIS_
+        _Out_ PULONG Columns
+        ) PURE;
+    STDMETHOD(SetOutputWidth)(
+        THIS_
+        _In_ ULONG Columns
+        ) PURE;
+    // Some of the engines output commands produce
+    // multiple lines of output.  A prefix can be
+    // set that the engine will automatically output
+    // for each line in that case, allowing a caller
+    // to control indentation or identifying marks.
+    // This is not a general setting for any output
+    // with a newline in it.  Methods which use
+    // the line prefix are marked in their documentation.
+    STDMETHOD(GetOutputLinePrefix)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR Prefix
+        ) PURE;
+
+    // Returns a string describing the machine
+    // and user this client represents.  The
+    // specific content of the string varies
+    // with operating system.  If the client is
+    // remotely connected some network information
+    // may also be present.
+    STDMETHOD(GetIdentity)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    // Format is a printf-like format string
+    // with one %s where the identity string should go.
+    STDMETHOD(OutputIdentity)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCSTR Format
+        ) PURE;
+
+    // Event callbacks allow a client to
+    // receive notification about changes
+    // during the debug session.
+    STDMETHOD(GetEventCallbacks)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_EVENT_CALLBACKS Callbacks
+        ) PURE;
+
+    // The engine sometimes merges compatible callback
+    // requests to reduce callback overhead.  This is
+    // most noticeable with output as small pieces of
+    // output are collected into larger groups to
+    // reduce the overall number of output callback calls.
+    // A client can use this method to force all pending
+    // callbacks to be delivered.  This is rarely necessary.
+    STDMETHOD(FlushCallbacks)(
+        THIS
+        ) PURE;
+
+    // IDebugClient2.
+
+    // Functions similarly to WriteDumpFile with
+    // the addition of the ability to specify
+    // per-dump-format write control flags.
+    // Comment is not supported in all formats.
+    STDMETHOD(WriteDumpFile2)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCSTR Comment
+        ) PURE;
+    // Registers additional files of supporting information
+    // for a dump file open.  This method must be called
+    // before OpenDumpFile is called.
+    // The files registered may be opened at the time
+    // this method is called but generally will not
+    // be used until OpenDumpFile is called.
+    STDMETHOD(AddDumpInformationFile)(
+        THIS_
+        _In_ PCSTR InfoFile,
+        _In_ ULONG Type
+        ) PURE;
+
+    // Requests that the remote process server shut down.
+    STDMETHOD(EndProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+    // Waits for a started process server to
+    // exit.  Allows an application running a
+    // process server to monitor the process
+    // server so that it can tell when a remote
+    // client has asked for it to exit.
+    // Returns S_OK if the process server has
+    // shut down and S_FALSE for a timeout.
+    STDMETHOD(WaitForProcessServerEnd)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Returns S_OK if the system is configured
+    // to allow kernel debugging.
+    STDMETHOD(IsKernelDebuggerEnabled)(
+        THIS
+        ) PURE;
+
+    // Attempts to terminate the current process.
+    // Exit process events for the process may be generated.
+    STDMETHOD(TerminateCurrentProcess)(
+        THIS
+        ) PURE;
+    // Attempts to detach from the current process.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachCurrentProcess)(
+        THIS
+        ) PURE;
+    // Removes the process from the debuggers process
+    // list without making any other changes.  The process
+    // will still be marked as being debugged and will
+    // not run.  This allows a debugger to be shut down
+    // and a new debugger attached without taking the
+    // process out of the debugged state.
+    // This is only supported on some system versions.
+    STDMETHOD(AbandonCurrentProcess)(
+        THIS
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugClient3
+DECLARE_INTERFACE_(IDebugClient3, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugClient.
+
+    // The following set of methods start
+    // the different kinds of debuggees.
+
+    // Begins a debug session using the kernel
+    // debugging protocol.  This method selects
+    // the protocol as the debuggee communication
+    // mechanism but does not initiate the communication
+    // itself.
+    STDMETHOD(AttachKernel)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptions)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    // Updates the connection options for a live
+    // kernel connection.  This can only be used
+    // to modify parameters for the connection, not
+    // to switch to a completely different kind of
+    // connection.
+    // This method is reentrant.
+    STDMETHOD(SetKernelConnectionOptions)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+
+    // Starts a process server for remote
+    // user-mode process control.
+    // The local process server is server zero.
+    STDMETHOD(StartProcessServer)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServer)(
+        THIS_
+        _In_ PCSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+    STDMETHOD(DisconnectProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+
+    // Enumerates and describes processes
+    // accessible through the given process server.
+    STDMETHOD(GetRunningProcessSystemIds)(
+        THIS_
+        _In_ ULONG64 Server,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _In_ ULONG Count,
+        _Out_opt_ PULONG ActualCount
+        ) PURE;
+    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescription)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    // Attaches to a running user-mode process.
+    STDMETHOD(AttachProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Creates a new user-mode process for debugging.
+    // CreateFlags are as given to Win32s CreateProcess.
+    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
+    // must be specified.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    // Creates or attaches to a user-mode process, or both.
+    // If CommandLine is NULL this method operates as
+    // AttachProcess does.  If ProcessId is zero it
+    // operates as CreateProcess does.  If CommandLine is
+    // non-NULL and ProcessId is non-zero the method first
+    // starts a process with the given information but
+    // in a suspended state.  The engine then attaches to
+    // the indicated process.  Once the attach is successful
+    // the suspended process is resumed.  This provides
+    // synchronization between the new process and the
+    // attachment.
+    STDMETHOD(CreateProcessAndAttach)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Gets and sets process control flags.
+    STDMETHOD(GetProcessOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Opens any kind of user- or kernel-mode dump file
+    // and begins a debug session with the information
+    // contained within it.
+    STDMETHOD(OpenDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile
+        ) PURE;
+    // Writes a dump file from the current session information.
+    // The kind of dump file written is determined by the
+    // kind of session and the type qualifier given.
+    // For example, if the current session is a kernel
+    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
+    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
+    STDMETHOD(WriteDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier
+        ) PURE;
+
+    // Indicates that a remote client is ready to
+    // begin participating in the current session.
+    // HistoryLimit gives a character limit on
+    // the amount of output history to be sent.
+    STDMETHOD(ConnectSession)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG HistoryLimit
+        ) PURE;
+    // Indicates that the engine should start accepting
+    // remote connections. Options specifies connection types
+    // and their parameters.  Supported strings are:
+    //    npipe:Pipe=<Pipe name>
+    //    tcp:Port=<IP port>
+    STDMETHOD(StartServer)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+    // List the servers running on the given machine.
+    // Uses the line prefix.
+    STDMETHOD(OutputServers)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Attempts to terminate all processes in the debuggers list.
+    STDMETHOD(TerminateProcesses)(
+        THIS
+        ) PURE;
+    // Attempts to detach from all processes in the debuggers list.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachProcesses)(
+        THIS
+        ) PURE;
+    // Stops the current debug session.  If a process
+    // was created or attached an active EndSession can
+    // terminate or detach from it.
+    // If a kernel connection was opened it will be closed but the
+    // target machine is otherwise unaffected.
+    STDMETHOD(EndSession)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // If a process was started and ran to completion
+    // this method can be used to retrieve its exit code.
+    STDMETHOD(GetExitCode)(
+        THIS_
+        _Out_ PULONG Code
+        ) PURE;
+
+    // Client event callbacks are called on the thread
+    // of the client.  In order to give thread
+    // execution to the engine for callbacks all
+    // client threads should call DispatchCallbacks
+    // when they are idle.  Callbacks are only
+    // received when a thread calls DispatchCallbacks
+    // or WaitForEvent.  WaitForEvent can only be
+    // called by the thread that started the debug
+    // session so all other client threads should
+    // call DispatchCallbacks when possible.
+    // DispatchCallbacks returns when ExitDispatch is used
+    // to interrupt dispatch or when the timeout expires.
+    // DispatchCallbacks dispatches callbacks for all
+    // clients associated with the thread calling
+    // DispatchCallbacks.
+    // DispatchCallbacks returns S_FALSE when the
+    // timeout expires.
+    STDMETHOD(DispatchCallbacks)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+    // ExitDispatch can be used to interrupt callback
+    // dispatch when a client thread is needed by the
+    // client.  This method is reentrant and can
+    // be called from any thread.
+    STDMETHOD(ExitDispatch)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client
+        ) PURE;
+
+    // Clients are specific to the thread that
+    // created them.  Calls from other threads
+    // fail immediately.  The CreateClient method
+    // is a notable exception; it allows creation
+    // of a new client for a new thread.
+    STDMETHOD(CreateClient)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Client
+        ) PURE;
+
+    STDMETHOD(GetInputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_INPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetInputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_INPUT_CALLBACKS Callbacks
+        ) PURE;
+
+    // Output callback interfaces are described separately.
+    STDMETHOD(GetOutputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_OUTPUT_CALLBACKS Callbacks
+        ) PURE;
+    // Output flags provide control over
+    // the distribution of output among clients.
+    // Output masks select which output streams
+    // should be sent to the output callbacks.
+    // Only Output calls with a mask that
+    // contains one of the output mask bits
+    // will be sent to the output callbacks.
+    // These methods are reentrant.
+    // If such access is not synchronized
+    // disruptions in output may occur.
+    STDMETHOD(GetOutputMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOutputMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+    // These methods allow access to another clients
+    // output mask.  They are necessary for changing
+    // a clients output mask when it is
+    // waiting for events.  These methods are reentrant
+    // and can be called from any thread.
+    STDMETHOD(GetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _In_ ULONG Mask
+        ) PURE;
+    // Control the width of an output line for
+    // commands which produce formatted output.
+    // This setting is just a suggestion.
+    STDMETHOD(GetOutputWidth)(
+        THIS_
+        _Out_ PULONG Columns
+        ) PURE;
+    STDMETHOD(SetOutputWidth)(
+        THIS_
+        _In_ ULONG Columns
+        ) PURE;
+    // Some of the engines output commands produce
+    // multiple lines of output.  A prefix can be
+    // set that the engine will automatically output
+    // for each line in that case, allowing a caller
+    // to control indentation or identifying marks.
+    // This is not a general setting for any output
+    // with a newline in it.  Methods which use
+    // the line prefix are marked in their documentation.
+    STDMETHOD(GetOutputLinePrefix)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR Prefix
+        ) PURE;
+
+    // Returns a string describing the machine
+    // and user this client represents.  The
+    // specific content of the string varies
+    // with operating system.  If the client is
+    // remotely connected some network information
+    // may also be present.
+    STDMETHOD(GetIdentity)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    // Format is a printf-like format string
+    // with one %s where the identity string should go.
+    STDMETHOD(OutputIdentity)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCSTR Format
+        ) PURE;
+
+    // Event callbacks allow a client to
+    // receive notification about changes
+    // during the debug session.
+    STDMETHOD(GetEventCallbacks)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_EVENT_CALLBACKS Callbacks
+        ) PURE;
+
+    // The engine sometimes merges compatible callback
+    // requests to reduce callback overhead.  This is
+    // most noticeable with output as small pieces of
+    // output are collected into larger groups to
+    // reduce the overall number of output callback calls.
+    // A client can use this method to force all pending
+    // callbacks to be delivered.  This is rarely necessary.
+    STDMETHOD(FlushCallbacks)(
+        THIS
+        ) PURE;
+
+    // IDebugClient2.
+
+    // Functions similarly to WriteDumpFile with
+    // the addition of the ability to specify
+    // per-dump-format write control flags.
+    // Comment is not supported in all formats.
+    STDMETHOD(WriteDumpFile2)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCSTR Comment
+        ) PURE;
+    // Registers additional files of supporting information
+    // for a dump file open.  This method must be called
+    // before OpenDumpFile is called.
+    // The files registered may be opened at the time
+    // this method is called but generally will not
+    // be used until OpenDumpFile is called.
+    STDMETHOD(AddDumpInformationFile)(
+        THIS_
+        _In_ PCSTR InfoFile,
+        _In_ ULONG Type
+        ) PURE;
+
+    // Requests that the remote process server shut down.
+    STDMETHOD(EndProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+    // Waits for a started process server to
+    // exit.  Allows an application running a
+    // process server to monitor the process
+    // server so that it can tell when a remote
+    // client has asked for it to exit.
+    // Returns S_OK if the process server has
+    // shut down and S_FALSE for a timeout.
+    STDMETHOD(WaitForProcessServerEnd)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Returns S_OK if the system is configured
+    // to allow kernel debugging.
+    STDMETHOD(IsKernelDebuggerEnabled)(
+        THIS
+        ) PURE;
+
+    // Attempts to terminate the current process.
+    // Exit process events for the process may be generated.
+    STDMETHOD(TerminateCurrentProcess)(
+        THIS
+        ) PURE;
+    // Attempts to detach from the current process.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachCurrentProcess)(
+        THIS
+        ) PURE;
+    // Removes the process from the debuggers process
+    // list without making any other changes.  The process
+    // will still be marked as being debugged and will
+    // not run.  This allows a debugger to be shut down
+    // and a new debugger attached without taking the
+    // process out of the debugged state.
+    // This is only supported on some system versions.
+    STDMETHOD(AbandonCurrentProcess)(
+        THIS
+        ) PURE;
+
+    // IDebugClient3.
+
+    STDMETHOD(GetRunningProcessSystemIdByExecutableNameWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescriptionWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PWSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PWSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    STDMETHOD(CreateProcessWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttachWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+};
+
+//
+// Special indices for GetDumpFile to return
+// alternate filenames.
+//
+
+// Special index that returns the name of the last .dmp file
+// that failed to load (whether directly or from inside a
+// .cab file).
+#define DEBUG_DUMP_FILE_LOAD_FAILED_INDEX  0xffffffff
+// Index that returns last cab file opened, this is needed to
+// get the name of original CAB file since debugger returns the
+// extracted dump file in the GetDumpFile method.
+#define DEBUG_DUMP_FILE_ORIGINAL_CAB_INDEX 0xfffffffe
+
+#undef INTERFACE
+#define INTERFACE IDebugClient4
+DECLARE_INTERFACE_(IDebugClient4, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugClient.
+
+    // The following set of methods start
+    // the different kinds of debuggees.
+
+    // Begins a debug session using the kernel
+    // debugging protocol.  This method selects
+    // the protocol as the debuggee communication
+    // mechanism but does not initiate the communication
+    // itself.
+    STDMETHOD(AttachKernel)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptions)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    // Updates the connection options for a live
+    // kernel connection.  This can only be used
+    // to modify parameters for the connection, not
+    // to switch to a completely different kind of
+    // connection.
+    // This method is reentrant.
+    STDMETHOD(SetKernelConnectionOptions)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+
+    // Starts a process server for remote
+    // user-mode process control.
+    // The local process server is server zero.
+    STDMETHOD(StartProcessServer)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServer)(
+        THIS_
+        _In_ PCSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+    STDMETHOD(DisconnectProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+
+    // Enumerates and describes processes
+    // accessible through the given process server.
+    STDMETHOD(GetRunningProcessSystemIds)(
+        THIS_
+        _In_ ULONG64 Server,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _In_ ULONG Count,
+        _Out_opt_ PULONG ActualCount
+        ) PURE;
+    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescription)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    // Attaches to a running user-mode process.
+    STDMETHOD(AttachProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Creates a new user-mode process for debugging.
+    // CreateFlags are as given to Win32s CreateProcess.
+    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
+    // must be specified.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    // Creates or attaches to a user-mode process, or both.
+    // If CommandLine is NULL this method operates as
+    // AttachProcess does.  If ProcessId is zero it
+    // operates as CreateProcess does.  If CommandLine is
+    // non-NULL and ProcessId is non-zero the method first
+    // starts a process with the given information but
+    // in a suspended state.  The engine then attaches to
+    // the indicated process.  Once the attach is successful
+    // the suspended process is resumed.  This provides
+    // synchronization between the new process and the
+    // attachment.
+    STDMETHOD(CreateProcessAndAttach)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Gets and sets process control flags.
+    STDMETHOD(GetProcessOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Opens any kind of user- or kernel-mode dump file
+    // and begins a debug session with the information
+    // contained within it.
+    STDMETHOD(OpenDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile
+        ) PURE;
+    // Writes a dump file from the current session information.
+    // The kind of dump file written is determined by the
+    // kind of session and the type qualifier given.
+    // For example, if the current session is a kernel
+    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
+    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
+    STDMETHOD(WriteDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier
+        ) PURE;
+
+    // Indicates that a remote client is ready to
+    // begin participating in the current session.
+    // HistoryLimit gives a character limit on
+    // the amount of output history to be sent.
+    STDMETHOD(ConnectSession)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG HistoryLimit
+        ) PURE;
+    // Indicates that the engine should start accepting
+    // remote connections. Options specifies connection types
+    // and their parameters.  Supported strings are:
+    //    npipe:Pipe=<Pipe name>
+    //    tcp:Port=<IP port>
+    STDMETHOD(StartServer)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+    // List the servers running on the given machine.
+    // Uses the line prefix.
+    STDMETHOD(OutputServers)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Attempts to terminate all processes in the debuggers list.
+    STDMETHOD(TerminateProcesses)(
+        THIS
+        ) PURE;
+    // Attempts to detach from all processes in the debuggers list.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachProcesses)(
+        THIS
+        ) PURE;
+    // Stops the current debug session.  If a process
+    // was created or attached an active EndSession can
+    // terminate or detach from it.
+    // If a kernel connection was opened it will be closed but the
+    // target machine is otherwise unaffected.
+    STDMETHOD(EndSession)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // If a process was started and ran to completion
+    // this method can be used to retrieve its exit code.
+    STDMETHOD(GetExitCode)(
+        THIS_
+        _Out_ PULONG Code
+        ) PURE;
+
+    // Client event callbacks are called on the thread
+    // of the client.  In order to give thread
+    // execution to the engine for callbacks all
+    // client threads should call DispatchCallbacks
+    // when they are idle.  Callbacks are only
+    // received when a thread calls DispatchCallbacks
+    // or WaitForEvent.  WaitForEvent can only be
+    // called by the thread that started the debug
+    // session so all other client threads should
+    // call DispatchCallbacks when possible.
+    // DispatchCallbacks returns when ExitDispatch is used
+    // to interrupt dispatch or when the timeout expires.
+    // DispatchCallbacks dispatches callbacks for all
+    // clients associated with the thread calling
+    // DispatchCallbacks.
+    // DispatchCallbacks returns S_FALSE when the
+    // timeout expires.
+    STDMETHOD(DispatchCallbacks)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+    // ExitDispatch can be used to interrupt callback
+    // dispatch when a client thread is needed by the
+    // client.  This method is reentrant and can
+    // be called from any thread.
+    STDMETHOD(ExitDispatch)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client
+        ) PURE;
+
+    // Clients are specific to the thread that
+    // created them.  Calls from other threads
+    // fail immediately.  The CreateClient method
+    // is a notable exception; it allows creation
+    // of a new client for a new thread.
+    STDMETHOD(CreateClient)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Client
+        ) PURE;
+
+    STDMETHOD(GetInputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_INPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetInputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_INPUT_CALLBACKS Callbacks
+        ) PURE;
+
+    // Output callback interfaces are described separately.
+    STDMETHOD(GetOutputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_OUTPUT_CALLBACKS Callbacks
+        ) PURE;
+    // Output flags provide control over
+    // the distribution of output among clients.
+    // Output masks select which output streams
+    // should be sent to the output callbacks.
+    // Only Output calls with a mask that
+    // contains one of the output mask bits
+    // will be sent to the output callbacks.
+    // These methods are reentrant.
+    // If such access is not synchronized
+    // disruptions in output may occur.
+    STDMETHOD(GetOutputMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOutputMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+    // These methods allow access to another clients
+    // output mask.  They are necessary for changing
+    // a clients output mask when it is
+    // waiting for events.  These methods are reentrant
+    // and can be called from any thread.
+    STDMETHOD(GetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _In_ ULONG Mask
+        ) PURE;
+    // Control the width of an output line for
+    // commands which produce formatted output.
+    // This setting is just a suggestion.
+    STDMETHOD(GetOutputWidth)(
+        THIS_
+        _Out_ PULONG Columns
+        ) PURE;
+    STDMETHOD(SetOutputWidth)(
+        THIS_
+        _In_ ULONG Columns
+        ) PURE;
+    // Some of the engines output commands produce
+    // multiple lines of output.  A prefix can be
+    // set that the engine will automatically output
+    // for each line in that case, allowing a caller
+    // to control indentation or identifying marks.
+    // This is not a general setting for any output
+    // with a newline in it.  Methods which use
+    // the line prefix are marked in their documentation.
+    STDMETHOD(GetOutputLinePrefix)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR Prefix
+        ) PURE;
+
+    // Returns a string describing the machine
+    // and user this client represents.  The
+    // specific content of the string varies
+    // with operating system.  If the client is
+    // remotely connected some network information
+    // may also be present.
+    STDMETHOD(GetIdentity)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    // Format is a printf-like format string
+    // with one %s where the identity string should go.
+    STDMETHOD(OutputIdentity)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCSTR Format
+        ) PURE;
+
+    // Event callbacks allow a client to
+    // receive notification about changes
+    // during the debug session.
+    STDMETHOD(GetEventCallbacks)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_EVENT_CALLBACKS Callbacks
+        ) PURE;
+
+    // The engine sometimes merges compatible callback
+    // requests to reduce callback overhead.  This is
+    // most noticeable with output as small pieces of
+    // output are collected into larger groups to
+    // reduce the overall number of output callback calls.
+    // A client can use this method to force all pending
+    // callbacks to be delivered.  This is rarely necessary.
+    STDMETHOD(FlushCallbacks)(
+        THIS
+        ) PURE;
+
+    // IDebugClient2.
+
+    // Functions similarly to WriteDumpFile with
+    // the addition of the ability to specify
+    // per-dump-format write control flags.
+    // Comment is not supported in all formats.
+    STDMETHOD(WriteDumpFile2)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCSTR Comment
+        ) PURE;
+    // Registers additional files of supporting information
+    // for a dump file open.  This method must be called
+    // before OpenDumpFile is called.
+    // The files registered may be opened at the time
+    // this method is called but generally will not
+    // be used until OpenDumpFile is called.
+    STDMETHOD(AddDumpInformationFile)(
+        THIS_
+        _In_ PCSTR InfoFile,
+        _In_ ULONG Type
+        ) PURE;
+
+    // Requests that the remote process server shut down.
+    STDMETHOD(EndProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+    // Waits for a started process server to
+    // exit.  Allows an application running a
+    // process server to monitor the process
+    // server so that it can tell when a remote
+    // client has asked for it to exit.
+    // Returns S_OK if the process server has
+    // shut down and S_FALSE for a timeout.
+    STDMETHOD(WaitForProcessServerEnd)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Returns S_OK if the system is configured
+    // to allow kernel debugging.
+    STDMETHOD(IsKernelDebuggerEnabled)(
+        THIS
+        ) PURE;
+
+    // Attempts to terminate the current process.
+    // Exit process events for the process may be generated.
+    STDMETHOD(TerminateCurrentProcess)(
+        THIS
+        ) PURE;
+    // Attempts to detach from the current process.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachCurrentProcess)(
+        THIS
+        ) PURE;
+    // Removes the process from the debuggers process
+    // list without making any other changes.  The process
+    // will still be marked as being debugged and will
+    // not run.  This allows a debugger to be shut down
+    // and a new debugger attached without taking the
+    // process out of the debugged state.
+    // This is only supported on some system versions.
+    STDMETHOD(AbandonCurrentProcess)(
+        THIS
+        ) PURE;
+
+    // IDebugClient3.
+
+    STDMETHOD(GetRunningProcessSystemIdByExecutableNameWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescriptionWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PWSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PWSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    STDMETHOD(CreateProcessWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttachWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+
+    // IDebugClient4.
+
+    // In the following methods both a filename and a file
+    // handle can be passed in.  If a file handle is given
+    // the filename may be omitted, although providing it
+    // allows the debugger to properly report the name when
+    // queried.
+    // File handles cannot be used in remote calls.
+    STDMETHOD(OpenDumpFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle
+        ) PURE;
+    STDMETHOD(WriteDumpFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCWSTR Comment
+        ) PURE;
+    STDMETHOD(AddDumpInformationFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle,
+        _In_ ULONG Type
+        ) PURE;
+    // These methods can be used to retrieve
+    // file information for all targets that
+    // involve files.
+    STDMETHOD(GetNumberDumpFiles)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetDumpFile)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Handle,
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(GetDumpFileWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Handle,
+        _Out_ PULONG Type
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugClient5
+DECLARE_INTERFACE_(IDebugClient5, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugClient.
+
+    // The following set of methods start
+    // the different kinds of debuggees.
+
+    // Begins a debug session using the kernel
+    // debugging protocol.  This method selects
+    // the protocol as the debuggee communication
+    // mechanism but does not initiate the communication
+    // itself.
+    STDMETHOD(AttachKernel)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptions)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    // Updates the connection options for a live
+    // kernel connection.  This can only be used
+    // to modify parameters for the connection, not
+    // to switch to a completely different kind of
+    // connection.
+    // This method is reentrant.
+    STDMETHOD(SetKernelConnectionOptions)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+
+    // Starts a process server for remote
+    // user-mode process control.
+    // The local process server is server zero.
+    STDMETHOD(StartProcessServer)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServer)(
+        THIS_
+        _In_ PCSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+    STDMETHOD(DisconnectProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+
+    // Enumerates and describes processes
+    // accessible through the given process server.
+    STDMETHOD(GetRunningProcessSystemIds)(
+        THIS_
+        _In_ ULONG64 Server,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _In_ ULONG Count,
+        _Out_opt_ PULONG ActualCount
+        ) PURE;
+    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescription)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    // Attaches to a running user-mode process.
+    STDMETHOD(AttachProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Creates a new user-mode process for debugging.
+    // CreateFlags are as given to Win32s CreateProcess.
+    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
+    // must be specified.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    // Creates or attaches to a user-mode process, or both.
+    // If CommandLine is NULL this method operates as
+    // AttachProcess does.  If ProcessId is zero it
+    // operates as CreateProcess does.  If CommandLine is
+    // non-NULL and ProcessId is non-zero the method first
+    // starts a process with the given information but
+    // in a suspended state.  The engine then attaches to
+    // the indicated process.  Once the attach is successful
+    // the suspended process is resumed.  This provides
+    // synchronization between the new process and the
+    // attachment.
+    STDMETHOD(CreateProcessAndAttach)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Gets and sets process control flags.
+    STDMETHOD(GetProcessOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Opens any kind of user- or kernel-mode dump file
+    // and begins a debug session with the information
+    // contained within it.
+    STDMETHOD(OpenDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile
+        ) PURE;
+    // Writes a dump file from the current session information.
+    // The kind of dump file written is determined by the
+    // kind of session and the type qualifier given.
+    // For example, if the current session is a kernel
+    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
+    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
+    STDMETHOD(WriteDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier
+        ) PURE;
+
+    // Indicates that a remote client is ready to
+    // begin participating in the current session.
+    // HistoryLimit gives a character limit on
+    // the amount of output history to be sent.
+    STDMETHOD(ConnectSession)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG HistoryLimit
+        ) PURE;
+    // Indicates that the engine should start accepting
+    // remote connections. Options specifies connection types
+    // and their parameters.  Supported strings are:
+    //    npipe:Pipe=<Pipe name>
+    //    tcp:Port=<IP port>
+    STDMETHOD(StartServer)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+    // List the servers running on the given machine.
+    // Uses the line prefix.
+    STDMETHOD(OutputServers)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Attempts to terminate all processes in the debuggers list.
+    STDMETHOD(TerminateProcesses)(
+        THIS
+        ) PURE;
+    // Attempts to detach from all processes in the debuggers list.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachProcesses)(
+        THIS
+        ) PURE;
+    // Stops the current debug session.  If a process
+    // was created or attached an active EndSession can
+    // terminate or detach from it.
+    // If a kernel connection was opened it will be closed but the
+    // target machine is otherwise unaffected.
+    STDMETHOD(EndSession)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // If a process was started and ran to completion
+    // this method can be used to retrieve its exit code.
+    STDMETHOD(GetExitCode)(
+        THIS_
+        _Out_ PULONG Code
+        ) PURE;
+
+    // Client event callbacks are called on the thread
+    // of the client.  In order to give thread
+    // execution to the engine for callbacks all
+    // client threads should call DispatchCallbacks
+    // when they are idle.  Callbacks are only
+    // received when a thread calls DispatchCallbacks
+    // or WaitForEvent.  WaitForEvent can only be
+    // called by the thread that started the debug
+    // session so all other client threads should
+    // call DispatchCallbacks when possible.
+    // DispatchCallbacks returns when ExitDispatch is used
+    // to interrupt dispatch or when the timeout expires.
+    // DispatchCallbacks dispatches callbacks for all
+    // clients associated with the thread calling
+    // DispatchCallbacks.
+    // DispatchCallbacks returns S_FALSE when the
+    // timeout expires.
+    STDMETHOD(DispatchCallbacks)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+    // ExitDispatch can be used to interrupt callback
+    // dispatch when a client thread is needed by the
+    // client.  This method is reentrant and can
+    // be called from any thread.
+    STDMETHOD(ExitDispatch)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client
+        ) PURE;
+
+    // Clients are specific to the thread that
+    // created them.  Calls from other threads
+    // fail immediately.  The CreateClient method
+    // is a notable exception; it allows creation
+    // of a new client for a new thread.
+    STDMETHOD(CreateClient)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Client
+        ) PURE;
+
+    STDMETHOD(GetInputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_INPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetInputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_INPUT_CALLBACKS Callbacks
+        ) PURE;
+
+    // Output callback interfaces are described separately.
+    STDMETHOD(GetOutputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_OUTPUT_CALLBACKS Callbacks
+        ) PURE;
+    // Output flags provide control over
+    // the distribution of output among clients.
+    // Output masks select which output streams
+    // should be sent to the output callbacks.
+    // Only Output calls with a mask that
+    // contains one of the output mask bits
+    // will be sent to the output callbacks.
+    // These methods are reentrant.
+    // If such access is not synchronized
+    // disruptions in output may occur.
+    STDMETHOD(GetOutputMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOutputMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+    // These methods allow access to another clients
+    // output mask.  They are necessary for changing
+    // a clients output mask when it is
+    // waiting for events.  These methods are reentrant
+    // and can be called from any thread.
+    STDMETHOD(GetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _In_ ULONG Mask
+        ) PURE;
+    // Control the width of an output line for
+    // commands which produce formatted output.
+    // This setting is just a suggestion.
+    STDMETHOD(GetOutputWidth)(
+        THIS_
+        _Out_ PULONG Columns
+        ) PURE;
+    STDMETHOD(SetOutputWidth)(
+        THIS_
+        _In_ ULONG Columns
+        ) PURE;
+    // Some of the engines output commands produce
+    // multiple lines of output.  A prefix can be
+    // set that the engine will automatically output
+    // for each line in that case, allowing a caller
+    // to control indentation or identifying marks.
+    // This is not a general setting for any output
+    // with a newline in it.  Methods which use
+    // the line prefix are marked in their documentation.
+    STDMETHOD(GetOutputLinePrefix)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR Prefix
+        ) PURE;
+
+    // Returns a string describing the machine
+    // and user this client represents.  The
+    // specific content of the string varies
+    // with operating system.  If the client is
+    // remotely connected some network information
+    // may also be present.
+    STDMETHOD(GetIdentity)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    // Format is a printf-like format string
+    // with one %s where the identity string should go.
+    STDMETHOD(OutputIdentity)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCSTR Format
+        ) PURE;
+
+    // Event callbacks allow a client to
+    // receive notification about changes
+    // during the debug session.
+    STDMETHOD(GetEventCallbacks)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_EVENT_CALLBACKS Callbacks
+        ) PURE;
+
+    // The engine sometimes merges compatible callback
+    // requests to reduce callback overhead.  This is
+    // most noticeable with output as small pieces of
+    // output are collected into larger groups to
+    // reduce the overall number of output callback calls.
+    // A client can use this method to force all pending
+    // callbacks to be delivered.  This is rarely necessary.
+    STDMETHOD(FlushCallbacks)(
+        THIS
+        ) PURE;
+
+    // IDebugClient2.
+
+    // Functions similarly to WriteDumpFile with
+    // the addition of the ability to specify
+    // per-dump-format write control flags.
+    // Comment is not supported in all formats.
+    STDMETHOD(WriteDumpFile2)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCSTR Comment
+        ) PURE;
+    // Registers additional files of supporting information
+    // for a dump file open.  This method must be called
+    // before OpenDumpFile is called.
+    // The files registered may be opened at the time
+    // this method is called but generally will not
+    // be used until OpenDumpFile is called.
+    STDMETHOD(AddDumpInformationFile)(
+        THIS_
+        _In_ PCSTR InfoFile,
+        _In_ ULONG Type
+        ) PURE;
+
+    // Requests that the remote process server shut down.
+    STDMETHOD(EndProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+    // Waits for a started process server to
+    // exit.  Allows an application running a
+    // process server to monitor the process
+    // server so that it can tell when a remote
+    // client has asked for it to exit.
+    // Returns S_OK if the process server has
+    // shut down and S_FALSE for a timeout.
+    STDMETHOD(WaitForProcessServerEnd)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Returns S_OK if the system is configured
+    // to allow kernel debugging.
+    STDMETHOD(IsKernelDebuggerEnabled)(
+        THIS
+        ) PURE;
+
+    // Attempts to terminate the current process.
+    // Exit process events for the process may be generated.
+    STDMETHOD(TerminateCurrentProcess)(
+        THIS
+        ) PURE;
+    // Attempts to detach from the current process.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachCurrentProcess)(
+        THIS
+        ) PURE;
+    // Removes the process from the debuggers process
+    // list without making any other changes.  The process
+    // will still be marked as being debugged and will
+    // not run.  This allows a debugger to be shut down
+    // and a new debugger attached without taking the
+    // process out of the debugged state.
+    // This is only supported on some system versions.
+    STDMETHOD(AbandonCurrentProcess)(
+        THIS
+        ) PURE;
+
+    // IDebugClient3.
+
+    STDMETHOD(GetRunningProcessSystemIdByExecutableNameWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescriptionWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PWSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PWSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    STDMETHOD(CreateProcessWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttachWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+
+    // IDebugClient4.
+
+    // In the following methods both a filename and a file
+    // handle can be passed in.  If a file handle is given
+    // the filename may be omitted, although providing it
+    // allows the debugger to properly report the name when
+    // queried.
+    // File handles cannot be used in remote calls.
+    STDMETHOD(OpenDumpFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle
+        ) PURE;
+    STDMETHOD(WriteDumpFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCWSTR Comment
+        ) PURE;
+    STDMETHOD(AddDumpInformationFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle,
+        _In_ ULONG Type
+        ) PURE;
+    // These methods can be used to retrieve
+    // file information for all targets that
+    // involve files.
+    STDMETHOD(GetNumberDumpFiles)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetDumpFile)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Handle,
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(GetDumpFileWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Handle,
+        _Out_ PULONG Type
+        ) PURE;
+
+    // IDebugClient5.
+
+    STDMETHOD(AttachKernelWide)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCWSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptionsWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    STDMETHOD(SetKernelConnectionOptionsWide)(
+        THIS_
+        _In_ PCWSTR Options
+        ) PURE;
+
+    STDMETHOD(StartProcessServerWide)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCWSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServerWide)(
+        THIS_
+        _In_ PCWSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+
+    STDMETHOD(StartServerWide)(
+        THIS_
+        _In_ PCWSTR Options
+        ) PURE;
+    STDMETHOD(OutputServersWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetOutputCallbacksWide)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS_WIDE* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacksWide)(
+        THIS_
+        _In_ PDEBUG_OUTPUT_CALLBACKS_WIDE Callbacks
+        ) PURE;
+    STDMETHOD(GetOutputLinePrefixWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefixWide)(
+        THIS_
+        _In_opt_ PCWSTR Prefix
+        ) PURE;
+
+    STDMETHOD(GetIdentityWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    STDMETHOD(OutputIdentityWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCWSTR Format
+        ) PURE;
+
+    STDMETHOD(GetEventCallbacksWide)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS_WIDE* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacksWide)(
+        THIS_
+        _In_ PDEBUG_EVENT_CALLBACKS_WIDE Callbacks
+        ) PURE;
+
+    STDMETHOD(CreateProcess2)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCSTR InitialDirectory,
+        _In_opt_ PCSTR Environment
+        ) PURE;
+    STDMETHOD(CreateProcess2Wide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PWSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCWSTR InitialDirectory,
+        _In_opt_ PCWSTR Environment
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttach2)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCSTR InitialDirectory,
+        _In_opt_ PCSTR Environment,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttach2Wide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PWSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCWSTR InitialDirectory,
+        _In_opt_ PCWSTR Environment,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+
+    // Helpers for saving and restoring the
+    // current output line prefix.
+    STDMETHOD(PushOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR NewPrefix,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(PushOutputLinePrefixWide)(
+        THIS_
+        _In_opt_ PCWSTR NewPrefix,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(PopOutputLinePrefix)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    // Queries to determine if any clients
+    // could potentially respond to the given callback.
+    STDMETHOD(GetNumberInputCallbacks)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+    STDMETHOD(GetNumberOutputCallbacks)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+    STDMETHOD(GetNumberEventCallbacks)(
+        THIS_
+        _In_ ULONG EventFlags,
+        _Out_ PULONG Count
+        ) PURE;
+
+    // Control over locking the session against
+    // undesired quits.  The quit lock string
+    // cannot be retrieved from a secure session.
+    STDMETHOD(GetQuitLockString)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(SetQuitLockString)(
+        THIS_
+        _In_ PCSTR String
+        ) PURE;
+    STDMETHOD(GetQuitLockStringWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(SetQuitLockStringWide)(
+        THIS_
+        _In_ PCWSTR String
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugClient6
+DECLARE_INTERFACE_(IDebugClient6, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugClient.
+
+    // The following set of methods start
+    // the different kinds of debuggees.
+
+    // Begins a debug session using the kernel
+    // debugging protocol.  This method selects
+    // the protocol as the debuggee communication
+    // mechanism but does not initiate the communication
+    // itself.
+    STDMETHOD(AttachKernel)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptions)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    // Updates the connection options for a live
+    // kernel connection.  This can only be used
+    // to modify parameters for the connection, not
+    // to switch to a completely different kind of
+    // connection.
+    // This method is reentrant.
+    STDMETHOD(SetKernelConnectionOptions)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+
+    // Starts a process server for remote
+    // user-mode process control.
+    // The local process server is server zero.
+    STDMETHOD(StartProcessServer)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServer)(
+        THIS_
+        _In_ PCSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+    STDMETHOD(DisconnectProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+
+    // Enumerates and describes processes
+    // accessible through the given process server.
+    STDMETHOD(GetRunningProcessSystemIds)(
+        THIS_
+        _In_ ULONG64 Server,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _In_ ULONG Count,
+        _Out_opt_ PULONG ActualCount
+        ) PURE;
+    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescription)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    // Attaches to a running user-mode process.
+    STDMETHOD(AttachProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Creates a new user-mode process for debugging.
+    // CreateFlags are as given to Win32s CreateProcess.
+    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
+    // must be specified.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    // Creates or attaches to a user-mode process, or both.
+    // If CommandLine is NULL this method operates as
+    // AttachProcess does.  If ProcessId is zero it
+    // operates as CreateProcess does.  If CommandLine is
+    // non-NULL and ProcessId is non-zero the method first
+    // starts a process with the given information but
+    // in a suspended state.  The engine then attaches to
+    // the indicated process.  Once the attach is successful
+    // the suspended process is resumed.  This provides
+    // synchronization between the new process and the
+    // attachment.
+    STDMETHOD(CreateProcessAndAttach)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Gets and sets process control flags.
+    STDMETHOD(GetProcessOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Opens any kind of user- or kernel-mode dump file
+    // and begins a debug session with the information
+    // contained within it.
+    STDMETHOD(OpenDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile
+        ) PURE;
+    // Writes a dump file from the current session information.
+    // The kind of dump file written is determined by the
+    // kind of session and the type qualifier given.
+    // For example, if the current session is a kernel
+    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
+    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
+    STDMETHOD(WriteDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier
+        ) PURE;
+
+    // Indicates that a remote client is ready to
+    // begin participating in the current session.
+    // HistoryLimit gives a character limit on
+    // the amount of output history to be sent.
+    STDMETHOD(ConnectSession)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG HistoryLimit
+        ) PURE;
+    // Indicates that the engine should start accepting
+    // remote connections. Options specifies connection types
+    // and their parameters.  Supported strings are:
+    //    npipe:Pipe=<Pipe name>
+    //    tcp:Port=<IP port>
+    STDMETHOD(StartServer)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+    // List the servers running on the given machine.
+    // Uses the line prefix.
+    STDMETHOD(OutputServers)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Attempts to terminate all processes in the debuggers list.
+    STDMETHOD(TerminateProcesses)(
+        THIS
+        ) PURE;
+    // Attempts to detach from all processes in the debuggers list.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachProcesses)(
+        THIS
+        ) PURE;
+    // Stops the current debug session.  If a process
+    // was created or attached an active EndSession can
+    // terminate or detach from it.
+    // If a kernel connection was opened it will be closed but the
+    // target machine is otherwise unaffected.
+    STDMETHOD(EndSession)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // If a process was started and ran to completion
+    // this method can be used to retrieve its exit code.
+    STDMETHOD(GetExitCode)(
+        THIS_
+        _Out_ PULONG Code
+        ) PURE;
+
+    // Client event callbacks are called on the thread
+    // of the client.  In order to give thread
+    // execution to the engine for callbacks all
+    // client threads should call DispatchCallbacks
+    // when they are idle.  Callbacks are only
+    // received when a thread calls DispatchCallbacks
+    // or WaitForEvent.  WaitForEvent can only be
+    // called by the thread that started the debug
+    // session so all other client threads should
+    // call DispatchCallbacks when possible.
+    // DispatchCallbacks returns when ExitDispatch is used
+    // to interrupt dispatch or when the timeout expires.
+    // DispatchCallbacks dispatches callbacks for all
+    // clients associated with the thread calling
+    // DispatchCallbacks.
+    // DispatchCallbacks returns S_FALSE when the
+    // timeout expires.
+    STDMETHOD(DispatchCallbacks)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+    // ExitDispatch can be used to interrupt callback
+    // dispatch when a client thread is needed by the
+    // client.  This method is reentrant and can
+    // be called from any thread.
+    STDMETHOD(ExitDispatch)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client
+        ) PURE;
+
+    // Clients are specific to the thread that
+    // created them.  Calls from other threads
+    // fail immediately.  The CreateClient method
+    // is a notable exception; it allows creation
+    // of a new client for a new thread.
+    STDMETHOD(CreateClient)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Client
+        ) PURE;
+
+    STDMETHOD(GetInputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_INPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetInputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_INPUT_CALLBACKS Callbacks
+        ) PURE;
+
+    // Output callback interfaces are described separately.
+    STDMETHOD(GetOutputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_OUTPUT_CALLBACKS Callbacks
+        ) PURE;
+    // Output flags provide control over
+    // the distribution of output among clients.
+    // Output masks select which output streams
+    // should be sent to the output callbacks.
+    // Only Output calls with a mask that
+    // contains one of the output mask bits
+    // will be sent to the output callbacks.
+    // These methods are reentrant.
+    // If such access is not synchronized
+    // disruptions in output may occur.
+    STDMETHOD(GetOutputMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOutputMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+    // These methods allow access to another clients
+    // output mask.  They are necessary for changing
+    // a clients output mask when it is
+    // waiting for events.  These methods are reentrant
+    // and can be called from any thread.
+    STDMETHOD(GetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _In_ ULONG Mask
+        ) PURE;
+    // Control the width of an output line for
+    // commands which produce formatted output.
+    // This setting is just a suggestion.
+    STDMETHOD(GetOutputWidth)(
+        THIS_
+        _Out_ PULONG Columns
+        ) PURE;
+    STDMETHOD(SetOutputWidth)(
+        THIS_
+        _In_ ULONG Columns
+        ) PURE;
+    // Some of the engines output commands produce
+    // multiple lines of output.  A prefix can be
+    // set that the engine will automatically output
+    // for each line in that case, allowing a caller
+    // to control indentation or identifying marks.
+    // This is not a general setting for any output
+    // with a newline in it.  Methods which use
+    // the line prefix are marked in their documentation.
+    STDMETHOD(GetOutputLinePrefix)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR Prefix
+        ) PURE;
+
+    // Returns a string describing the machine
+    // and user this client represents.  The
+    // specific content of the string varies
+    // with operating system.  If the client is
+    // remotely connected some network information
+    // may also be present.
+    STDMETHOD(GetIdentity)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    // Format is a printf-like format string
+    // with one %s where the identity string should go.
+    STDMETHOD(OutputIdentity)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCSTR Format
+        ) PURE;
+
+    // Event callbacks allow a client to
+    // receive notification about changes
+    // during the debug session.
+    STDMETHOD(GetEventCallbacks)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_EVENT_CALLBACKS Callbacks
+        ) PURE;
+
+    // The engine sometimes merges compatible callback
+    // requests to reduce callback overhead.  This is
+    // most noticeable with output as small pieces of
+    // output are collected into larger groups to
+    // reduce the overall number of output callback calls.
+    // A client can use this method to force all pending
+    // callbacks to be delivered.  This is rarely necessary.
+    STDMETHOD(FlushCallbacks)(
+        THIS
+        ) PURE;
+
+    // IDebugClient2.
+
+    // Functions similarly to WriteDumpFile with
+    // the addition of the ability to specify
+    // per-dump-format write control flags.
+    // Comment is not supported in all formats.
+    STDMETHOD(WriteDumpFile2)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCSTR Comment
+        ) PURE;
+    // Registers additional files of supporting information
+    // for a dump file open.  This method must be called
+    // before OpenDumpFile is called.
+    // The files registered may be opened at the time
+    // this method is called but generally will not
+    // be used until OpenDumpFile is called.
+    STDMETHOD(AddDumpInformationFile)(
+        THIS_
+        _In_ PCSTR InfoFile,
+        _In_ ULONG Type
+        ) PURE;
+
+    // Requests that the remote process server shut down.
+    STDMETHOD(EndProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+    // Waits for a started process server to
+    // exit.  Allows an application running a
+    // process server to monitor the process
+    // server so that it can tell when a remote
+    // client has asked for it to exit.
+    // Returns S_OK if the process server has
+    // shut down and S_FALSE for a timeout.
+    STDMETHOD(WaitForProcessServerEnd)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Returns S_OK if the system is configured
+    // to allow kernel debugging.
+    STDMETHOD(IsKernelDebuggerEnabled)(
+        THIS
+        ) PURE;
+
+    // Attempts to terminate the current process.
+    // Exit process events for the process may be generated.
+    STDMETHOD(TerminateCurrentProcess)(
+        THIS
+        ) PURE;
+    // Attempts to detach from the current process.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachCurrentProcess)(
+        THIS
+        ) PURE;
+    // Removes the process from the debuggers process
+    // list without making any other changes.  The process
+    // will still be marked as being debugged and will
+    // not run.  This allows a debugger to be shut down
+    // and a new debugger attached without taking the
+    // process out of the debugged state.
+    // This is only supported on some system versions.
+    STDMETHOD(AbandonCurrentProcess)(
+        THIS
+        ) PURE;
+
+    // IDebugClient3.
+
+    STDMETHOD(GetRunningProcessSystemIdByExecutableNameWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescriptionWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PWSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PWSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    STDMETHOD(CreateProcessWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttachWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+
+    // IDebugClient4.
+
+    // In the following methods both a filename and a file
+    // handle can be passed in.  If a file handle is given
+    // the filename may be omitted, although providing it
+    // allows the debugger to properly report the name when
+    // queried.
+    // File handles cannot be used in remote calls.
+    STDMETHOD(OpenDumpFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle
+        ) PURE;
+    STDMETHOD(WriteDumpFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCWSTR Comment
+        ) PURE;
+    STDMETHOD(AddDumpInformationFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle,
+        _In_ ULONG Type
+        ) PURE;
+    // These methods can be used to retrieve
+    // file information for all targets that
+    // involve files.
+    STDMETHOD(GetNumberDumpFiles)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetDumpFile)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Handle,
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(GetDumpFileWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Handle,
+        _Out_ PULONG Type
+        ) PURE;
+
+    // IDebugClient5.
+
+    STDMETHOD(AttachKernelWide)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCWSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptionsWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    STDMETHOD(SetKernelConnectionOptionsWide)(
+        THIS_
+        _In_ PCWSTR Options
+        ) PURE;
+
+    STDMETHOD(StartProcessServerWide)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCWSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServerWide)(
+        THIS_
+        _In_ PCWSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+
+    STDMETHOD(StartServerWide)(
+        THIS_
+        _In_ PCWSTR Options
+        ) PURE;
+    STDMETHOD(OutputServersWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetOutputCallbacksWide)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS_WIDE* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacksWide)(
+        THIS_
+        _In_ PDEBUG_OUTPUT_CALLBACKS_WIDE Callbacks
+        ) PURE;
+    STDMETHOD(GetOutputLinePrefixWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefixWide)(
+        THIS_
+        _In_opt_ PCWSTR Prefix
+        ) PURE;
+
+    STDMETHOD(GetIdentityWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    STDMETHOD(OutputIdentityWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCWSTR Format
+        ) PURE;
+
+    STDMETHOD(GetEventCallbacksWide)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS_WIDE* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacksWide)(
+        THIS_
+        _In_ PDEBUG_EVENT_CALLBACKS_WIDE Callbacks
+        ) PURE;
+
+    STDMETHOD(CreateProcess2)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCSTR InitialDirectory,
+        _In_opt_ PCSTR Environment
+        ) PURE;
+    STDMETHOD(CreateProcess2Wide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PWSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCWSTR InitialDirectory,
+        _In_opt_ PCWSTR Environment
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttach2)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCSTR InitialDirectory,
+        _In_opt_ PCSTR Environment,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttach2Wide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PWSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCWSTR InitialDirectory,
+        _In_opt_ PCWSTR Environment,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+
+    // Helpers for saving and restoring the
+    // current output line prefix.
+    STDMETHOD(PushOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR NewPrefix,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(PushOutputLinePrefixWide)(
+        THIS_
+        _In_opt_ PCWSTR NewPrefix,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(PopOutputLinePrefix)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    // Queries to determine if any clients
+    // could potentially respond to the given callback.
+    STDMETHOD(GetNumberInputCallbacks)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+    STDMETHOD(GetNumberOutputCallbacks)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+    STDMETHOD(GetNumberEventCallbacks)(
+        THIS_
+        _In_ ULONG EventFlags,
+        _Out_ PULONG Count
+        ) PURE;
+
+    // Control over locking the session against
+    // undesired quits.  The quit lock string
+    // cannot be retrieved from a secure session.
+    STDMETHOD(GetQuitLockString)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(SetQuitLockString)(
+        THIS_
+        _In_ PCSTR String
+        ) PURE;
+    STDMETHOD(GetQuitLockStringWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(SetQuitLockStringWide)(
+        THIS_
+        _In_ PCWSTR String
+        ) PURE;
+
+    // IDebugClient6
+
+    STDMETHOD(SetEventContextCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_EVENT_CONTEXT_CALLBACKS Callbacks
+        ) PURE;
+
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugClient7
+DECLARE_INTERFACE_(IDebugClient7, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugClient.
+
+    // The following set of methods start
+    // the different kinds of debuggees.
+
+    // Begins a debug session using the kernel
+    // debugging protocol.  This method selects
+    // the protocol as the debuggee communication
+    // mechanism but does not initiate the communication
+    // itself.
+    STDMETHOD(AttachKernel)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptions)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    // Updates the connection options for a live
+    // kernel connection.  This can only be used
+    // to modify parameters for the connection, not
+    // to switch to a completely different kind of
+    // connection.
+    // This method is reentrant.
+    STDMETHOD(SetKernelConnectionOptions)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+
+    // Starts a process server for remote
+    // user-mode process control.
+    // The local process server is server zero.
+    STDMETHOD(StartProcessServer)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServer)(
+        THIS_
+        _In_ PCSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+    STDMETHOD(DisconnectProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+
+    // Enumerates and describes processes
+    // accessible through the given process server.
+    STDMETHOD(GetRunningProcessSystemIds)(
+        THIS_
+        _In_ ULONG64 Server,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _In_ ULONG Count,
+        _Out_opt_ PULONG ActualCount
+        ) PURE;
+    STDMETHOD(GetRunningProcessSystemIdByExecutableName)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescription)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    // Attaches to a running user-mode process.
+    STDMETHOD(AttachProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Creates a new user-mode process for debugging.
+    // CreateFlags are as given to Win32s CreateProcess.
+    // One of DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS
+    // must be specified.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    // Creates or attaches to a user-mode process, or both.
+    // If CommandLine is NULL this method operates as
+    // AttachProcess does.  If ProcessId is zero it
+    // operates as CreateProcess does.  If CommandLine is
+    // non-NULL and ProcessId is non-zero the method first
+    // starts a process with the given information but
+    // in a suspended state.  The engine then attaches to
+    // the indicated process.  Once the attach is successful
+    // the suspended process is resumed.  This provides
+    // synchronization between the new process and the
+    // attachment.
+    STDMETHOD(CreateProcessAndAttach)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    // Gets and sets process control flags.
+    STDMETHOD(GetProcessOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetProcessOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Opens any kind of user- or kernel-mode dump file
+    // and begins a debug session with the information
+    // contained within it.
+    STDMETHOD(OpenDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile
+        ) PURE;
+    // Writes a dump file from the current session information.
+    // The kind of dump file written is determined by the
+    // kind of session and the type qualifier given.
+    // For example, if the current session is a kernel
+    // debug session (DEBUG_CLASS_KERNEL) and the qualifier
+    // is DEBUG_DUMP_SMALL a small kernel dump will be written.
+    STDMETHOD(WriteDumpFile)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier
+        ) PURE;
+
+    // Indicates that a remote client is ready to
+    // begin participating in the current session.
+    // HistoryLimit gives a character limit on
+    // the amount of output history to be sent.
+    STDMETHOD(ConnectSession)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG HistoryLimit
+        ) PURE;
+    // Indicates that the engine should start accepting
+    // remote connections. Options specifies connection types
+    // and their parameters.  Supported strings are:
+    //    npipe:Pipe=<Pipe name>
+    //    tcp:Port=<IP port>
+    STDMETHOD(StartServer)(
+        THIS_
+        _In_ PCSTR Options
+        ) PURE;
+    // List the servers running on the given machine.
+    // Uses the line prefix.
+    STDMETHOD(OutputServers)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Attempts to terminate all processes in the debuggers list.
+    STDMETHOD(TerminateProcesses)(
+        THIS
+        ) PURE;
+    // Attempts to detach from all processes in the debuggers list.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachProcesses)(
+        THIS
+        ) PURE;
+    // Stops the current debug session.  If a process
+    // was created or attached an active EndSession can
+    // terminate or detach from it.
+    // If a kernel connection was opened it will be closed but the
+    // target machine is otherwise unaffected.
+    STDMETHOD(EndSession)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // If a process was started and ran to completion
+    // this method can be used to retrieve its exit code.
+    STDMETHOD(GetExitCode)(
+        THIS_
+        _Out_ PULONG Code
+        ) PURE;
+
+    // Client event callbacks are called on the thread
+    // of the client.  In order to give thread
+    // execution to the engine for callbacks all
+    // client threads should call DispatchCallbacks
+    // when they are idle.  Callbacks are only
+    // received when a thread calls DispatchCallbacks
+    // or WaitForEvent.  WaitForEvent can only be
+    // called by the thread that started the debug
+    // session so all other client threads should
+    // call DispatchCallbacks when possible.
+    // DispatchCallbacks returns when ExitDispatch is used
+    // to interrupt dispatch or when the timeout expires.
+    // DispatchCallbacks dispatches callbacks for all
+    // clients associated with the thread calling
+    // DispatchCallbacks.
+    // DispatchCallbacks returns S_FALSE when the
+    // timeout expires.
+    STDMETHOD(DispatchCallbacks)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+    // ExitDispatch can be used to interrupt callback
+    // dispatch when a client thread is needed by the
+    // client.  This method is reentrant and can
+    // be called from any thread.
+    STDMETHOD(ExitDispatch)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client
+        ) PURE;
+
+    // Clients are specific to the thread that
+    // created them.  Calls from other threads
+    // fail immediately.  The CreateClient method
+    // is a notable exception; it allows creation
+    // of a new client for a new thread.
+    STDMETHOD(CreateClient)(
+        THIS_
+        _Out_ PDEBUG_CLIENT* Client
+        ) PURE;
+
+    STDMETHOD(GetInputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_INPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetInputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_INPUT_CALLBACKS Callbacks
+        ) PURE;
+
+    // Output callback interfaces are described separately.
+    STDMETHOD(GetOutputCallbacks)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_OUTPUT_CALLBACKS Callbacks
+        ) PURE;
+    // Output flags provide control over
+    // the distribution of output among clients.
+    // Output masks select which output streams
+    // should be sent to the output callbacks.
+    // Only Output calls with a mask that
+    // contains one of the output mask bits
+    // will be sent to the output callbacks.
+    // These methods are reentrant.
+    // If such access is not synchronized
+    // disruptions in output may occur.
+    STDMETHOD(GetOutputMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOutputMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+    // These methods allow access to another clients
+    // output mask.  They are necessary for changing
+    // a clients output mask when it is
+    // waiting for events.  These methods are reentrant
+    // and can be called from any thread.
+    STDMETHOD(GetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetOtherOutputMask)(
+        THIS_
+        _In_ PDEBUG_CLIENT Client,
+        _In_ ULONG Mask
+        ) PURE;
+    // Control the width of an output line for
+    // commands which produce formatted output.
+    // This setting is just a suggestion.
+    STDMETHOD(GetOutputWidth)(
+        THIS_
+        _Out_ PULONG Columns
+        ) PURE;
+    STDMETHOD(SetOutputWidth)(
+        THIS_
+        _In_ ULONG Columns
+        ) PURE;
+    // Some of the engines output commands produce
+    // multiple lines of output.  A prefix can be
+    // set that the engine will automatically output
+    // for each line in that case, allowing a caller
+    // to control indentation or identifying marks.
+    // This is not a general setting for any output
+    // with a newline in it.  Methods which use
+    // the line prefix are marked in their documentation.
+    STDMETHOD(GetOutputLinePrefix)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR Prefix
+        ) PURE;
+
+    // Returns a string describing the machine
+    // and user this client represents.  The
+    // specific content of the string varies
+    // with operating system.  If the client is
+    // remotely connected some network information
+    // may also be present.
+    STDMETHOD(GetIdentity)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    // Format is a printf-like format string
+    // with one %s where the identity string should go.
+    STDMETHOD(OutputIdentity)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCSTR Format
+        ) PURE;
+
+    // Event callbacks allow a client to
+    // receive notification about changes
+    // during the debug session.
+    STDMETHOD(GetEventCallbacks)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_EVENT_CALLBACKS Callbacks
+        ) PURE;
+
+    // The engine sometimes merges compatible callback
+    // requests to reduce callback overhead.  This is
+    // most noticeable with output as small pieces of
+    // output are collected into larger groups to
+    // reduce the overall number of output callback calls.
+    // A client can use this method to force all pending
+    // callbacks to be delivered.  This is rarely necessary.
+    STDMETHOD(FlushCallbacks)(
+        THIS
+        ) PURE;
+
+    // IDebugClient2.
+
+    // Functions similarly to WriteDumpFile with
+    // the addition of the ability to specify
+    // per-dump-format write control flags.
+    // Comment is not supported in all formats.
+    STDMETHOD(WriteDumpFile2)(
+        THIS_
+        _In_ PCSTR DumpFile,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCSTR Comment
+        ) PURE;
+    // Registers additional files of supporting information
+    // for a dump file open.  This method must be called
+    // before OpenDumpFile is called.
+    // The files registered may be opened at the time
+    // this method is called but generally will not
+    // be used until OpenDumpFile is called.
+    STDMETHOD(AddDumpInformationFile)(
+        THIS_
+        _In_ PCSTR InfoFile,
+        _In_ ULONG Type
+        ) PURE;
+
+    // Requests that the remote process server shut down.
+    STDMETHOD(EndProcessServer)(
+        THIS_
+        _In_ ULONG64 Server
+        ) PURE;
+    // Waits for a started process server to
+    // exit.  Allows an application running a
+    // process server to monitor the process
+    // server so that it can tell when a remote
+    // client has asked for it to exit.
+    // Returns S_OK if the process server has
+    // shut down and S_FALSE for a timeout.
+    STDMETHOD(WaitForProcessServerEnd)(
+        THIS_
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Returns S_OK if the system is configured
+    // to allow kernel debugging.
+    STDMETHOD(IsKernelDebuggerEnabled)(
+        THIS
+        ) PURE;
+
+    // Attempts to terminate the current process.
+    // Exit process events for the process may be generated.
+    STDMETHOD(TerminateCurrentProcess)(
+        THIS
+        ) PURE;
+    // Attempts to detach from the current process.
+    // This requires OS support for debugger detach.
+    STDMETHOD(DetachCurrentProcess)(
+        THIS
+        ) PURE;
+    // Removes the process from the debuggers process
+    // list without making any other changes.  The process
+    // will still be marked as being debugged and will
+    // not run.  This allows a debugger to be shut down
+    // and a new debugger attached without taking the
+    // process out of the debugged state.
+    // This is only supported on some system versions.
+    STDMETHOD(AbandonCurrentProcess)(
+        THIS
+        ) PURE;
+
+    // IDebugClient3.
+
+    STDMETHOD(GetRunningProcessSystemIdByExecutableNameWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR ExeName,
+        _In_ ULONG Flags,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetRunningProcessDescriptionWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG SystemId,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(ExeNameSize) PWSTR ExeName,
+        _In_ ULONG ExeNameSize,
+        _Out_opt_ PULONG ActualExeNameSize,
+        _Out_writes_opt_(DescriptionSize) PWSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG ActualDescriptionSize
+        ) PURE;
+
+    STDMETHOD(CreateProcessWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttachWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PWSTR CommandLine,
+        _In_ ULONG CreateFlags,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+
+    // IDebugClient4.
+
+    // In the following methods both a filename and a file
+    // handle can be passed in.  If a file handle is given
+    // the filename may be omitted, although providing it
+    // allows the debugger to properly report the name when
+    // queried.
+    // File handles cannot be used in remote calls.
+    STDMETHOD(OpenDumpFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle
+        ) PURE;
+    STDMETHOD(WriteDumpFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle,
+        _In_ ULONG Qualifier,
+        _In_ ULONG FormatFlags,
+        _In_opt_ PCWSTR Comment
+        ) PURE;
+    STDMETHOD(AddDumpInformationFileWide)(
+        THIS_
+        _In_opt_ PCWSTR FileName,
+        _In_ ULONG64 FileHandle,
+        _In_ ULONG Type
+        ) PURE;
+    // These methods can be used to retrieve
+    // file information for all targets that
+    // involve files.
+    STDMETHOD(GetNumberDumpFiles)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetDumpFile)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Handle,
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(GetDumpFileWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Handle,
+        _Out_ PULONG Type
+        ) PURE;
+
+    // IDebugClient5.
+
+    STDMETHOD(AttachKernelWide)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PCWSTR ConnectOptions
+        ) PURE;
+    STDMETHOD(GetKernelConnectionOptionsWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG OptionsSize
+        ) PURE;
+    STDMETHOD(SetKernelConnectionOptionsWide)(
+        THIS_
+        _In_ PCWSTR Options
+        ) PURE;
+
+    STDMETHOD(StartProcessServerWide)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ PCWSTR Options,
+        _In_opt_ _Reserved_ PVOID Reserved
+        ) PURE;
+    STDMETHOD(ConnectProcessServerWide)(
+        THIS_
+        _In_ PCWSTR RemoteOptions,
+        _Out_ PULONG64 Server
+        ) PURE;
+
+    STDMETHOD(StartServerWide)(
+        THIS_
+        _In_ PCWSTR Options
+        ) PURE;
+    STDMETHOD(OutputServersWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR Machine,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetOutputCallbacksWide)(
+        THIS_
+        _Out_ PDEBUG_OUTPUT_CALLBACKS_WIDE* Callbacks
+        ) PURE;
+    STDMETHOD(SetOutputCallbacksWide)(
+        THIS_
+        _In_ PDEBUG_OUTPUT_CALLBACKS_WIDE Callbacks
+        ) PURE;
+    STDMETHOD(GetOutputLinePrefixWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PrefixSize
+        ) PURE;
+    STDMETHOD(SetOutputLinePrefixWide)(
+        THIS_
+        _In_opt_ PCWSTR Prefix
+        ) PURE;
+
+    STDMETHOD(GetIdentityWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG IdentitySize
+        ) PURE;
+    STDMETHOD(OutputIdentityWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ PCWSTR Format
+        ) PURE;
+
+    STDMETHOD(GetEventCallbacksWide)(
+        THIS_
+        _Out_ PDEBUG_EVENT_CALLBACKS_WIDE* Callbacks
+        ) PURE;
+    STDMETHOD(SetEventCallbacksWide)(
+        THIS_
+        _In_ PDEBUG_EVENT_CALLBACKS_WIDE Callbacks
+        ) PURE;
+
+    STDMETHOD(CreateProcess2)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCSTR InitialDirectory,
+        _In_opt_ PCSTR Environment
+        ) PURE;
+    STDMETHOD(CreateProcess2Wide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PWSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCWSTR InitialDirectory,
+        _In_opt_ PCWSTR Environment
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttach2)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCSTR InitialDirectory,
+        _In_opt_ PCSTR Environment,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+    STDMETHOD(CreateProcessAndAttach2Wide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_opt_ PWSTR CommandLine,
+        _In_reads_bytes_(OptionsBufferSize) PVOID OptionsBuffer,
+        _In_ ULONG OptionsBufferSize,
+        _In_opt_ PCWSTR InitialDirectory,
+        _In_opt_ PCWSTR Environment,
+        _In_ ULONG ProcessId,
+        _In_ ULONG AttachFlags
+        ) PURE;
+
+    // Helpers for saving and restoring the
+    // current output line prefix.
+    STDMETHOD(PushOutputLinePrefix)(
+        THIS_
+        _In_opt_ PCSTR NewPrefix,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(PushOutputLinePrefixWide)(
+        THIS_
+        _In_opt_ PCWSTR NewPrefix,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(PopOutputLinePrefix)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    // Queries to determine if any clients
+    // could potentially respond to the given callback.
+    STDMETHOD(GetNumberInputCallbacks)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+    STDMETHOD(GetNumberOutputCallbacks)(
+        THIS_
+        _Out_ PULONG Count
+        ) PURE;
+    STDMETHOD(GetNumberEventCallbacks)(
+        THIS_
+        _In_ ULONG EventFlags,
+        _Out_ PULONG Count
+        ) PURE;
+
+    // Control over locking the session against
+    // undesired quits.  The quit lock string
+    // cannot be retrieved from a secure session.
+    STDMETHOD(GetQuitLockString)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(SetQuitLockString)(
+        THIS_
+        _In_ PCSTR String
+        ) PURE;
+    STDMETHOD(GetQuitLockStringWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(SetQuitLockStringWide)(
+        THIS_
+        _In_ PCWSTR String
+        ) PURE;
+
+    // IDebugClient6
+
+    STDMETHOD(SetEventContextCallbacks)(
+        THIS_
+        _In_opt_ PDEBUG_EVENT_CONTEXT_CALLBACKS Callbacks
+        ) PURE;
+
+    // IDebugClient7
+
+    STDMETHOD(SetClientContext)(
+        THIS_
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugPlmClient
+DECLARE_INTERFACE_(IDebugPlmClient, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugPlmClient
+
+    // Launches suspended Plm Application
+    STDMETHOD(LaunchPlmPackageForDebugWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG Timeout,
+        _In_ PCWSTR PackageFullName,
+        _In_ PCWSTR AppName,
+        _In_opt_ PCWSTR Arguments,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugPlmClient2
+DECLARE_INTERFACE_(IDebugPlmClient2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugPlmClient
+
+    // Launches suspended Plm Application
+    STDMETHOD(LaunchPlmPackageForDebugWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG Timeout,
+        _In_ PCWSTR PackageFullName,
+        _In_ PCWSTR AppName,
+        _In_opt_ PCWSTR Arguments,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId
+        ) PURE;
+
+    // IDebugPlmClient2
+
+     // Launches suspended Plm Bg Task
+    STDMETHOD(LaunchPlmBgTaskForDebugWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG Timeout,
+        _In_ PCWSTR PackageFullName,
+        _In_ PCWSTR BackgroundTaskId,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugPlmClient3
+DECLARE_INTERFACE_(IDebugPlmClient3, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugPlmClient
+
+    // Launches suspended Plm Application
+    STDMETHOD(LaunchPlmPackageForDebugWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG Timeout,
+        _In_ PCWSTR PackageFullName,
+        _In_ PCWSTR AppName,
+        _In_opt_ PCWSTR Arguments,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId
+        ) PURE;
+
+    // IDebugPlmClient2
+
+     // Launches suspended Plm Bg Task
+    STDMETHOD(LaunchPlmBgTaskForDebugWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ ULONG Timeout,
+        _In_ PCWSTR PackageFullName,
+        _In_ PCWSTR BackgroundTaskId,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId
+        ) PURE;
+
+    // IDebugPlmClient3
+
+    STDMETHOD(QueryPlmPackageWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR PackageFullName,
+        _In_ PDEBUG_OUTPUT_STREAM Stream
+        ) PURE;
+
+    STDMETHOD(QueryPlmPackageList)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PDEBUG_OUTPUT_STREAM Stream
+        ) PURE;
+
+    STDMETHOD(EnablePlmPackageDebugWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR PackageFullName
+        ) PURE;
+
+    STDMETHOD(DisablePlmPackageDebugWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR PackageFullName
+        ) PURE;
+
+    STDMETHOD(SuspendPlmPackageWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR PackageFullName
+        ) PURE;
+
+    STDMETHOD(ResumePlmPackageWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR PackageFullName
+        ) PURE;
+
+    STDMETHOD(TerminatePlmPackageWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR PackageFullName
+        ) PURE;
+
+    // Launches and attaches to Plm Application. Starts debugger session
+    // if it is not already started
+    STDMETHOD(LaunchAndDebugPlmAppWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR PackageFullName,
+        _In_ PCWSTR AppName,
+        _In_ PCWSTR Arguments
+        ) PURE;
+
+    // Launches and attaches to Plm Bg Task. Starts debugger session
+    // if it is not already started
+    STDMETHOD(ActivateAndDebugPlmBgTaskWide)(
+        THIS_
+        _In_ ULONG64 Server,
+        _In_ PCWSTR PackageFullName,
+        _In_ PCWSTR BackgroundTaskId
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugOutputStream
+DECLARE_INTERFACE_(IDebugOutputStream, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        __in REFIID InterfaceId,
+        __out PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugOutputStream.
+    STDMETHOD(Write)(
+        THIS_
+        _In_ PCWSTR psz
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugControl.
+//
+//----------------------------------------------------------------------------
+
+// Execution status codes used for waiting,
+// for returning current status and for
+// event method return values.
+#define DEBUG_STATUS_NO_CHANGE           0
+#define DEBUG_STATUS_GO                  1
+#define DEBUG_STATUS_GO_HANDLED          2
+#define DEBUG_STATUS_GO_NOT_HANDLED      3
+#define DEBUG_STATUS_STEP_OVER           4
+#define DEBUG_STATUS_STEP_INTO           5
+#define DEBUG_STATUS_BREAK               6
+#define DEBUG_STATUS_NO_DEBUGGEE         7
+#define DEBUG_STATUS_STEP_BRANCH         8
+#define DEBUG_STATUS_IGNORE_EVENT        9
+#define DEBUG_STATUS_RESTART_REQUESTED   10
+#define DEBUG_STATUS_REVERSE_GO          11
+#define DEBUG_STATUS_REVERSE_STEP_BRANCH 12
+#define DEBUG_STATUS_REVERSE_STEP_OVER   13
+#define DEBUG_STATUS_REVERSE_STEP_INTO   14
+#define DEBUG_STATUS_OUT_OF_SYNC                15
+#define DEBUG_STATUS_WAIT_INPUT                         16
+#define DEBUG_STATUS_TIMEOUT             17
+
+#define DEBUG_STATUS_MASK                0x1f
+
+// This bit is added in DEBUG_CES_EXECUTION_STATUS
+// notifications when the engines execution status
+// is changing due to operations performed during
+// a wait, such as making synchronous callbacks.  If
+// the bit is not set the execution status is changing
+// due to a wait being satisfied.
+#define DEBUG_STATUS_INSIDE_WAIT  0x100000000
+// This bit is added in DEBUG_CES_EXECUTION_STATUS
+// notifications when the engines execution status
+// update is coming after a wait has timed-out.
+// It indicates that the execution status change
+// was not due to an actual event.
+#define DEBUG_STATUS_WAIT_TIMEOUT 0x200000000
+
+// Output control flags.
+// Output generated by methods called by this
+// client will be sent only to this clients
+// output callbacks.
+#define DEBUG_OUTCTL_THIS_CLIENT       0x00000000
+// Output will be sent to all clients.
+#define DEBUG_OUTCTL_ALL_CLIENTS       0x00000001
+// Output will be sent to all clients except
+// the client generating the output.
+#define DEBUG_OUTCTL_ALL_OTHER_CLIENTS 0x00000002
+// Output will be discarded immediately and will not
+// be logged or sent to callbacks.
+#define DEBUG_OUTCTL_IGNORE            0x00000003
+// Output will be logged but not sent to callbacks.
+#define DEBUG_OUTCTL_LOG_ONLY          0x00000004
+// All send control bits.
+#define DEBUG_OUTCTL_SEND_MASK         0x00000007
+// Do not place output from this client in
+// the global log file.
+#define DEBUG_OUTCTL_NOT_LOGGED        0x00000008
+// Send output to clients regardless of whether the
+// mask allows it or not.
+#define DEBUG_OUTCTL_OVERRIDE_MASK     0x00000010
+// Text is markup instead of plain text.
+#define DEBUG_OUTCTL_DML               0x00000020
+
+// Special values which mean leave the output settings
+// unchanged.
+#define DEBUG_OUTCTL_AMBIENT_DML       0xfffffffe
+#define DEBUG_OUTCTL_AMBIENT_TEXT      0xffffffff
+
+// Old ambient flag which maps to text.
+#define DEBUG_OUTCTL_AMBIENT           DEBUG_OUTCTL_AMBIENT_TEXT
+
+// Interrupt types.
+// Force a break in if the debuggee is running.
+#define DEBUG_INTERRUPT_ACTIVE  0
+// Notify but do not force a break in.
+#define DEBUG_INTERRUPT_PASSIVE 1
+// Try and get the current engine operation to
+// complete so that the engine will be available
+// again.  If no wait is active this is the same
+// as a passive interrupt.  If a wait is active
+// this will try to cause the wait to fail without
+// breaking in to the debuggee.  There is
+// no guarantee that issuing an exit interrupt
+// will cause the engine to become available
+// as not all operations are arbitrarily
+// interruptible.
+#define DEBUG_INTERRUPT_EXIT    2
+
+// OutputCurrentState flags.  These flags
+// allow a particular type of information
+// to be displayed but do not guarantee
+// that it will be displayed.  Other global
+// settings may override these flags or
+// the particular state may not be available.
+// For example, source line information may
+// not be present so source line information
+// may not be displayed.
+#define DEBUG_CURRENT_DEFAULT     0x0000000f
+#define DEBUG_CURRENT_SYMBOL      0x00000001
+#define DEBUG_CURRENT_DISASM      0x00000002
+#define DEBUG_CURRENT_REGISTERS   0x00000004
+#define DEBUG_CURRENT_SOURCE_LINE 0x00000008
+
+//
+// Disassemble flags.
+//
+
+// Compute the effective address from current register
+// information and display it.
+#define DEBUG_DISASM_EFFECTIVE_ADDRESS  0x00000001
+// If the current disassembly offset has an exact
+// symbol match output the symbol.
+#define DEBUG_DISASM_MATCHING_SYMBOLS   0x00000002
+// Output the source line number for each disassembly offset.
+#define DEBUG_DISASM_SOURCE_LINE_NUMBER 0x00000004
+// Output the source file name (no path) for each disassembly offset.
+#define DEBUG_DISASM_SOURCE_FILE_NAME   0x00000008
+
+// Code interpretation levels for stepping
+// and other operations.
+#define DEBUG_LEVEL_SOURCE   0
+#define DEBUG_LEVEL_ASSEMBLY 1
+
+// Engine control flags.
+#define DEBUG_ENGOPT_IGNORE_DBGHELP_VERSION      0x00000001
+#define DEBUG_ENGOPT_IGNORE_EXTENSION_VERSIONS   0x00000002
+// If neither allow nor disallow is specified
+// the engine will pick one based on what kind
+// of debugging is going on.
+#define DEBUG_ENGOPT_ALLOW_NETWORK_PATHS         0x00000004
+#define DEBUG_ENGOPT_DISALLOW_NETWORK_PATHS      0x00000008
+#define DEBUG_ENGOPT_NETWORK_PATHS               (0x00000004 | 0x00000008)
+// Ignore loader-generated first-chance exceptions.
+#define DEBUG_ENGOPT_IGNORE_LOADER_EXCEPTIONS    0x00000010
+// Break in on a debuggees initial event.  In user-mode
+// this will break at the initial system breakpoint
+// for every created process.  In kernel-mode it
+// will attempt break in on the target at the first
+// WaitForEvent.
+#define DEBUG_ENGOPT_INITIAL_BREAK               0x00000020
+// Break in on the first module load for a debuggee.
+#define DEBUG_ENGOPT_INITIAL_MODULE_BREAK        0x00000040
+// Break in on a debuggees final event.  In user-mode
+// this will break on process exit for every process.
+// In kernel-mode it currently does nothing.
+#define DEBUG_ENGOPT_FINAL_BREAK                 0x00000080
+// By default Execute will repeat the last command
+// if it is given an empty string.  The flags to
+// Execute can override this behavior for a single
+// command or this engine option can be used to
+// change the default globally.
+#define DEBUG_ENGOPT_NO_EXECUTE_REPEAT           0x00000100
+// Disable places in the engine that have fallback
+// code when presented with incomplete information.
+//   1. Fails minidump module loads unless matching
+//      executables can be mapped.
+#define DEBUG_ENGOPT_FAIL_INCOMPLETE_INFORMATION 0x00000200
+// Allow the debugger to manipulate page protections
+// in order to insert code breakpoints on pages that
+// do not have write access.  This option is not on
+// by default as it allows breakpoints to be set
+// in potentially hazardous memory areas.
+#define DEBUG_ENGOPT_ALLOW_READ_ONLY_BREAKPOINTS 0x00000400
+// When using a software (bp/bu) breakpoint in code
+// that will be executed by multiple threads it is
+// possible for breakpoint management to cause the
+// breakpoint to be missed or for spurious single-step
+// exceptions to be generated.  This flag suspends
+// all but the active thread when doing breakpoint
+// management and thereby avoids multithreading
+// problems.  Care must be taken when using it, though,
+// as the suspension of threads can cause deadlocks
+// if the suspended threads are holding resources that
+// the active thread needs.  Additionally, there
+// are still rare situations where problems may
+// occur, but setting this flag corrects nearly
+// all multithreading issues with software breakpoints.
+// Thread-restricted stepping and execution supersedes
+// this flags effect.
+// This flag is ignored in kernel sessions as there
+// is no way to restrict processor execution.
+#define DEBUG_ENGOPT_SYNCHRONIZE_BREAKPOINTS     0x00000800
+// Disallows executing shell commands through the
+// engine with .shell (!!).
+#define DEBUG_ENGOPT_DISALLOW_SHELL_COMMANDS     0x00001000
+// Turns on "quiet mode", a somewhat less verbose mode
+// of operation supported in the debuggers that were
+// superseded by dbgeng.dll.  This equates to the KDQUIET
+// environment variable.
+#define DEBUG_ENGOPT_KD_QUIET_MODE               0x00002000
+// Disables managed code debugging support in the engine.
+// If managed support is already in use this flag has no effect.
+#define DEBUG_ENGOPT_DISABLE_MANAGED_SUPPORT     0x00004000
+// Disables symbol loading for all modules created
+// after this flag is set.
+#define DEBUG_ENGOPT_DISABLE_MODULE_SYMBOL_LOAD  0x00008000
+// Disables execution commands.
+#define DEBUG_ENGOPT_DISABLE_EXECUTION_COMMANDS  0x00010000
+// Disallows mapping of image files from disk for any use.
+// For example, this disallows image mapping for memory
+// content when debugging minidumps.
+// Does not affect existing mappings, only future attempts.
+#define DEBUG_ENGOPT_DISALLOW_IMAGE_FILE_MAPPING 0x00020000
+// Requests that dbgeng run DML-enhanced versions of commands
+// and operations by default.
+#define DEBUG_ENGOPT_PREFER_DML                  0x00040000
+// Explicitly disable SQM upload.
+#define DEBUG_ENGOPT_DISABLESQM                  0x00080000
+// This is used to disable the source stepping (step over/step in) into CFG code.
+#define DEBUG_ENGOPT_DISABLE_STEPLINES_OPTIONS   0x00200000
+// This is used when debugging target with sensitive data.
+// It will disable saving dumps during debugging
+// Can be set only (no reset once it is set)
+#define DEBUG_ENGOPT_DEBUGGING_SENSITIVE_DATA    0x00400000
+// When opening .cab or .zip files, if there is a trace (.run file), open
+// it instead of any other dump files in the archive.
+#define DEBUG_ENGOPT_PREFER_TRACE_FILES          0x00800000
+#define DEBUG_ENGOPT_ALL                         0x00EFFFFF
+
+// General unspecified ID constant.
+#define DEBUG_ANY_ID 0xffffffff
+
+typedef struct _DEBUG_STACK_FRAME
+{
+    ULONG64 InstructionOffset;
+    ULONG64 ReturnOffset;
+    ULONG64 FrameOffset;
+    ULONG64 StackOffset;
+    ULONG64 FuncTableEntry;
+    ULONG64 Params[4];
+    ULONG64 Reserved[6];
+    BOOL    Virtual;
+    ULONG   FrameNumber;
+} DEBUG_STACK_FRAME, *PDEBUG_STACK_FRAME;
+
+#define DBG_FRAME_DEFAULT                0 // the same as INLINE_FRAME_CONTEXT_INIT in dbghelp.h
+#define DBG_FRAME_IGNORE_INLINE 0xFFFFFFFF // the same as INLINE_FRAME_CONTEXT_IGNORE in dbghelp.h
+
+typedef struct _DEBUG_STACK_FRAME_EX
+{
+    // First DEBUG_STACK_FRAME structure
+    ULONG64 InstructionOffset;
+    ULONG64 ReturnOffset;
+    ULONG64 FrameOffset;
+    ULONG64 StackOffset;
+    ULONG64 FuncTableEntry;
+    ULONG64 Params[4];
+    ULONG64 Reserved[6];
+    BOOL    Virtual;
+    ULONG   FrameNumber;
+
+    // Extended DEBUG_STACK_FRAME fields.
+    ULONG InlineFrameContext;
+    ULONG Reserved1; // For alignment purpose.
+} DEBUG_STACK_FRAME_EX, *PDEBUG_STACK_FRAME_EX;
+
+// The types of inline frame context.
+#define STACK_FRAME_TYPE_INIT   0x00
+#define STACK_FRAME_TYPE_STACK  0x01
+#define STACK_FRAME_TYPE_INLINE 0x02
+#define STACK_FRAME_TYPE_RA     0x80 // Whether the instruction pointer is the current IP or a RA from callee frame.
+#define STACK_FRAME_TYPE_IGNORE 0xFF
+
+#pragma warning(push)
+#pragma warning(disable:4201) // nonstandard extension used : nameless struct
+
+typedef union _INLINE_FRAME_CONTEXT {
+    DWORD ContextValue;
+    struct {
+        BYTE FrameId;
+        BYTE FrameType;
+        WORD FrameSignature;
+    };
+} INLINE_FRAME_CONTEXT;
+
+#pragma warning(pop)
+
+typedef struct _STACK_SRC_INFO
+{
+    PCWSTR ImagePath;
+    PCWSTR ModuleName;
+    PCWSTR Function;
+    ULONG Displacement;
+    ULONG Row;
+    ULONG Column;
+} STACK_SRC_INFO, *PSTACK_SRC_INFO;
+
+typedef struct _STACK_SYM_FRAME_INFO
+{
+    DEBUG_STACK_FRAME_EX StackFrameEx;
+    STACK_SRC_INFO       SrcInfo;
+} STACK_SYM_FRAME_INFO, *PSTACK_SYM_FRAME_INFO;
+
+// OutputStackTrace flags.
+// Display a small number of arguments for each call.
+// These may or may not be the actual arguments depending
+// on the architecture, particular function and
+// point during the execution of the function.
+// If the current code level is assembly arguments
+// are dumped as hex values.  If the code level is
+// source the engine attempts to provide symbolic
+// argument information.
+#define DEBUG_STACK_ARGUMENTS               0x00000001
+// Displays information about the functions
+// frame such as __stdcall arguments, FPO
+// information and whatever else is available.
+#define DEBUG_STACK_FUNCTION_INFO           0x00000002
+// Displays source line information for each
+// frame of the stack trace.
+#define DEBUG_STACK_SOURCE_LINE             0x00000004
+// Show return, previous frame and other relevant address
+// values for each frame.
+#define DEBUG_STACK_FRAME_ADDRESSES         0x00000008
+// Show column names.
+#define DEBUG_STACK_COLUMN_NAMES            0x00000010
+// Show non-volatile register context for each
+// frame.  This is only meaningful for some platforms.
+#define DEBUG_STACK_NONVOLATILE_REGISTERS   0x00000020
+// Show frame numbers
+#define DEBUG_STACK_FRAME_NUMBERS           0x00000040
+// Show typed source parameters.
+#define DEBUG_STACK_PARAMETERS              0x00000080
+// Show just return address in stack frame addresses.
+#define DEBUG_STACK_FRAME_ADDRESSES_RA_ONLY 0x00000100
+// Show frame-to-frame memory usage.
+#define DEBUG_STACK_FRAME_MEMORY_USAGE      0x00000200
+// Show typed source parameters one to a line.
+#define DEBUG_STACK_PARAMETERS_NEWLINE      0x00000400
+// Produce stack output enhanced with DML content.
+#define DEBUG_STACK_DML                     0x00000800
+// Show offset from stack frame
+#define DEBUG_STACK_FRAME_OFFSETS           0x00001000
+// The stack trace information is from a stack provider
+#define DEBUG_STACK_PROVIDER                0x00002000
+// The architecture of the frame (for mixed architecture stacks)
+#define DEBUG_STACK_FRAME_ARCH              0x00004000
+
+// Classes of debuggee.  Each class
+// has different qualifiers for specific
+// kinds of debuggees.
+#define DEBUG_CLASS_UNINITIALIZED 0
+#define DEBUG_CLASS_KERNEL        1
+#define DEBUG_CLASS_USER_WINDOWS  2
+#define DEBUG_CLASS_IMAGE_FILE    3
+
+// Generic dump types.  These can be used
+// with either user or kernel sessions.
+// Session-type-specific aliases are also
+// provided.
+#define DEBUG_DUMP_SMALL      1024
+#define DEBUG_DUMP_DEFAULT    1025
+#define DEBUG_DUMP_FULL       1026
+#define DEBUG_DUMP_IMAGE_FILE 1027
+#define DEBUG_DUMP_TRACE_LOG  1028
+#define DEBUG_DUMP_WINDOWS_CE 1029
+#define DEBUG_DUMP_ACTIVE     1030
+
+// Specific types of kernel debuggees.
+#define DEBUG_KERNEL_CONNECTION     0
+#define DEBUG_KERNEL_LOCAL          1
+#define DEBUG_KERNEL_EXDI_DRIVER    2
+#define DEBUG_KERNEL_IDNA           3
+#define DEBUG_KERNEL_INSTALL_DRIVER 4
+#define DEBUG_KERNEL_REPT           5
+
+#define DEBUG_KERNEL_SMALL_DUMP  DEBUG_DUMP_SMALL
+#define DEBUG_KERNEL_DUMP        DEBUG_DUMP_DEFAULT
+#define DEBUG_KERNEL_ACTIVE_DUMP DEBUG_DUMP_ACTIVE
+#define DEBUG_KERNEL_FULL_DUMP   DEBUG_DUMP_FULL
+
+#define DEBUG_KERNEL_TRACE_LOG   DEBUG_DUMP_TRACE_LOG
+
+// Specific types of Windows user debuggees.
+#define DEBUG_USER_WINDOWS_PROCESS         0
+#define DEBUG_USER_WINDOWS_PROCESS_SERVER  1
+#define DEBUG_USER_WINDOWS_IDNA            2
+#define DEBUG_USER_WINDOWS_REPT            3
+#define DEBUG_USER_WINDOWS_SMALL_DUMP      DEBUG_DUMP_SMALL
+#define DEBUG_USER_WINDOWS_DUMP            DEBUG_DUMP_DEFAULT
+#define DEBUG_USER_WINDOWS_DUMP_WINDOWS_CE DEBUG_DUMP_WINDOWS_CE
+
+// Extension flags.
+#define DEBUG_EXTENSION_AT_ENGINE 0x00000000
+
+// Execute and ExecuteCommandFile flags.
+// These flags only apply to the command
+// text itself; output from the executed
+// command is controlled by the output
+// control parameter.
+// Default execution.  Command is logged
+// but not output.
+#define DEBUG_EXECUTE_DEFAULT    0x00000000
+// Echo commands during execution.  In
+// ExecuteCommandFile also echoes the prompt
+// for each line of the file.
+#define DEBUG_EXECUTE_ECHO       0x00000001
+// Do not log or output commands during execution.
+// Overridden by DEBUG_EXECUTE_ECHO.
+#define DEBUG_EXECUTE_NOT_LOGGED 0x00000002
+// If this flag is not set an empty string
+// to Execute will repeat the last Execute
+// string.
+#define DEBUG_EXECUTE_NO_REPEAT  0x00000004
+// If this flag is set , the source of command
+// execution is user typing from remote session.
+#define DEBUG_EXECUTE_USER_TYPED  0x00000008
+// If this flag is set , the source of command
+// execution is user clicking from remote session.
+#define DEBUG_EXECUTE_USER_CLICKED  0x00000010
+// If this flag is set , the source of command
+// execution is debugger extension.
+#define DEBUG_EXECUTE_EXTENSION  0x00000020
+// If this flag is set , the source of command
+// execution is internal command like debugger setup.
+#define DEBUG_EXECUTE_INTERNAL  0x00000040
+// If this flag is set , the source of command
+// execution is debugger script.
+#define DEBUG_EXECUTE_SCRIPT  0x00000080
+// If this flag is set, the source of command
+// execution is a toolbar button.
+#define DEBUG_EXECUTE_TOOLBAR  0x00000100
+// If this flag is set, the source of command
+// execution is a menu item.
+#define DEBUG_EXECUTE_MENU  0x00000200
+// If this flag is set, the source of command
+// execution is a keyboard shortcut or hotkey.
+#define DEBUG_EXECUTE_HOTKEY  0x00000400
+// If this flag is set, the source of command
+// execution is a command registered on an event.
+#define DEBUG_EXECUTE_EVENT  0x00000800
+
+// Specific event filter types.  Some event
+// filters have optional arguments to further
+// qualify their operation.
+#define DEBUG_FILTER_CREATE_THREAD       0x00000000
+#define DEBUG_FILTER_EXIT_THREAD         0x00000001
+#define DEBUG_FILTER_CREATE_PROCESS      0x00000002
+#define DEBUG_FILTER_EXIT_PROCESS        0x00000003
+// Argument is the name of a module to break on.
+#define DEBUG_FILTER_LOAD_MODULE         0x00000004
+// Argument is the base address of a specific module to break on.
+#define DEBUG_FILTER_UNLOAD_MODULE       0x00000005
+#define DEBUG_FILTER_SYSTEM_ERROR        0x00000006
+// Initial breakpoint and initial module load are one-shot
+// events that are triggered at the appropriate points in
+// the beginning of a session.  Their commands are executed
+// and then further processing is controlled by the normal
+// exception and load module filters.
+#define DEBUG_FILTER_INITIAL_BREAKPOINT  0x00000007
+#define DEBUG_FILTER_INITIAL_MODULE_LOAD 0x00000008
+// The debug output filter allows the debugger to stop
+// when output is produced so that the code causing
+// output can be tracked down or synchronized with.
+// This filter is not supported for live dual-machine
+// kernel debugging.
+#define DEBUG_FILTER_DEBUGGEE_OUTPUT     0x00000009
+
+// Event filter execution options.
+// Break in always.
+#define DEBUG_FILTER_BREAK               0x00000000
+// Break in on second-chance exceptions.  For events
+// that are not exceptions this is the same as BREAK.
+#define DEBUG_FILTER_SECOND_CHANCE_BREAK 0x00000001
+// Output a message about the event but continue.
+#define DEBUG_FILTER_OUTPUT              0x00000002
+// Continue the event.
+#define DEBUG_FILTER_IGNORE              0x00000003
+// Used to remove general exception filters.
+#define DEBUG_FILTER_REMOVE              0x00000004
+
+// Event filter continuation options.  These options are
+// only used when DEBUG_STATUS_GO is used to continue
+// execution.  If a specific go status such as
+// DEBUG_STATUS_GO_NOT_HANDLED is used it controls
+// the continuation.
+#define DEBUG_FILTER_GO_HANDLED          0x00000000
+#define DEBUG_FILTER_GO_NOT_HANDLED      0x00000001
+
+// Specific event filter settings.
+typedef struct _DEBUG_SPECIFIC_FILTER_PARAMETERS
+{
+    ULONG ExecutionOption;
+    ULONG ContinueOption;
+    ULONG TextSize;
+    ULONG CommandSize;
+    // If ArgumentSize is zero this filter does
+    // not have an argument.  An empty argument for
+    // a filter which does have an argument will take
+    // one byte for the terminator.
+    ULONG ArgumentSize;
+} DEBUG_SPECIFIC_FILTER_PARAMETERS, *PDEBUG_SPECIFIC_FILTER_PARAMETERS;
+
+// Exception event filter settings.
+typedef struct _DEBUG_EXCEPTION_FILTER_PARAMETERS
+{
+    ULONG ExecutionOption;
+    ULONG ContinueOption;
+    ULONG TextSize;
+    ULONG CommandSize;
+    ULONG SecondCommandSize;
+    ULONG ExceptionCode;
+} DEBUG_EXCEPTION_FILTER_PARAMETERS, *PDEBUG_EXCEPTION_FILTER_PARAMETERS;
+
+// Wait flags.
+#define DEBUG_WAIT_DEFAULT 0x00000000
+
+// Last event information structures.
+typedef struct _DEBUG_LAST_EVENT_INFO_BREAKPOINT
+{
+    ULONG Id;
+} DEBUG_LAST_EVENT_INFO_BREAKPOINT, *PDEBUG_LAST_EVENT_INFO_BREAKPOINT;
+
+typedef struct _DEBUG_LAST_EVENT_INFO_EXCEPTION
+{
+    EXCEPTION_RECORD64 ExceptionRecord;
+    ULONG FirstChance;
+} DEBUG_LAST_EVENT_INFO_EXCEPTION, *PDEBUG_LAST_EVENT_INFO_EXCEPTION;
+
+typedef struct _DEBUG_LAST_EVENT_INFO_EXIT_THREAD
+{
+    ULONG ExitCode;
+} DEBUG_LAST_EVENT_INFO_EXIT_THREAD, *PDEBUG_LAST_EVENT_INFO_EXIT_THREAD;
+
+typedef struct _DEBUG_LAST_EVENT_INFO_EXIT_PROCESS
+{
+    ULONG ExitCode;
+} DEBUG_LAST_EVENT_INFO_EXIT_PROCESS, *PDEBUG_LAST_EVENT_INFO_EXIT_PROCESS;
+
+typedef struct _DEBUG_LAST_EVENT_INFO_LOAD_MODULE
+{
+    ULONG64 Base;
+} DEBUG_LAST_EVENT_INFO_LOAD_MODULE, *PDEBUG_LAST_EVENT_INFO_LOAD_MODULE;
+
+typedef struct _DEBUG_LAST_EVENT_INFO_UNLOAD_MODULE
+{
+    ULONG64 Base;
+} DEBUG_LAST_EVENT_INFO_UNLOAD_MODULE, *PDEBUG_LAST_EVENT_INFO_UNLOAD_MODULE;
+
+typedef struct _DEBUG_LAST_EVENT_INFO_SYSTEM_ERROR
+{
+    ULONG Error;
+    ULONG Level;
+} DEBUG_LAST_EVENT_INFO_SYSTEM_ERROR, *PDEBUG_LAST_EVENT_INFO_SYSTEM_ERROR;
+
+typedef struct _DEBUG_LAST_EVENT_INFO_SERVICE_EXCEPTION
+{
+    ULONG Kind;
+    ULONG DataSize;
+    ULONG64 Address;
+
+    //
+    // (Kind) Specific Data... (e.g.: an EXCEPTION_RECORD64 or another definition given by
+    //                                a specific platform service)
+    //
+} DEBUG_LAST_EVENT_INFO_SERVICE_EXCEPTION, *PDEBUG_LAST_EVENT_INFO_SERVICE_EXCEPTION;
+
+// DEBUG_VALUE types.
+#define DEBUG_VALUE_INVALID      0
+#define DEBUG_VALUE_INT8         1
+#define DEBUG_VALUE_INT16        2
+#define DEBUG_VALUE_INT32        3
+#define DEBUG_VALUE_INT64        4
+#define DEBUG_VALUE_FLOAT32      5
+#define DEBUG_VALUE_FLOAT64      6
+#define DEBUG_VALUE_FLOAT80      7
+#define DEBUG_VALUE_FLOAT82      8
+#define DEBUG_VALUE_FLOAT128     9
+#define DEBUG_VALUE_VECTOR64     10
+#define DEBUG_VALUE_VECTOR128    11
+// Count of type indices.
+#define DEBUG_VALUE_TYPES        12
+
+#if defined(_MSC_VER)
+#if _MSC_VER >= 800
+#if _MSC_VER >= 1200
+#pragma warning(push)
+#endif
+#pragma warning(disable:4201)    /* Nameless struct/union */
+#endif
+#endif
+
+// We want the DEBUG_VALUE structure to have 8-byte alignment
+// and be 32 bytes total.  This is tricky because the compiler
+// wants to pad the union of values out to a even 8-byte multiple,
+// pushing the type out too far.  We can't use 4-packing because
+// then the 8-byte alignment requirement is lost, so instead
+// we shrink the union to 24 bytes and have a reserved field
+// before the type field.  The same amount of space is available
+// and everybody's happy, but the structure is somewhat unusual.
+
+typedef struct _DEBUG_VALUE
+{
+    union
+    {
+        UCHAR I8;
+        USHORT I16;
+        ULONG I32;
+        struct
+        {
+            // Extra NAT indicator for IA64
+            // integer registers.  NAT will
+            // always be false for other CPUs.
+            ULONG64 I64;
+            BOOL Nat;
+        };
+        float F32;
+        double F64;
+        UCHAR F80Bytes[10];
+        UCHAR F82Bytes[11];
+        UCHAR F128Bytes[16];
+        // Vector interpretations.  The actual number
+        // of valid elements depends on the vector length.
+        UCHAR VI8[16];
+        USHORT VI16[8];
+        ULONG VI32[4];
+        ULONG64 VI64[2];
+        float VF32[4];
+        double VF64[2];
+        struct
+        {
+            ULONG LowPart;
+            ULONG HighPart;
+        } I64Parts32;
+        struct
+        {
+            ULONG64 LowPart;
+            LONG64 HighPart;
+        } F128Parts64;
+        // Allows raw byte access to content.  Array
+        // can be indexed for as much data as Type
+        // describes.  This array also serves to pad
+        // the structure out to 32 bytes and reserves
+        // space for future members.
+        UCHAR RawBytes[24];
+    };
+    ULONG TailOfRawBytes;
+  ULONG Type;
+} DEBUG_VALUE, *PDEBUG_VALUE;
+
+#if defined(_MSC_VER)
+#if _MSC_VER >= 800
+#if _MSC_VER >= 1200
+#pragma warning(pop)
+#else
+#pragma warning(default:4201)    /* Nameless struct/union */
+#endif
+#endif
+#endif
+
+#undef INTERFACE
+#define INTERFACE IDebugControl
+DECLARE_INTERFACE_(IDebugControl, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugControl.
+
+    // Checks for a user interrupt, such a Ctrl-C
+    // or stop button.
+    // This method is reentrant.
+    STDMETHOD(GetInterrupt)(
+        THIS
+        ) PURE;
+    // Registers a user interrupt.
+    // This method is reentrant.
+    STDMETHOD(SetInterrupt)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Interrupting a user-mode process requires
+    // access to some system resources that the
+    // process may hold itself, preventing the
+    // interrupt from occurring.  The engine
+    // will time-out pending interrupt requests
+    // and simulate an interrupt if necessary.
+    // These methods control the interrupt timeout.
+    STDMETHOD(GetInterruptTimeout)(
+        THIS_
+        _Out_ PULONG Seconds
+        ) PURE;
+    STDMETHOD(SetInterruptTimeout)(
+        THIS_
+        _In_ ULONG Seconds
+        ) PURE;
+
+    STDMETHOD(GetLogFile)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    // Opens a log file which collects all
+    // output.  Output from every client except
+    // those that explicitly disable logging
+    // goes into the log.
+    // Opening a log file closes any log file
+    // already open.
+    STDMETHOD(OpenLogFile)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ BOOL Append
+        ) PURE;
+    STDMETHOD(CloseLogFile)(
+        THIS
+        ) PURE;
+    // Controls what output is logged.
+    STDMETHOD(GetLogMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetLogMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+
+    // Input requests input from all clients.
+    // The first input that is returned is used
+    // to satisfy the call.  Other returned
+    // input is discarded.
+    STDMETHOD(Input)(
+        THIS_
+        _Out_writes_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    // This method is used by clients to return
+    // input when it is available.  It will
+    // return S_OK if the input is used to
+    // satisfy an Input call and S_FALSE if
+    // the input is ignored.
+    // This method is reentrant.
+    STDMETHOD(ReturnInput)(
+        THIS_
+        _In_ PCSTR Buffer
+        ) PURE;
+
+    // Sends output through clients
+    // output callbacks if the mask is allowed
+    // by the current output control mask and
+    // according to the output distribution
+    // settings.
+    STDMETHODV(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaList)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // The following methods allow direct control
+    // over the distribution of the given output
+    // for situations where something other than
+    // the default is desired.  These methods require
+    // extra work in the engine so they should
+    // only be used when necessary.
+    STDMETHODV(ControlledOutput)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    // Displays the standard command-line prompt
+    // followed by the given output.  If Format
+    // is NULL no additional output is produced.
+    // Output is produced under the
+    // DEBUG_OUTPUT_PROMPT mask.
+    // This method only outputs the prompt; it
+    // does not get input.
+    STDMETHODV(OutputPrompt)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // Gets the text that would be displayed by OutputPrompt.
+    STDMETHOD(GetPromptText)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // Outputs information about the current
+    // debuggee state such as a register
+    // summary, disassembly at the current PC,
+    // closest symbol and others.
+    // Uses the line prefix.
+    STDMETHOD(OutputCurrentState)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Outputs the debugger and extension version
+    // information.  This method is reentrant.
+    // Uses the line prefix.
+    STDMETHOD(OutputVersionInformation)(
+        THIS_
+        _In_ ULONG OutputControl
+        ) PURE;
+
+    // In user-mode debugging sessions the
+    // engine will set an event when
+    // exceptions are continued.  This can
+    // be used to synchronize other processes
+    // with the debuggers handling of events.
+    // For example, this is used to support
+    // the e argument to ntsd.
+    STDMETHOD(GetNotifyEventHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(SetNotifyEventHandle)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Assemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(Disassemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Returns the value of the effective address
+    // computed for the last Disassemble, if there
+    // was one.
+    STDMETHOD(GetDisassembleEffectiveOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Uses the line prefix if necessary.
+    STDMETHOD(OutputDisassembly)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Produces multiple lines of disassembly output.
+    // There will be PreviousLines of disassembly before
+    // the given offset if a valid disassembly exists.
+    // In all, there will be TotalLines of output produced.
+    // The first and last line offsets are returned
+    // specially and all lines offsets can be retrieved
+    // through LineOffsets.  LineOffsets will contain
+    // offsets for each line where disassembly started.
+    // When disassembly of a single instruction takes
+    // multiple lines the initial offset will be followed
+    // by DEBUG_INVALID_OFFSET.
+    // Uses the line prefix.
+    STDMETHOD(OutputDisassemblyLines)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG PreviousLines,
+        _In_ ULONG TotalLines,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG OffsetLine,
+        _Out_opt_ PULONG64 StartOffset,
+        _Out_opt_ PULONG64 EndOffset,
+        _Out_writes_opt_(TotalLines) PULONG64 LineOffsets
+        ) PURE;
+    // Returns the offset of the start of
+    // the instruction thats the given
+    // delta away from the instruction
+    // at the initial offset.
+    // This routine does not check for
+    // validity of the instruction or
+    // the memory containing it.
+    STDMETHOD(GetNearInstruction)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_ PULONG64 NearOffset
+        ) PURE;
+
+    // Offsets can be passed in as zero to use the current
+    // thread state.
+    STDMETHOD(GetStackTrace)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    // Does a simple stack trace to determine
+    // what the current return address is.
+    STDMETHOD(GetReturnOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // If Frames is NULL OutputStackTrace will
+    // use GetStackTrace to get FramesSize frames
+    // and then output them.  The current register
+    // values for frame, stack and instruction offsets
+    // are used.
+    // Uses the line prefix.
+    STDMETHOD(OutputStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Returns information about the debuggee such
+    // as user vs. kernel, dump vs. live, etc.
+    STDMETHOD(GetDebuggeeType)(
+        THIS_
+        _Out_ PULONG Class,
+        _Out_ PULONG Qualifier
+        ) PURE;
+    // Returns the type of physical processors in
+    // the machine.
+    // Returns one of the IMAGE_FILE_MACHINE values.
+    STDMETHOD(GetActualProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Returns the type of processor used in the
+    // current processor context.
+    STDMETHOD(GetExecutingProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Query all the possible processor types that
+    // may be encountered during this debug session.
+    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetPossibleExecutingProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Get the number of actual processors in
+    // the machine.
+    STDMETHOD(GetNumberProcessors)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // PlatformId is one of the VER_PLATFORM values.
+    // Major and minor are as given in the NT
+    // kernel debugger protocol.
+    // ServicePackString and ServicePackNumber indicate the
+    // system service pack level.  ServicePackNumber is not
+    // available in some sessions where the service pack level
+    // is only expressed as a string.  The service pack information
+    // will be empty if the system does not have a service pack
+    // applied.
+    // The build string is string information identifying the
+    // particular build of the system.  The build string is
+    // empty if the system has no particular identifying
+    // information.
+    STDMETHOD(GetSystemVersion)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Major,
+        _Out_ PULONG Minor,
+        _Out_writes_opt_(ServicePackStringSize) PSTR ServicePackString,
+        _In_ ULONG ServicePackStringSize,
+        _Out_opt_ PULONG ServicePackStringUsed,
+        _Out_ PULONG ServicePackNumber,
+        _Out_writes_opt_(BuildStringSize) PSTR BuildString,
+        _In_ ULONG BuildStringSize,
+        _Out_opt_ PULONG BuildStringUsed
+        ) PURE;
+    // Returns the page size for the currently executing
+    // processor context.  The page size may vary between
+    // processor types.
+    STDMETHOD(GetPageSize)(
+        THIS_
+        _Out_ PULONG Size
+        ) PURE;
+    // Returns S_OK if the current processor context uses
+    // 64-bit addresses, otherwise S_FALSE.
+    STDMETHOD(IsPointer64Bit)(
+        THIS
+        ) PURE;
+    // Reads the bugcheck data area and returns the
+    // current contents.  This method only works
+    // in kernel debugging sessions.
+    STDMETHOD(ReadBugCheckData)(
+        THIS_
+        _Out_ PULONG Code,
+        _Out_ PULONG64 Arg1,
+        _Out_ PULONG64 Arg2,
+        _Out_ PULONG64 Arg3,
+        _Out_ PULONG64 Arg4
+        ) PURE;
+
+    // Query all the processor types supported by
+    // the engine.  This is a complete list and is
+    // not related to the machine running the engine
+    // or the debuggee.
+    STDMETHOD(GetNumberSupportedProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetSupportedProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Returns a full, descriptive name and an
+    // abbreviated name for a processor type.
+    STDMETHOD(GetProcessorTypeNames)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    // Gets and sets the type of processor to
+    // use when doing things like setting
+    // breakpoints, accessing registers,
+    // getting stack traces and so on.
+    STDMETHOD(GetEffectiveProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(SetEffectiveProcessorType)(
+        THIS_
+        _In_ ULONG Type
+        ) PURE;
+
+    // Returns information about whether and how
+    // the debuggee is running.  Status will
+    // be GO if the debuggee is running and
+    // BREAK if it isnt.
+    // If no debuggee exists the status is
+    // NO_DEBUGGEE.
+    // This method is reentrant.
+    STDMETHOD(GetExecutionStatus)(
+        THIS_
+        _Out_ PULONG Status
+        ) PURE;
+    // Changes the execution status of the
+    // engine from stopped to running.
+    // Status must be one of the go or step
+    // status values.
+    STDMETHOD(SetExecutionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // Controls what code interpretation level the debugger
+    // runs at.  The debugger checks the code level when
+    // deciding whether to step by a source line or
+    // assembly instruction along with other related operations.
+    STDMETHOD(GetCodeLevel)(
+        THIS_
+        _Out_ PULONG Level
+        ) PURE;
+    STDMETHOD(SetCodeLevel)(
+        THIS_
+        _In_ ULONG Level
+        ) PURE;
+
+    // Gets and sets engine control flags.
+    // These methods are reentrant.
+    STDMETHOD(GetEngineOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Gets and sets control values for
+    // handling system error events.
+    // If the system error level is less
+    // than or equal to the given levels
+    // the error may be displayed and
+    // the default break for the event
+    // may be set.
+    STDMETHOD(GetSystemErrorControl)(
+        THIS_
+        _Out_ PULONG OutputLevel,
+        _Out_ PULONG BreakLevel
+        ) PURE;
+    STDMETHOD(SetSystemErrorControl)(
+        THIS_
+        _In_ ULONG OutputLevel,
+        _In_ ULONG BreakLevel
+        ) PURE;
+
+    // The command processor supports simple
+    // string replacement macros in Evaluate and
+    // Execute.  There are currently ten macro
+    // slots available.  Slots 0-9 map to
+    // the command invocations $u0-$u9.
+    STDMETHOD(GetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCSTR Macro
+        ) PURE;
+
+    // Controls the default number radix used
+    // in expressions and commands.
+    STDMETHOD(GetRadix)(
+        THIS_
+        _Out_ PULONG Radix
+        ) PURE;
+    STDMETHOD(SetRadix)(
+        THIS_
+        _In_ ULONG Radix
+        ) PURE;
+
+    // Evaluates the given expression string and
+    // returns the resulting value.
+    // If DesiredType is DEBUG_VALUE_INVALID then
+    // the natural type is used.
+    // RemainderIndex, if provided, is set to the index
+    // of the first character in the input string that was
+    // not used when evaluating the expression.
+    STDMETHOD(Evaluate)(
+        THIS_
+        _In_ PCSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+    // Attempts to convert the input value to a value
+    // of the requested type in the output value.
+    // Conversions can fail if no conversion exists.
+    // Successful conversions may be lossy.
+    STDMETHOD(CoerceValue)(
+        THIS_
+        _In_ PDEBUG_VALUE In,
+        _In_ ULONG OutType,
+        _Out_ PDEBUG_VALUE Out
+        ) PURE;
+    STDMETHOD(CoerceValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_VALUE In,
+        _In_reads_(Count) PULONG OutTypes,
+        _Out_writes_(Count) PDEBUG_VALUE Out
+        ) PURE;
+
+    // Executes the given command string.
+    // If the string has multiple commands
+    // Execute will not return until all
+    // of them have been executed.  If this
+    // requires waiting for the debuggee to
+    // execute an internal wait will be done
+    // so Execute can take an arbitrary amount
+    // of time.
+    STDMETHOD(Execute)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    // Executes the given command file by
+    // reading a line at a time and processing
+    // it with Execute.
+    STDMETHOD(ExecuteCommandFile)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Breakpoint interfaces are described
+    // elsewhere in this section.
+    STDMETHOD(GetNumberBreakpoints)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // It is possible for this retrieval function to
+    // fail even with an index within the number of
+    // existing breakpoints if the breakpoint is
+    // a private breakpoint.
+    STDMETHOD(GetBreakpointByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // If Ids is non-NULL the Count breakpoints
+    // referred to in the Ids array are returned,
+    // otherwise breakpoints from index Start to
+    // Start + Count  1 are returned.
+    STDMETHOD(GetBreakpointParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Ids,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+    // Breakpoints are created empty and disabled.
+    // When their parameters have been set they
+    // should be enabled by setting the ENABLE flag.
+    // If DesiredId is DEBUG_ANY_ID then the
+    // engine picks an unused ID.  If DesiredId
+    // is any other number the engine attempts
+    // to use the given ID for the breakpoint.
+    // If another breakpoint exists with that ID
+    // the call will fail.
+    STDMETHOD(AddBreakpoint)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // Breakpoint interface is invalid after this call.
+    STDMETHOD(RemoveBreakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT Bp
+        ) PURE;
+
+    // Control and use extension DLLs.
+    STDMETHOD(AddExtension)(
+        THIS_
+        _In_ PCSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(RemoveExtension)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPath)(
+        THIS_
+        _In_ PCSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Handle is zero the extension
+    // chain is walked searching for the
+    // function.
+    STDMETHOD(CallExtension)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR Function,
+        _In_opt_ PCSTR Arguments
+        ) PURE;
+    // GetExtensionFunction works like
+    // GetProcAddress on extension DLLs
+    // to allow raw function-call-level
+    // interaction with extension DLLs.
+    // Such functions do not need to
+    // follow the standard extension prototype
+    // if they are not going to be called
+    // through the text extension interface.
+    // _EFN_ is automatically prepended to
+    // the name string given.
+    // This function cannot be called remotely.
+    STDMETHOD(GetExtensionFunction)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+    // These methods return alternate
+    // extension interfaces in order to allow
+    // interface-style extension DLLs to mix in
+    // older extension calls.
+    // Structure sizes must be initialized before
+    // the call.
+    // These methods cannot be called remotely.
+    STDMETHOD(GetWindbgExtensionApis32)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS32 Api
+        ) PURE;
+    STDMETHOD(GetWindbgExtensionApis64)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS64 Api
+        ) PURE;
+
+    // The engine provides a simple mechanism
+    // to filter common events.  Arbitrarily complicated
+    // filtering can be done by registering event callbacks
+    // but simple event filtering only requires
+    // setting the options of one of the predefined
+    // event filters.
+    // Simple event filters are either for specific
+    // events and therefore have an enumerant or
+    // they are for an exception and are based on
+    // the exceptions code.  Exception filters
+    // are further divided into exceptions specially
+    // handled by the engine, which is a fixed set,
+    // and arbitrary exceptions.
+    // All three groups of filters are indexed together
+    // with the specific filters first, then the specific
+    // exception filters and finally the arbitrary
+    // exception filters.
+    // The first specific exception is the default
+    // exception.  If an exception event occurs for
+    // an exception without settings the default
+    // exception settings are used.
+    STDMETHOD(GetNumberEventFilters)(
+        THIS_
+        _Out_ PULONG SpecificEvents,
+        _Out_ PULONG SpecificExceptions,
+        _Out_ PULONG ArbitraryExceptions
+        ) PURE;
+    // Some filters have descriptive text associated with them.
+    STDMETHOD(GetEventFilterText)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // All filters support executing a command when the
+    // event occurs.
+    STDMETHOD(GetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    STDMETHOD(SetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    // Some specific filters have arguments to further
+    // qualify their operation.
+    STDMETHOD(GetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Argument
+        ) PURE;
+    // If Codes is non-NULL Start is ignored.
+    STDMETHOD(GetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Codes,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // The codes in the parameter data control the application
+    // of the parameter data.  If a code is not already in
+    // the set of filters it is added.  If the ExecutionOption
+    // for a code is REMOVE then the filter is removed.
+    // Specific exception filters cannot be removed.
+    STDMETHOD(SetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // Exception filters support an additional command for
+    // second-chance events.
+    STDMETHOD(GetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Yields processing to the engine until
+    // an event occurs.  This method may
+    // only be called by the thread that started
+    // the debug session.
+    // When an event occurs the engine carries
+    // out all event processing such as calling
+    // callbacks.
+    // If the callbacks indicate that execution should
+    // break the wait will return, otherwise it
+    // goes back to waiting for a new event.
+    // If the timeout expires, S_FALSE is returned.
+    // The timeout is not currently supported for
+    // kernel debugging.
+    STDMETHOD(WaitForEvent)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Retrieves information about the last event that occurred.
+    // EventType is one of the event callback mask bits.
+    // ExtraInformation contains additional event-specific
+    // information.  Not all events have additional information.
+    STDMETHOD(GetLastEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+};
+
+// OutputTextReplacements flags.
+#define DEBUG_OUT_TEXT_REPL_DEFAULT 0x00000000
+
+#undef INTERFACE
+#define INTERFACE IDebugControl2
+DECLARE_INTERFACE_(IDebugControl2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugControl.
+
+    // Checks for a user interrupt, such a Ctrl-C
+    // or stop button.
+    // This method is reentrant.
+    STDMETHOD(GetInterrupt)(
+        THIS
+        ) PURE;
+    // Registers a user interrupt.
+    // This method is reentrant.
+    STDMETHOD(SetInterrupt)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Interrupting a user-mode process requires
+    // access to some system resources that the
+    // process may hold itself, preventing the
+    // interrupt from occurring.  The engine
+    // will time-out pending interrupt requests
+    // and simulate an interrupt if necessary.
+    // These methods control the interrupt timeout.
+    STDMETHOD(GetInterruptTimeout)(
+        THIS_
+        _Out_ PULONG Seconds
+        ) PURE;
+    STDMETHOD(SetInterruptTimeout)(
+        THIS_
+        _In_ ULONG Seconds
+        ) PURE;
+
+    STDMETHOD(GetLogFile)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    // Opens a log file which collects all
+    // output.  Output from every client except
+    // those that explicitly disable logging
+    // goes into the log.
+    // Opening a log file closes any log file
+    // already open.
+    STDMETHOD(OpenLogFile)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ BOOL Append
+        ) PURE;
+    STDMETHOD(CloseLogFile)(
+        THIS
+        ) PURE;
+    // Controls what output is logged.
+    STDMETHOD(GetLogMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetLogMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+
+    // Input requests input from all clients.
+    // The first input that is returned is used
+    // to satisfy the call.  Other returned
+    // input is discarded.
+    STDMETHOD(Input)(
+        THIS_
+        _Out_writes_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    // This method is used by clients to return
+    // input when it is available.  It will
+    // return S_OK if the input is used to
+    // satisfy an Input call and S_FALSE if
+    // the input is ignored.
+    // This method is reentrant.
+    STDMETHOD(ReturnInput)(
+        THIS_
+        _In_ PCSTR Buffer
+        ) PURE;
+
+    // Sends output through clients
+    // output callbacks if the mask is allowed
+    // by the current output control mask and
+    // according to the output distribution
+    // settings.
+    STDMETHODV(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaList)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // The following methods allow direct control
+    // over the distribution of the given output
+    // for situations where something other than
+    // the default is desired.  These methods require
+    // extra work in the engine so they should
+    // only be used when necessary.
+    STDMETHODV(ControlledOutput)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    // Displays the standard command-line prompt
+    // followed by the given output.  If Format
+    // is NULL no additional output is produced.
+    // Output is produced under the
+    // DEBUG_OUTPUT_PROMPT mask.
+    // This method only outputs the prompt; it
+    // does not get input.
+    STDMETHODV(OutputPrompt)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // Gets the text that would be displayed by OutputPrompt.
+    STDMETHOD(GetPromptText)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // Outputs information about the current
+    // debuggee state such as a register
+    // summary, disassembly at the current PC,
+    // closest symbol and others.
+    // Uses the line prefix.
+    STDMETHOD(OutputCurrentState)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Outputs the debugger and extension version
+    // information.  This method is reentrant.
+    // Uses the line prefix.
+    STDMETHOD(OutputVersionInformation)(
+        THIS_
+        _In_ ULONG OutputControl
+        ) PURE;
+
+    // In user-mode debugging sessions the
+    // engine will set an event when
+    // exceptions are continued.  This can
+    // be used to synchronize other processes
+    // with the debuggers handling of events.
+    // For example, this is used to support
+    // the e argument to ntsd.
+    STDMETHOD(GetNotifyEventHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(SetNotifyEventHandle)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Assemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(Disassemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Returns the value of the effective address
+    // computed for the last Disassemble, if there
+    // was one.
+    STDMETHOD(GetDisassembleEffectiveOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Uses the line prefix if necessary.
+    STDMETHOD(OutputDisassembly)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Produces multiple lines of disassembly output.
+    // There will be PreviousLines of disassembly before
+    // the given offset if a valid disassembly exists.
+    // In all, there will be TotalLines of output produced.
+    // The first and last line offsets are returned
+    // specially and all lines offsets can be retrieved
+    // through LineOffsets.  LineOffsets will contain
+    // offsets for each line where disassembly started.
+    // When disassembly of a single instruction takes
+    // multiple lines the initial offset will be followed
+    // by DEBUG_INVALID_OFFSET.
+    // Uses the line prefix.
+    STDMETHOD(OutputDisassemblyLines)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG PreviousLines,
+        _In_ ULONG TotalLines,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG OffsetLine,
+        _Out_opt_ PULONG64 StartOffset,
+        _Out_opt_ PULONG64 EndOffset,
+        _Out_writes_opt_(TotalLines) PULONG64 LineOffsets
+        ) PURE;
+    // Returns the offset of the start of
+    // the instruction thats the given
+    // delta away from the instruction
+    // at the initial offset.
+    // This routine does not check for
+    // validity of the instruction or
+    // the memory containing it.
+    STDMETHOD(GetNearInstruction)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_ PULONG64 NearOffset
+        ) PURE;
+
+    // Offsets can be passed in as zero to use the current
+    // thread state.
+    STDMETHOD(GetStackTrace)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    // Does a simple stack trace to determine
+    // what the current return address is.
+    STDMETHOD(GetReturnOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // If Frames is NULL OutputStackTrace will
+    // use GetStackTrace to get FramesSize frames
+    // and then output them.  The current register
+    // values for frame, stack and instruction offsets
+    // are used.
+    // Uses the line prefix.
+    STDMETHOD(OutputStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Returns information about the debuggee such
+    // as user vs. kernel, dump vs. live, etc.
+    STDMETHOD(GetDebuggeeType)(
+        THIS_
+        _Out_ PULONG Class,
+        _Out_ PULONG Qualifier
+        ) PURE;
+    // Returns the type of physical processors in
+    // the machine.
+    // Returns one of the IMAGE_FILE_MACHINE values.
+    STDMETHOD(GetActualProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Returns the type of processor used in the
+    // current processor context.
+    STDMETHOD(GetExecutingProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Query all the possible processor types that
+    // may be encountered during this debug session.
+    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetPossibleExecutingProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Get the number of actual processors in
+    // the machine.
+    STDMETHOD(GetNumberProcessors)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // PlatformId is one of the VER_PLATFORM values.
+    // Major and minor are as given in the NT
+    // kernel debugger protocol.
+    // ServicePackString and ServicePackNumber indicate the
+    // system service pack level.  ServicePackNumber is not
+    // available in some sessions where the service pack level
+    // is only expressed as a string.  The service pack information
+    // will be empty if the system does not have a service pack
+    // applied.
+    // The build string is string information identifying the
+    // particular build of the system.  The build string is
+    // empty if the system has no particular identifying
+    // information.
+    STDMETHOD(GetSystemVersion)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Major,
+        _Out_ PULONG Minor,
+        _Out_writes_opt_(ServicePackStringSize) PSTR ServicePackString,
+        _In_ ULONG ServicePackStringSize,
+        _Out_opt_ PULONG ServicePackStringUsed,
+        _Out_ PULONG ServicePackNumber,
+        _Out_writes_opt_(BuildStringSize) PSTR BuildString,
+        _In_ ULONG BuildStringSize,
+        _Out_opt_ PULONG BuildStringUsed
+        ) PURE;
+    // Returns the page size for the currently executing
+    // processor context.  The page size may vary between
+    // processor types.
+    STDMETHOD(GetPageSize)(
+        THIS_
+        _Out_ PULONG Size
+        ) PURE;
+    // Returns S_OK if the current processor context uses
+    // 64-bit addresses, otherwise S_FALSE.
+    STDMETHOD(IsPointer64Bit)(
+        THIS
+        ) PURE;
+    // Reads the bugcheck data area and returns the
+    // current contents.  This method only works
+    // in kernel debugging sessions.
+    STDMETHOD(ReadBugCheckData)(
+        THIS_
+        _Out_ PULONG Code,
+        _Out_ PULONG64 Arg1,
+        _Out_ PULONG64 Arg2,
+        _Out_ PULONG64 Arg3,
+        _Out_ PULONG64 Arg4
+        ) PURE;
+
+    // Query all the processor types supported by
+    // the engine.  This is a complete list and is
+    // not related to the machine running the engine
+    // or the debuggee.
+    STDMETHOD(GetNumberSupportedProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetSupportedProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Returns a full, descriptive name and an
+    // abbreviated name for a processor type.
+    STDMETHOD(GetProcessorTypeNames)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    // Gets and sets the type of processor to
+    // use when doing things like setting
+    // breakpoints, accessing registers,
+    // getting stack traces and so on.
+    STDMETHOD(GetEffectiveProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(SetEffectiveProcessorType)(
+        THIS_
+        _In_ ULONG Type
+        ) PURE;
+
+    // Returns information about whether and how
+    // the debuggee is running.  Status will
+    // be GO if the debuggee is running and
+    // BREAK if it isnt.
+    // If no debuggee exists the status is
+    // NO_DEBUGGEE.
+    // This method is reentrant.
+    STDMETHOD(GetExecutionStatus)(
+        THIS_
+        _Out_ PULONG Status
+        ) PURE;
+    // Changes the execution status of the
+    // engine from stopped to running.
+    // Status must be one of the go or step
+    // status values.
+    STDMETHOD(SetExecutionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // Controls what code interpretation level the debugger
+    // runs at.  The debugger checks the code level when
+    // deciding whether to step by a source line or
+    // assembly instruction along with other related operations.
+    STDMETHOD(GetCodeLevel)(
+        THIS_
+        _Out_ PULONG Level
+        ) PURE;
+    STDMETHOD(SetCodeLevel)(
+        THIS_
+        _In_ ULONG Level
+        ) PURE;
+
+    // Gets and sets engine control flags.
+    // These methods are reentrant.
+    STDMETHOD(GetEngineOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Gets and sets control values for
+    // handling system error events.
+    // If the system error level is less
+    // than or equal to the given levels
+    // the error may be displayed and
+    // the default break for the event
+    // may be set.
+    STDMETHOD(GetSystemErrorControl)(
+        THIS_
+        _Out_ PULONG OutputLevel,
+        _Out_ PULONG BreakLevel
+        ) PURE;
+    STDMETHOD(SetSystemErrorControl)(
+        THIS_
+        _In_ ULONG OutputLevel,
+        _In_ ULONG BreakLevel
+        ) PURE;
+
+    // The command processor supports simple
+    // string replacement macros in Evaluate and
+    // Execute.  There are currently ten macro
+    // slots available.  Slots 0-9 map to
+    // the command invocations $u0-$u9.
+    STDMETHOD(GetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCSTR Macro
+        ) PURE;
+
+    // Controls the default number radix used
+    // in expressions and commands.
+    STDMETHOD(GetRadix)(
+        THIS_
+        _Out_ PULONG Radix
+        ) PURE;
+    STDMETHOD(SetRadix)(
+        THIS_
+        _In_ ULONG Radix
+        ) PURE;
+
+    // Evaluates the given expression string and
+    // returns the resulting value.
+    // If DesiredType is DEBUG_VALUE_INVALID then
+    // the natural type is used.
+    // RemainderIndex, if provided, is set to the index
+    // of the first character in the input string that was
+    // not used when evaluating the expression.
+    STDMETHOD(Evaluate)(
+        THIS_
+        _In_ PCSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+    // Attempts to convert the input value to a value
+    // of the requested type in the output value.
+    // Conversions can fail if no conversion exists.
+    // Successful conversions may be lossy.
+    STDMETHOD(CoerceValue)(
+        THIS_
+        _In_ PDEBUG_VALUE In,
+        _In_ ULONG OutType,
+        _Out_ PDEBUG_VALUE Out
+        ) PURE;
+    STDMETHOD(CoerceValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_VALUE In,
+        _In_reads_(Count) PULONG OutTypes,
+        _Out_writes_(Count) PDEBUG_VALUE Out
+        ) PURE;
+
+    // Executes the given command string.
+    // If the string has multiple commands
+    // Execute will not return until all
+    // of them have been executed.  If this
+    // requires waiting for the debuggee to
+    // execute an internal wait will be done
+    // so Execute can take an arbitrary amount
+    // of time.
+    STDMETHOD(Execute)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    // Executes the given command file by
+    // reading a line at a time and processing
+    // it with Execute.
+    STDMETHOD(ExecuteCommandFile)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Breakpoint interfaces are described
+    // elsewhere in this section.
+    STDMETHOD(GetNumberBreakpoints)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // It is possible for this retrieval function to
+    // fail even with an index within the number of
+    // existing breakpoints if the breakpoint is
+    // a private breakpoint.
+    STDMETHOD(GetBreakpointByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // If Ids is non-NULL the Count breakpoints
+    // referred to in the Ids array are returned,
+    // otherwise breakpoints from index Start to
+    // Start + Count  1 are returned.
+    STDMETHOD(GetBreakpointParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Ids,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+    // Breakpoints are created empty and disabled.
+    // When their parameters have been set they
+    // should be enabled by setting the ENABLE flag.
+    // If DesiredId is DEBUG_ANY_ID then the
+    // engine picks an unused ID.  If DesiredId
+    // is any other number the engine attempts
+    // to use the given ID for the breakpoint.
+    // If another breakpoint exists with that ID
+    // the call will fail.
+    STDMETHOD(AddBreakpoint)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // Breakpoint interface is invalid after this call.
+    STDMETHOD(RemoveBreakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT Bp
+        ) PURE;
+
+    // Control and use extension DLLs.
+    STDMETHOD(AddExtension)(
+        THIS_
+        _In_ PCSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(RemoveExtension)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPath)(
+        THIS_
+        _In_ PCSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Handle is zero the extension
+    // chain is walked searching for the
+    // function.
+    STDMETHOD(CallExtension)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR Function,
+        _In_opt_ PCSTR Arguments
+        ) PURE;
+    // GetExtensionFunction works like
+    // GetProcAddress on extension DLLs
+    // to allow raw function-call-level
+    // interaction with extension DLLs.
+    // Such functions do not need to
+    // follow the standard extension prototype
+    // if they are not going to be called
+    // through the text extension interface.
+    // This function cannot be called remotely.
+    STDMETHOD(GetExtensionFunction)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+    // These methods return alternate
+    // extension interfaces in order to allow
+    // interface-style extension DLLs to mix in
+    // older extension calls.
+    // Structure sizes must be initialized before
+    // the call.
+    // These methods cannot be called remotely.
+    STDMETHOD(GetWindbgExtensionApis32)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS32 Api
+        ) PURE;
+    STDMETHOD(GetWindbgExtensionApis64)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS64 Api
+        ) PURE;
+
+    // The engine provides a simple mechanism
+    // to filter common events.  Arbitrarily complicated
+    // filtering can be done by registering event callbacks
+    // but simple event filtering only requires
+    // setting the options of one of the predefined
+    // event filters.
+    // Simple event filters are either for specific
+    // events and therefore have an enumerant or
+    // they are for an exception and are based on
+    // the exceptions code.  Exception filters
+    // are further divided into exceptions specially
+    // handled by the engine, which is a fixed set,
+    // and arbitrary exceptions.
+    // All three groups of filters are indexed together
+    // with the specific filters first, then the specific
+    // exception filters and finally the arbitrary
+    // exception filters.
+    // The first specific exception is the default
+    // exception.  If an exception event occurs for
+    // an exception without settings the default
+    // exception settings are used.
+    STDMETHOD(GetNumberEventFilters)(
+        THIS_
+        _Out_ PULONG SpecificEvents,
+        _Out_ PULONG SpecificExceptions,
+        _Out_ PULONG ArbitraryExceptions
+        ) PURE;
+    // Some filters have descriptive text associated with them.
+    STDMETHOD(GetEventFilterText)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // All filters support executing a command when the
+    // event occurs.
+    STDMETHOD(GetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    STDMETHOD(SetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    // Some specific filters have arguments to further
+    // qualify their operation.
+    STDMETHOD(GetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Argument
+        ) PURE;
+    // If Codes is non-NULL Start is ignored.
+    STDMETHOD(GetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Codes,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // The codes in the parameter data control the application
+    // of the parameter data.  If a code is not already in
+    // the set of filters it is added.  If the ExecutionOption
+    // for a code is REMOVE then the filter is removed.
+    // Specific exception filters cannot be removed.
+    STDMETHOD(SetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // Exception filters support an additional command for
+    // second-chance events.
+    STDMETHOD(GetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Yields processing to the engine until
+    // an event occurs.  This method may
+    // only be called by the thread that started
+    // the debug session.
+    // When an event occurs the engine carries
+    // out all event processing such as calling
+    // callbacks.
+    // If the callbacks indicate that execution should
+    // break the wait will return, otherwise it
+    // goes back to waiting for a new event.
+    // If the timeout expires, S_FALSE is returned.
+    // The timeout is not currently supported for
+    // kernel debugging.
+    STDMETHOD(WaitForEvent)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Retrieves information about the last event that occurred.
+    // EventType is one of the event callback mask bits.
+    // ExtraInformation contains additional event-specific
+    // information.  Not all events have additional information.
+    STDMETHOD(GetLastEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    // IDebugControl2.
+
+    STDMETHOD(GetCurrentTimeDate)(
+        THIS_
+        _Out_ PULONG TimeDate
+        ) PURE;
+    // Retrieves the number of seconds since the
+    // machine started running.
+    STDMETHOD(GetCurrentSystemUpTime)(
+        THIS_
+        _Out_ PULONG UpTime
+        ) PURE;
+
+    // If the current session is a dump session,
+    // retrieves any extended format information.
+    STDMETHOD(GetDumpFormatFlags)(
+        THIS_
+        _Out_ PULONG FormatFlags
+        ) PURE;
+
+    // The debugger has been enhanced to allow
+    // arbitrary text replacements in addition
+    // to the simple $u0-$u9 text macros.
+    // Text replacement takes a given source
+    // text in commands and converts it to the
+    // given destination text.  Replacements
+    // are named by their source text so that
+    // only one replacement for a source text
+    // string can exist.
+    STDMETHOD(GetNumberTextReplacements)(
+        THIS_
+        _Out_ PULONG NumRepl
+        ) PURE;
+    // If SrcText is non-NULL the replacement
+    // is looked up by source text, otherwise
+    // Index is used to get the Nth replacement.
+    STDMETHOD(GetTextReplacement)(
+        THIS_
+        _In_opt_ PCSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    // Setting the destination text to
+    // NULL removes the alias.
+    STDMETHOD(SetTextReplacement)(
+        THIS_
+        _In_ PCSTR SrcText,
+        _In_opt_ PCSTR DstText
+        ) PURE;
+    STDMETHOD(RemoveTextReplacements)(
+        THIS
+        ) PURE;
+    // Outputs the complete list of current
+    // replacements.
+    STDMETHOD(OutputTextReplacements)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+};
+
+//
+// Assembly/disassembly options.
+//
+// The specific effects of these flags varies depending
+// on the particular instruction set.
+//
+
+#define DEBUG_ASMOPT_DEFAULT             0x00000000
+// Display additional information in disassembly.
+#define DEBUG_ASMOPT_VERBOSE             0x00000001
+// Do not display raw code bytes in disassembly.
+#define DEBUG_ASMOPT_NO_CODE_BYTES       0x00000002
+// Do not take the output width into account when
+// formatting disassembly.
+#define DEBUG_ASMOPT_IGNORE_OUTPUT_WIDTH 0x00000004
+// Display source file line number before each line if available.
+#define DEBUG_ASMOPT_SOURCE_LINE_NUMBER  0x00000008
+
+//
+// Expression syntax options.
+//
+
+// MASM-style expression evaluation.
+#define DEBUG_EXPR_MASM      0x00000000
+// C++-style expression evaluation.
+#define DEBUG_EXPR_CPLUSPLUS 0x00000001
+
+//
+// Event index description information.
+//
+
+#define DEBUG_EINDEX_NAME 0x00000000
+
+//
+// SetNextEventIndex relation options.
+//
+
+// Value increases forward from the first index.
+#define DEBUG_EINDEX_FROM_START   0x00000000
+// Value increases backwards from the last index.
+#define DEBUG_EINDEX_FROM_END     0x00000001
+// Value is a signed delta from the current index.
+#define DEBUG_EINDEX_FROM_CURRENT 0x00000002
+
+#undef INTERFACE
+#define INTERFACE IDebugControl3
+DECLARE_INTERFACE_(IDebugControl3, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugControl.
+
+    // Checks for a user interrupt, such a Ctrl-C
+    // or stop button.
+    // This method is reentrant.
+    STDMETHOD(GetInterrupt)(
+        THIS
+        ) PURE;
+    // Registers a user interrupt.
+    // This method is reentrant.
+    STDMETHOD(SetInterrupt)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Interrupting a user-mode process requires
+    // access to some system resources that the
+    // process may hold itself, preventing the
+    // interrupt from occurring.  The engine
+    // will time-out pending interrupt requests
+    // and simulate an interrupt if necessary.
+    // These methods control the interrupt timeout.
+    STDMETHOD(GetInterruptTimeout)(
+        THIS_
+        _Out_ PULONG Seconds
+        ) PURE;
+    STDMETHOD(SetInterruptTimeout)(
+        THIS_
+        _In_ ULONG Seconds
+        ) PURE;
+
+    STDMETHOD(GetLogFile)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    // Opens a log file which collects all
+    // output.  Output from every client except
+    // those that explicitly disable logging
+    // goes into the log.
+    // Opening a log file closes any log file
+    // already open.
+    STDMETHOD(OpenLogFile)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ BOOL Append
+        ) PURE;
+    STDMETHOD(CloseLogFile)(
+        THIS
+        ) PURE;
+    // Controls what output is logged.
+    STDMETHOD(GetLogMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetLogMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+
+    // Input requests input from all clients.
+    // The first input that is returned is used
+    // to satisfy the call.  Other returned
+    // input is discarded.
+    STDMETHOD(Input)(
+        THIS_
+        _Out_writes_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    // This method is used by clients to return
+    // input when it is available.  It will
+    // return S_OK if the input is used to
+    // satisfy an Input call and S_FALSE if
+    // the input is ignored.
+    // This method is reentrant.
+    STDMETHOD(ReturnInput)(
+        THIS_
+        _In_ PCSTR Buffer
+        ) PURE;
+
+    // Sends output through clients
+    // output callbacks if the mask is allowed
+    // by the current output control mask and
+    // according to the output distribution
+    // settings.
+    STDMETHODV(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaList)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // The following methods allow direct control
+    // over the distribution of the given output
+    // for situations where something other than
+    // the default is desired.  These methods require
+    // extra work in the engine so they should
+    // only be used when necessary.
+    STDMETHODV(ControlledOutput)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    // Displays the standard command-line prompt
+    // followed by the given output.  If Format
+    // is NULL no additional output is produced.
+    // Output is produced under the
+    // DEBUG_OUTPUT_PROMPT mask.
+    // This method only outputs the prompt; it
+    // does not get input.
+    STDMETHODV(OutputPrompt)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // Gets the text that would be displayed by OutputPrompt.
+    STDMETHOD(GetPromptText)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // Outputs information about the current
+    // debuggee state such as a register
+    // summary, disassembly at the current PC,
+    // closest symbol and others.
+    // Uses the line prefix.
+    STDMETHOD(OutputCurrentState)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Outputs the debugger and extension version
+    // information.  This method is reentrant.
+    // Uses the line prefix.
+    STDMETHOD(OutputVersionInformation)(
+        THIS_
+        _In_ ULONG OutputControl
+        ) PURE;
+
+    // In user-mode debugging sessions the
+    // engine will set an event when
+    // exceptions are continued.  This can
+    // be used to synchronize other processes
+    // with the debuggers handling of events.
+    // For example, this is used to support
+    // the e argument to ntsd.
+    STDMETHOD(GetNotifyEventHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(SetNotifyEventHandle)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Assemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(Disassemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Returns the value of the effective address
+    // computed for the last Disassemble, if there
+    // was one.
+    STDMETHOD(GetDisassembleEffectiveOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Uses the line prefix if necessary.
+    STDMETHOD(OutputDisassembly)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Produces multiple lines of disassembly output.
+    // There will be PreviousLines of disassembly before
+    // the given offset if a valid disassembly exists.
+    // In all, there will be TotalLines of output produced.
+    // The first and last line offsets are returned
+    // specially and all lines offsets can be retrieved
+    // through LineOffsets.  LineOffsets will contain
+    // offsets for each line where disassembly started.
+    // When disassembly of a single instruction takes
+    // multiple lines the initial offset will be followed
+    // by DEBUG_INVALID_OFFSET.
+    // Uses the line prefix.
+    STDMETHOD(OutputDisassemblyLines)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG PreviousLines,
+        _In_ ULONG TotalLines,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG OffsetLine,
+        _Out_opt_ PULONG64 StartOffset,
+        _Out_opt_ PULONG64 EndOffset,
+        _Out_writes_opt_(TotalLines) PULONG64 LineOffsets
+        ) PURE;
+    // Returns the offset of the start of
+    // the instruction thats the given
+    // delta away from the instruction
+    // at the initial offset.
+    // This routine does not check for
+    // validity of the instruction or
+    // the memory containing it.
+    STDMETHOD(GetNearInstruction)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_ PULONG64 NearOffset
+        ) PURE;
+
+    // Offsets can be passed in as zero to use the current
+    // thread state.
+    STDMETHOD(GetStackTrace)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    // Does a simple stack trace to determine
+    // what the current return address is.
+    STDMETHOD(GetReturnOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // If Frames is NULL OutputStackTrace will
+    // use GetStackTrace to get FramesSize frames
+    // and then output them.  The current register
+    // values for frame, stack and instruction offsets
+    // are used.
+    // Uses the line prefix.
+    STDMETHOD(OutputStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Returns information about the debuggee such
+    // as user vs. kernel, dump vs. live, etc.
+    STDMETHOD(GetDebuggeeType)(
+        THIS_
+        _Out_ PULONG Class,
+        _Out_ PULONG Qualifier
+        ) PURE;
+    // Returns the type of physical processors in
+    // the machine.
+    // Returns one of the IMAGE_FILE_MACHINE values.
+    STDMETHOD(GetActualProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Returns the type of processor used in the
+    // current processor context.
+    STDMETHOD(GetExecutingProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Query all the possible processor types that
+    // may be encountered during this debug session.
+    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetPossibleExecutingProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Get the number of actual processors in
+    // the machine.
+    STDMETHOD(GetNumberProcessors)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // PlatformId is one of the VER_PLATFORM values.
+    // Major and minor are as given in the NT
+    // kernel debugger protocol.
+    // ServicePackString and ServicePackNumber indicate the
+    // system service pack level.  ServicePackNumber is not
+    // available in some sessions where the service pack level
+    // is only expressed as a string.  The service pack information
+    // will be empty if the system does not have a service pack
+    // applied.
+    // The build string is string information identifying the
+    // particular build of the system.  The build string is
+    // empty if the system has no particular identifying
+    // information.
+    STDMETHOD(GetSystemVersion)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Major,
+        _Out_ PULONG Minor,
+        _Out_writes_opt_(ServicePackStringSize) PSTR ServicePackString,
+        _In_ ULONG ServicePackStringSize,
+        _Out_opt_ PULONG ServicePackStringUsed,
+        _Out_ PULONG ServicePackNumber,
+        _Out_writes_opt_(BuildStringSize) PSTR BuildString,
+        _In_ ULONG BuildStringSize,
+        _Out_opt_ PULONG BuildStringUsed
+        ) PURE;
+    // Returns the page size for the currently executing
+    // processor context.  The page size may vary between
+    // processor types.
+    STDMETHOD(GetPageSize)(
+        THIS_
+        _Out_ PULONG Size
+        ) PURE;
+    // Returns S_OK if the current processor context uses
+    // 64-bit addresses, otherwise S_FALSE.
+    STDMETHOD(IsPointer64Bit)(
+        THIS
+        ) PURE;
+    // Reads the bugcheck data area and returns the
+    // current contents.  This method only works
+    // in kernel debugging sessions.
+    STDMETHOD(ReadBugCheckData)(
+        THIS_
+        _Out_ PULONG Code,
+        _Out_ PULONG64 Arg1,
+        _Out_ PULONG64 Arg2,
+        _Out_ PULONG64 Arg3,
+        _Out_ PULONG64 Arg4
+        ) PURE;
+
+    // Query all the processor types supported by
+    // the engine.  This is a complete list and is
+    // not related to the machine running the engine
+    // or the debuggee.
+    STDMETHOD(GetNumberSupportedProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetSupportedProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Returns a full, descriptive name and an
+    // abbreviated name for a processor type.
+    STDMETHOD(GetProcessorTypeNames)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    // Gets and sets the type of processor to
+    // use when doing things like setting
+    // breakpoints, accessing registers,
+    // getting stack traces and so on.
+    STDMETHOD(GetEffectiveProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(SetEffectiveProcessorType)(
+        THIS_
+        _In_ ULONG Type
+        ) PURE;
+
+    // Returns information about whether and how
+    // the debuggee is running.  Status will
+    // be GO if the debuggee is running and
+    // BREAK if it isnt.
+    // If no debuggee exists the status is
+    // NO_DEBUGGEE.
+    // This method is reentrant.
+    STDMETHOD(GetExecutionStatus)(
+        THIS_
+        _Out_ PULONG Status
+        ) PURE;
+    // Changes the execution status of the
+    // engine from stopped to running.
+    // Status must be one of the go or step
+    // status values.
+    STDMETHOD(SetExecutionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // Controls what code interpretation level the debugger
+    // runs at.  The debugger checks the code level when
+    // deciding whether to step by a source line or
+    // assembly instruction along with other related operations.
+    STDMETHOD(GetCodeLevel)(
+        THIS_
+        _Out_ PULONG Level
+        ) PURE;
+    STDMETHOD(SetCodeLevel)(
+        THIS_
+        _In_ ULONG Level
+        ) PURE;
+
+    // Gets and sets engine control flags.
+    // These methods are reentrant.
+    STDMETHOD(GetEngineOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Gets and sets control values for
+    // handling system error events.
+    // If the system error level is less
+    // than or equal to the given levels
+    // the error may be displayed and
+    // the default break for the event
+    // may be set.
+    STDMETHOD(GetSystemErrorControl)(
+        THIS_
+        _Out_ PULONG OutputLevel,
+        _Out_ PULONG BreakLevel
+        ) PURE;
+    STDMETHOD(SetSystemErrorControl)(
+        THIS_
+        _In_ ULONG OutputLevel,
+        _In_ ULONG BreakLevel
+        ) PURE;
+
+    // The command processor supports simple
+    // string replacement macros in Evaluate and
+    // Execute.  There are currently ten macro
+    // slots available.  Slots 0-9 map to
+    // the command invocations $u0-$u9.
+    STDMETHOD(GetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCSTR Macro
+        ) PURE;
+
+    // Controls the default number radix used
+    // in expressions and commands.
+    STDMETHOD(GetRadix)(
+        THIS_
+        _Out_ PULONG Radix
+        ) PURE;
+    STDMETHOD(SetRadix)(
+        THIS_
+        _In_ ULONG Radix
+        ) PURE;
+
+    // Evaluates the given expression string and
+    // returns the resulting value.
+    // If DesiredType is DEBUG_VALUE_INVALID then
+    // the natural type is used.
+    // RemainderIndex, if provided, is set to the index
+    // of the first character in the input string that was
+    // not used when evaluating the expression.
+    STDMETHOD(Evaluate)(
+        THIS_
+        _In_ PCSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+    // Attempts to convert the input value to a value
+    // of the requested type in the output value.
+    // Conversions can fail if no conversion exists.
+    // Successful conversions may be lossy.
+    STDMETHOD(CoerceValue)(
+        THIS_
+        _In_ PDEBUG_VALUE In,
+        _In_ ULONG OutType,
+        _Out_ PDEBUG_VALUE Out
+        ) PURE;
+    STDMETHOD(CoerceValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_VALUE In,
+        _In_reads_(Count) PULONG OutTypes,
+        _Out_writes_(Count) PDEBUG_VALUE Out
+        ) PURE;
+
+    // Executes the given command string.
+    // If the string has multiple commands
+    // Execute will not return until all
+    // of them have been executed.  If this
+    // requires waiting for the debuggee to
+    // execute an internal wait will be done
+    // so Execute can take an arbitrary amount
+    // of time.
+    STDMETHOD(Execute)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    // Executes the given command file by
+    // reading a line at a time and processing
+    // it with Execute.
+    STDMETHOD(ExecuteCommandFile)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Breakpoint interfaces are described
+    // elsewhere in this section.
+    STDMETHOD(GetNumberBreakpoints)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // It is possible for this retrieval function to
+    // fail even with an index within the number of
+    // existing breakpoints if the breakpoint is
+    // a private breakpoint.
+    STDMETHOD(GetBreakpointByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // If Ids is non-NULL the Count breakpoints
+    // referred to in the Ids array are returned,
+    // otherwise breakpoints from index Start to
+    // Start + Count  1 are returned.
+    STDMETHOD(GetBreakpointParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Ids,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+    // Breakpoints are created empty and disabled.
+    // When their parameters have been set they
+    // should be enabled by setting the ENABLE flag.
+    // If DesiredId is DEBUG_ANY_ID then the
+    // engine picks an unused ID.  If DesiredId
+    // is any other number the engine attempts
+    // to use the given ID for the breakpoint.
+    // If another breakpoint exists with that ID
+    // the call will fail.
+    STDMETHOD(AddBreakpoint)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // Breakpoint interface is invalid after this call.
+    STDMETHOD(RemoveBreakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT Bp
+        ) PURE;
+
+    // Control and use extension DLLs.
+    STDMETHOD(AddExtension)(
+        THIS_
+        _In_ PCSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(RemoveExtension)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPath)(
+        THIS_
+        _In_ PCSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Handle is zero the extension
+    // chain is walked searching for the
+    // function.
+    STDMETHOD(CallExtension)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR Function,
+        _In_opt_ PCSTR Arguments
+        ) PURE;
+    // GetExtensionFunction works like
+    // GetProcAddress on extension DLLs
+    // to allow raw function-call-level
+    // interaction with extension DLLs.
+    // Such functions do not need to
+    // follow the standard extension prototype
+    // if they are not going to be called
+    // through the text extension interface.
+    // This function cannot be called remotely.
+    STDMETHOD(GetExtensionFunction)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+    // These methods return alternate
+    // extension interfaces in order to allow
+    // interface-style extension DLLs to mix in
+    // older extension calls.
+    // Structure sizes must be initialized before
+    // the call.
+    // These methods cannot be called remotely.
+    STDMETHOD(GetWindbgExtensionApis32)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS32 Api
+        ) PURE;
+    STDMETHOD(GetWindbgExtensionApis64)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS64 Api
+        ) PURE;
+
+    // The engine provides a simple mechanism
+    // to filter common events.  Arbitrarily complicated
+    // filtering can be done by registering event callbacks
+    // but simple event filtering only requires
+    // setting the options of one of the predefined
+    // event filters.
+    // Simple event filters are either for specific
+    // events and therefore have an enumerant or
+    // they are for an exception and are based on
+    // the exceptions code.  Exception filters
+    // are further divided into exceptions specially
+    // handled by the engine, which is a fixed set,
+    // and arbitrary exceptions.
+    // All three groups of filters are indexed together
+    // with the specific filters first, then the specific
+    // exception filters and finally the arbitrary
+    // exception filters.
+    // The first specific exception is the default
+    // exception.  If an exception event occurs for
+    // an exception without settings the default
+    // exception settings are used.
+    STDMETHOD(GetNumberEventFilters)(
+        THIS_
+        _Out_ PULONG SpecificEvents,
+        _Out_ PULONG SpecificExceptions,
+        _Out_ PULONG ArbitraryExceptions
+        ) PURE;
+    // Some filters have descriptive text associated with them.
+    STDMETHOD(GetEventFilterText)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // All filters support executing a command when the
+    // event occurs.
+    STDMETHOD(GetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    STDMETHOD(SetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    // Some specific filters have arguments to further
+    // qualify their operation.
+    STDMETHOD(GetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Argument
+        ) PURE;
+    // If Codes is non-NULL Start is ignored.
+    STDMETHOD(GetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Codes,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // The codes in the parameter data control the application
+    // of the parameter data.  If a code is not already in
+    // the set of filters it is added.  If the ExecutionOption
+    // for a code is REMOVE then the filter is removed.
+    // Specific exception filters cannot be removed.
+    STDMETHOD(SetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // Exception filters support an additional command for
+    // second-chance events.
+    STDMETHOD(GetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Yields processing to the engine until
+    // an event occurs.  This method may
+    // only be called by the thread that started
+    // the debug session.
+    // When an event occurs the engine carries
+    // out all event processing such as calling
+    // callbacks.
+    // If the callbacks indicate that execution should
+    // break the wait will return, otherwise it
+    // goes back to waiting for a new event.
+    // If the timeout expires, S_FALSE is returned.
+    // The timeout is not currently supported for
+    // kernel debugging.
+    STDMETHOD(WaitForEvent)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Retrieves information about the last event that occurred.
+    // EventType is one of the event callback mask bits.
+    // ExtraInformation contains additional event-specific
+    // information.  Not all events have additional information.
+    STDMETHOD(GetLastEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    // IDebugControl2.
+
+    STDMETHOD(GetCurrentTimeDate)(
+        THIS_
+        _Out_ PULONG TimeDate
+        ) PURE;
+    // Retrieves the number of seconds since the
+    // machine started running.
+    STDMETHOD(GetCurrentSystemUpTime)(
+        THIS_
+        _Out_ PULONG UpTime
+        ) PURE;
+
+    // If the current session is a dump session,
+    // retrieves any extended format information.
+    STDMETHOD(GetDumpFormatFlags)(
+        THIS_
+        _Out_ PULONG FormatFlags
+        ) PURE;
+
+    // The debugger has been enhanced to allow
+    // arbitrary text replacements in addition
+    // to the simple $u0-$u9 text macros.
+    // Text replacement takes a given source
+    // text in commands and converts it to the
+    // given destination text.  Replacements
+    // are named by their source text so that
+    // only one replacement for a source text
+    // string can exist.
+    STDMETHOD(GetNumberTextReplacements)(
+        THIS_
+        _Out_ PULONG NumRepl
+        ) PURE;
+    // If SrcText is non-NULL the replacement
+    // is looked up by source text, otherwise
+    // Index is used to get the Nth replacement.
+    STDMETHOD(GetTextReplacement)(
+        THIS_
+        _In_opt_ PCSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    // Setting the destination text to
+    // NULL removes the alias.
+    STDMETHOD(SetTextReplacement)(
+        THIS_
+        _In_ PCSTR SrcText,
+        _In_opt_ PCSTR DstText
+        ) PURE;
+    STDMETHOD(RemoveTextReplacements)(
+        THIS
+        ) PURE;
+    // Outputs the complete list of current
+    // replacements.
+    STDMETHOD(OutputTextReplacements)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // IDebugControl3.
+
+    // Control options for assembly and disassembly.
+    STDMETHOD(GetAssemblyOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Control the expression syntax.
+    STDMETHOD(GetExpressionSyntax)(
+        THIS_
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(SetExpressionSyntax)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Look up a syntax by its abbreviated
+    // name and set it.
+    STDMETHOD(SetExpressionSyntaxByName)(
+        THIS_
+        _In_ PCSTR AbbrevName
+        ) PURE;
+    STDMETHOD(GetNumberExpressionSyntaxes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetExpressionSyntaxNames)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    //
+    // Some debug sessions have only a single
+    // possible event, such as a snapshot dump
+    // file; some have dynamic events, such as
+    // a live debug session; and others may have
+    // multiple events, such as a dump file that
+    // contains snapshots from different points
+    // in time.  The following methods allow
+    // discovery and selection of the available
+    // events for a session.
+    // Sessions with one or more static events
+    // will be able to report all of the events
+    // when queried.  Sessions with dynamic events
+    // will only report a single event representing
+    // the current event.
+    // Switching events constitutes execution and
+    // changing the current event will alter the
+    // execution status to a running state, after
+    // which WaitForEvent must be used to process
+    // the selected event.
+    //
+
+    // GetNumberEvents returns S_OK if this is the
+    // complete set of events possible, such as for
+    // a static session; or S_FALSE if other events
+    // may be possible, such as for a dynamic session.
+    STDMETHOD(GetNumberEvents)(
+        THIS_
+        _Out_ PULONG Events
+        ) PURE;
+    // Sessions may have descriptive information for
+    // the various events available.  The amount of
+    // information varies according to the specific
+    // session and data.
+    STDMETHOD(GetEventIndexDescription)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG Which,
+        _In_opt_ PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DescSize
+        ) PURE;
+    STDMETHOD(GetCurrentEventIndex)(
+        THIS_
+        _Out_ PULONG Index
+        ) PURE;
+    // SetNextEventIndex works like seek in that
+    // it can set an absolute or relative index.
+    // SetNextEventIndex works similarly to SetExecutionStatus
+    // by putting the session into a running state, after
+    // which the caller must call WaitForEvent.  The
+    // current event index only changes when WaitForEvent
+    // is called.
+    STDMETHOD(SetNextEventIndex)(
+        THIS_
+        _In_ ULONG Relation,
+        _In_ ULONG Value,
+        _Out_ PULONG NextIndex
+        ) PURE;
+};
+
+//
+// Log file flags.
+//
+
+#define DEBUG_LOG_DEFAULT 0x00000000
+#define DEBUG_LOG_APPEND  0x00000001
+#define DEBUG_LOG_UNICODE 0x00000002
+#define DEBUG_LOG_DML     0x00000004
+
+//
+// System version strings.
+//
+
+#define DEBUG_SYSVERSTR_SERVICE_PACK 0x00000000
+#define DEBUG_SYSVERSTR_BUILD        0x00000001
+
+//
+// GetManagedStatus flags and strings.
+//
+
+#define DEBUG_MANAGED_DISABLED   0x00000000
+#define DEBUG_MANAGED_ALLOWED    0x00000001
+#define DEBUG_MANAGED_DLL_LOADED 0x00000002
+
+#define DEBUG_MANSTR_NONE               0x00000000
+#define DEBUG_MANSTR_LOADED_SUPPORT_DLL 0x00000001
+#define DEBUG_MANSTR_LOAD_STATUS        0x00000002
+
+//
+// ResetManagedStatus flags.
+//
+
+// Reset state to default engine startup state with
+// no support loaded.
+#define DEBUG_MANRESET_DEFAULT  0x00000000
+// Force managed support DLL load attempt.
+#define DEBUG_MANRESET_LOAD_DLL 0x00000001
+
+#undef INTERFACE
+#define INTERFACE IDebugControl4
+DECLARE_INTERFACE_(IDebugControl4, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugControl.
+
+    // Checks for a user interrupt, such a Ctrl-C
+    // or stop button.
+    // This method is reentrant.
+    STDMETHOD(GetInterrupt)(
+        THIS
+        ) PURE;
+    // Registers a user interrupt.
+    // This method is reentrant.
+    STDMETHOD(SetInterrupt)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Interrupting a user-mode process requires
+    // access to some system resources that the
+    // process may hold itself, preventing the
+    // interrupt from occurring.  The engine
+    // will time-out pending interrupt requests
+    // and simulate an interrupt if necessary.
+    // These methods control the interrupt timeout.
+    STDMETHOD(GetInterruptTimeout)(
+        THIS_
+        _Out_ PULONG Seconds
+        ) PURE;
+    STDMETHOD(SetInterruptTimeout)(
+        THIS_
+        _In_ ULONG Seconds
+        ) PURE;
+
+    STDMETHOD(GetLogFile)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    // Opens a log file which collects all
+    // output.  Output from every client except
+    // those that explicitly disable logging
+    // goes into the log.
+    // Opening a log file closes any log file
+    // already open.
+    STDMETHOD(OpenLogFile)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ BOOL Append
+        ) PURE;
+    STDMETHOD(CloseLogFile)(
+        THIS
+        ) PURE;
+    // Controls what output is logged.
+    STDMETHOD(GetLogMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetLogMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+
+    // Input requests input from all clients.
+    // The first input that is returned is used
+    // to satisfy the call.  Other returned
+    // input is discarded.
+    STDMETHOD(Input)(
+        THIS_
+        _Out_writes_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    // This method is used by clients to return
+    // input when it is available.  It will
+    // return S_OK if the input is used to
+    // satisfy an Input call and S_FALSE if
+    // the input is ignored.
+    // This method is reentrant.
+    STDMETHOD(ReturnInput)(
+        THIS_
+        _In_ PCSTR Buffer
+        ) PURE;
+
+    // Sends output through clients
+    // output callbacks if the mask is allowed
+    // by the current output control mask and
+    // according to the output distribution
+    // settings.
+    STDMETHODV(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaList)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // The following methods allow direct control
+    // over the distribution of the given output
+    // for situations where something other than
+    // the default is desired.  These methods require
+    // extra work in the engine so they should
+    // only be used when necessary.
+    STDMETHODV(ControlledOutput)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    // Displays the standard command-line prompt
+    // followed by the given output.  If Format
+    // is NULL no additional output is produced.
+    // Output is produced under the
+    // DEBUG_OUTPUT_PROMPT mask.
+    // This method only outputs the prompt; it
+    // does not get input.
+    STDMETHODV(OutputPrompt)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // Gets the text that would be displayed by OutputPrompt.
+    STDMETHOD(GetPromptText)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // Outputs information about the current
+    // debuggee state such as a register
+    // summary, disassembly at the current PC,
+    // closest symbol and others.
+    // Uses the line prefix.
+    STDMETHOD(OutputCurrentState)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Outputs the debugger and extension version
+    // information.  This method is reentrant.
+    // Uses the line prefix.
+    STDMETHOD(OutputVersionInformation)(
+        THIS_
+        _In_ ULONG OutputControl
+        ) PURE;
+
+    // In user-mode debugging sessions the
+    // engine will set an event when
+    // exceptions are continued.  This can
+    // be used to synchronize other processes
+    // with the debuggers handling of events.
+    // For example, this is used to support
+    // the e argument to ntsd.
+    STDMETHOD(GetNotifyEventHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(SetNotifyEventHandle)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Assemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(Disassemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Returns the value of the effective address
+    // computed for the last Disassemble, if there
+    // was one.
+    STDMETHOD(GetDisassembleEffectiveOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Uses the line prefix if necessary.
+    STDMETHOD(OutputDisassembly)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Produces multiple lines of disassembly output.
+    // There will be PreviousLines of disassembly before
+    // the given offset if a valid disassembly exists.
+    // In all, there will be TotalLines of output produced.
+    // The first and last line offsets are returned
+    // specially and all lines offsets can be retrieved
+    // through LineOffsets.  LineOffsets will contain
+    // offsets for each line where disassembly started.
+    // When disassembly of a single instruction takes
+    // multiple lines the initial offset will be followed
+    // by DEBUG_INVALID_OFFSET.
+    // Uses the line prefix.
+    STDMETHOD(OutputDisassemblyLines)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG PreviousLines,
+        _In_ ULONG TotalLines,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG OffsetLine,
+        _Out_opt_ PULONG64 StartOffset,
+        _Out_opt_ PULONG64 EndOffset,
+        _Out_writes_opt_(TotalLines) PULONG64 LineOffsets
+        ) PURE;
+    // Returns the offset of the start of
+    // the instruction thats the given
+    // delta away from the instruction
+    // at the initial offset.
+    // This routine does not check for
+    // validity of the instruction or
+    // the memory containing it.
+    STDMETHOD(GetNearInstruction)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_ PULONG64 NearOffset
+        ) PURE;
+
+    // Offsets can be passed in as zero to use the current
+    // thread state.
+    STDMETHOD(GetStackTrace)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    // Does a simple stack trace to determine
+    // what the current return address is.
+    STDMETHOD(GetReturnOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // If Frames is NULL OutputStackTrace will
+    // use GetStackTrace to get FramesSize frames
+    // and then output them.  The current register
+    // values for frame, stack and instruction offsets
+    // are used.
+    // Uses the line prefix.
+    STDMETHOD(OutputStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Returns information about the debuggee such
+    // as user vs. kernel, dump vs. live, etc.
+    STDMETHOD(GetDebuggeeType)(
+        THIS_
+        _Out_ PULONG Class,
+        _Out_ PULONG Qualifier
+        ) PURE;
+    // Returns the type of physical processors in
+    // the machine.
+    // Returns one of the IMAGE_FILE_MACHINE values.
+    STDMETHOD(GetActualProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Returns the type of processor used in the
+    // current processor context.
+    STDMETHOD(GetExecutingProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Query all the possible processor types that
+    // may be encountered during this debug session.
+    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetPossibleExecutingProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Get the number of actual processors in
+    // the machine.
+    STDMETHOD(GetNumberProcessors)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // PlatformId is one of the VER_PLATFORM values.
+    // Major and minor are as given in the NT
+    // kernel debugger protocol.
+    // ServicePackString and ServicePackNumber indicate the
+    // system service pack level.  ServicePackNumber is not
+    // available in some sessions where the service pack level
+    // is only expressed as a string.  The service pack information
+    // will be empty if the system does not have a service pack
+    // applied.
+    // The build string is string information identifying the
+    // particular build of the system.  The build string is
+    // empty if the system has no particular identifying
+    // information.
+    STDMETHOD(GetSystemVersion)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Major,
+        _Out_ PULONG Minor,
+        _Out_writes_opt_(ServicePackStringSize) PSTR ServicePackString,
+        _In_ ULONG ServicePackStringSize,
+        _Out_opt_ PULONG ServicePackStringUsed,
+        _Out_ PULONG ServicePackNumber,
+        _Out_writes_opt_(BuildStringSize) PSTR BuildString,
+        _In_ ULONG BuildStringSize,
+        _Out_opt_ PULONG BuildStringUsed
+        ) PURE;
+    // Returns the page size for the currently executing
+    // processor context.  The page size may vary between
+    // processor types.
+    STDMETHOD(GetPageSize)(
+        THIS_
+        _Out_ PULONG Size
+        ) PURE;
+    // Returns S_OK if the current processor context uses
+    // 64-bit addresses, otherwise S_FALSE.
+    STDMETHOD(IsPointer64Bit)(
+        THIS
+        ) PURE;
+    // Reads the bugcheck data area and returns the
+    // current contents.  This method only works
+    // in kernel debugging sessions.
+    STDMETHOD(ReadBugCheckData)(
+        THIS_
+        _Out_ PULONG Code,
+        _Out_ PULONG64 Arg1,
+        _Out_ PULONG64 Arg2,
+        _Out_ PULONG64 Arg3,
+        _Out_ PULONG64 Arg4
+        ) PURE;
+
+    // Query all the processor types supported by
+    // the engine.  This is a complete list and is
+    // not related to the machine running the engine
+    // or the debuggee.
+    STDMETHOD(GetNumberSupportedProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetSupportedProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Returns a full, descriptive name and an
+    // abbreviated name for a processor type.
+    STDMETHOD(GetProcessorTypeNames)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    // Gets and sets the type of processor to
+    // use when doing things like setting
+    // breakpoints, accessing registers,
+    // getting stack traces and so on.
+    STDMETHOD(GetEffectiveProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(SetEffectiveProcessorType)(
+        THIS_
+        _In_ ULONG Type
+        ) PURE;
+
+    // Returns information about whether and how
+    // the debuggee is running.  Status will
+    // be GO if the debuggee is running and
+    // BREAK if it isnt.
+    // If no debuggee exists the status is
+    // NO_DEBUGGEE.
+    // This method is reentrant.
+    STDMETHOD(GetExecutionStatus)(
+        THIS_
+        _Out_ PULONG Status
+        ) PURE;
+    // Changes the execution status of the
+    // engine from stopped to running.
+    // Status must be one of the go or step
+    // status values.
+    STDMETHOD(SetExecutionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // Controls what code interpretation level the debugger
+    // runs at.  The debugger checks the code level when
+    // deciding whether to step by a source line or
+    // assembly instruction along with other related operations.
+    STDMETHOD(GetCodeLevel)(
+        THIS_
+        _Out_ PULONG Level
+        ) PURE;
+    STDMETHOD(SetCodeLevel)(
+        THIS_
+        _In_ ULONG Level
+        ) PURE;
+
+    // Gets and sets engine control flags.
+    // These methods are reentrant.
+    STDMETHOD(GetEngineOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Gets and sets control values for
+    // handling system error events.
+    // If the system error level is less
+    // than or equal to the given levels
+    // the error may be displayed and
+    // the default break for the event
+    // may be set.
+    STDMETHOD(GetSystemErrorControl)(
+        THIS_
+        _Out_ PULONG OutputLevel,
+        _Out_ PULONG BreakLevel
+        ) PURE;
+    STDMETHOD(SetSystemErrorControl)(
+        THIS_
+        _In_ ULONG OutputLevel,
+        _In_ ULONG BreakLevel
+        ) PURE;
+
+    // The command processor supports simple
+    // string replacement macros in Evaluate and
+    // Execute.  There are currently ten macro
+    // slots available.  Slots 0-9 map to
+    // the command invocations $u0-$u9.
+    STDMETHOD(GetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCSTR Macro
+        ) PURE;
+
+    // Controls the default number radix used
+    // in expressions and commands.
+    STDMETHOD(GetRadix)(
+        THIS_
+        _Out_ PULONG Radix
+        ) PURE;
+    STDMETHOD(SetRadix)(
+        THIS_
+        _In_ ULONG Radix
+        ) PURE;
+
+    // Evaluates the given expression string and
+    // returns the resulting value.
+    // If DesiredType is DEBUG_VALUE_INVALID then
+    // the natural type is used.
+    // RemainderIndex, if provided, is set to the index
+    // of the first character in the input string that was
+    // not used when evaluating the expression.
+    STDMETHOD(Evaluate)(
+        THIS_
+        _In_ PCSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+    // Attempts to convert the input value to a value
+    // of the requested type in the output value.
+    // Conversions can fail if no conversion exists.
+    // Successful conversions may be lossy.
+    STDMETHOD(CoerceValue)(
+        THIS_
+        _In_ PDEBUG_VALUE In,
+        _In_ ULONG OutType,
+        _Out_ PDEBUG_VALUE Out
+        ) PURE;
+    STDMETHOD(CoerceValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_VALUE In,
+        _In_reads_(Count) PULONG OutTypes,
+        _Out_writes_(Count) PDEBUG_VALUE Out
+        ) PURE;
+
+    // Executes the given command string.
+    // If the string has multiple commands
+    // Execute will not return until all
+    // of them have been executed.  If this
+    // requires waiting for the debuggee to
+    // execute an internal wait will be done
+    // so Execute can take an arbitrary amount
+    // of time.
+    STDMETHOD(Execute)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    // Executes the given command file by
+    // reading a line at a time and processing
+    // it with Execute.
+    STDMETHOD(ExecuteCommandFile)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Breakpoint interfaces are described
+    // elsewhere in this section.
+    STDMETHOD(GetNumberBreakpoints)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // It is possible for this retrieval function to
+    // fail even with an index within the number of
+    // existing breakpoints if the breakpoint is
+    // a private breakpoint.
+    STDMETHOD(GetBreakpointByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // If Ids is non-NULL the Count breakpoints
+    // referred to in the Ids array are returned,
+    // otherwise breakpoints from index Start to
+    // Start + Count  1 are returned.
+    STDMETHOD(GetBreakpointParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Ids,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+    // Breakpoints are created empty and disabled.
+    // When their parameters have been set they
+    // should be enabled by setting the ENABLE flag.
+    // If DesiredId is DEBUG_ANY_ID then the
+    // engine picks an unused ID.  If DesiredId
+    // is any other number the engine attempts
+    // to use the given ID for the breakpoint.
+    // If another breakpoint exists with that ID
+    // the call will fail.
+    STDMETHOD(AddBreakpoint)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // Breakpoint interface is invalid after this call.
+    STDMETHOD(RemoveBreakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT Bp
+        ) PURE;
+
+    // Control and use extension DLLs.
+    STDMETHOD(AddExtension)(
+        THIS_
+        _In_ PCSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(RemoveExtension)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPath)(
+        THIS_
+        _In_ PCSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Handle is zero the extension
+    // chain is walked searching for the
+    // function.
+    STDMETHOD(CallExtension)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR Function,
+        _In_opt_ PCSTR Arguments
+        ) PURE;
+    // GetExtensionFunction works like
+    // GetProcAddress on extension DLLs
+    // to allow raw function-call-level
+    // interaction with extension DLLs.
+    // Such functions do not need to
+    // follow the standard extension prototype
+    // if they are not going to be called
+    // through the text extension interface.
+    // This function cannot be called remotely.
+    STDMETHOD(GetExtensionFunction)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+    // These methods return alternate
+    // extension interfaces in order to allow
+    // interface-style extension DLLs to mix in
+    // older extension calls.
+    // Structure sizes must be initialized before
+    // the call.
+    // These methods cannot be called remotely.
+    STDMETHOD(GetWindbgExtensionApis32)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS32 Api
+        ) PURE;
+    STDMETHOD(GetWindbgExtensionApis64)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS64 Api
+        ) PURE;
+
+    // The engine provides a simple mechanism
+    // to filter common events.  Arbitrarily complicated
+    // filtering can be done by registering event callbacks
+    // but simple event filtering only requires
+    // setting the options of one of the predefined
+    // event filters.
+    // Simple event filters are either for specific
+    // events and therefore have an enumerant or
+    // they are for an exception and are based on
+    // the exceptions code.  Exception filters
+    // are further divided into exceptions specially
+    // handled by the engine, which is a fixed set,
+    // and arbitrary exceptions.
+    // All three groups of filters are indexed together
+    // with the specific filters first, then the specific
+    // exception filters and finally the arbitrary
+    // exception filters.
+    // The first specific exception is the default
+    // exception.  If an exception event occurs for
+    // an exception without settings the default
+    // exception settings are used.
+    STDMETHOD(GetNumberEventFilters)(
+        THIS_
+        _Out_ PULONG SpecificEvents,
+        _Out_ PULONG SpecificExceptions,
+        _Out_ PULONG ArbitraryExceptions
+        ) PURE;
+    // Some filters have descriptive text associated with them.
+    STDMETHOD(GetEventFilterText)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // All filters support executing a command when the
+    // event occurs.
+    STDMETHOD(GetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    STDMETHOD(SetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    // Some specific filters have arguments to further
+    // qualify their operation.
+    STDMETHOD(GetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Argument
+        ) PURE;
+    // If Codes is non-NULL Start is ignored.
+    STDMETHOD(GetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Codes,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // The codes in the parameter data control the application
+    // of the parameter data.  If a code is not already in
+    // the set of filters it is added.  If the ExecutionOption
+    // for a code is REMOVE then the filter is removed.
+    // Specific exception filters cannot be removed.
+    STDMETHOD(SetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // Exception filters support an additional command for
+    // second-chance events.
+    STDMETHOD(GetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Yields processing to the engine until
+    // an event occurs.  This method may
+    // only be called by the thread that started
+    // the debug session.
+    // When an event occurs the engine carries
+    // out all event processing such as calling
+    // callbacks.
+    // If the callbacks indicate that execution should
+    // break the wait will return, otherwise it
+    // goes back to waiting for a new event.
+    // If the timeout expires, S_FALSE is returned.
+    // The timeout is not currently supported for
+    // kernel debugging.
+    STDMETHOD(WaitForEvent)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Retrieves information about the last event that occurred.
+    // EventType is one of the event callback mask bits.
+    // ExtraInformation contains additional event-specific
+    // information.  Not all events have additional information.
+    STDMETHOD(GetLastEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    // IDebugControl2.
+
+    STDMETHOD(GetCurrentTimeDate)(
+        THIS_
+        _Out_ PULONG TimeDate
+        ) PURE;
+    // Retrieves the number of seconds since the
+    // machine started running.
+    STDMETHOD(GetCurrentSystemUpTime)(
+        THIS_
+        _Out_ PULONG UpTime
+        ) PURE;
+
+    // If the current session is a dump session,
+    // retrieves any extended format information.
+    STDMETHOD(GetDumpFormatFlags)(
+        THIS_
+        _Out_ PULONG FormatFlags
+        ) PURE;
+
+    // The debugger has been enhanced to allow
+    // arbitrary text replacements in addition
+    // to the simple $u0-$u9 text macros.
+    // Text replacement takes a given source
+    // text in commands and converts it to the
+    // given destination text.  Replacements
+    // are named by their source text so that
+    // only one replacement for a source text
+    // string can exist.
+    STDMETHOD(GetNumberTextReplacements)(
+        THIS_
+        _Out_ PULONG NumRepl
+        ) PURE;
+    // If SrcText is non-NULL the replacement
+    // is looked up by source text, otherwise
+    // Index is used to get the Nth replacement.
+    STDMETHOD(GetTextReplacement)(
+        THIS_
+        _In_opt_ PCSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    // Setting the destination text to
+    // NULL removes the alias.
+    STDMETHOD(SetTextReplacement)(
+        THIS_
+        _In_ PCSTR SrcText,
+        _In_opt_ PCSTR DstText
+        ) PURE;
+    STDMETHOD(RemoveTextReplacements)(
+        THIS
+        ) PURE;
+    // Outputs the complete list of current
+    // replacements.
+    STDMETHOD(OutputTextReplacements)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // IDebugControl3.
+
+    // Control options for assembly and disassembly.
+    STDMETHOD(GetAssemblyOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Control the expression syntax.
+    STDMETHOD(GetExpressionSyntax)(
+        THIS_
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(SetExpressionSyntax)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Look up a syntax by its abbreviated
+    // name and set it.
+    STDMETHOD(SetExpressionSyntaxByName)(
+        THIS_
+        _In_ PCSTR AbbrevName
+        ) PURE;
+    STDMETHOD(GetNumberExpressionSyntaxes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetExpressionSyntaxNames)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    //
+    // Some debug sessions have only a single
+    // possible event, such as a snapshot dump
+    // file; some have dynamic events, such as
+    // a live debug session; and others may have
+    // multiple events, such as a dump file that
+    // contains snapshots from different points
+    // in time.  The following methods allow
+    // discovery and selection of the available
+    // events for a session.
+    // Sessions with one or more static events
+    // will be able to report all of the events
+    // when queried.  Sessions with dynamic events
+    // will only report a single event representing
+    // the current event.
+    // Switching events constitutes execution and
+    // changing the current event will alter the
+    // execution status to a running state, after
+    // which WaitForEvent must be used to process
+    // the selected event.
+    //
+
+    // GetNumberEvents returns S_OK if this is the
+    // complete set of events possible, such as for
+    // a static session; or S_FALSE if other events
+    // may be possible, such as for a dynamic session.
+    STDMETHOD(GetNumberEvents)(
+        THIS_
+        _Out_ PULONG Events
+        ) PURE;
+    // Sessions may have descriptive information for
+    // the various events available.  The amount of
+    // information varies according to the specific
+    // session and data.
+    STDMETHOD(GetEventIndexDescription)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG Which,
+        _In_opt_ PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DescSize
+        ) PURE;
+    STDMETHOD(GetCurrentEventIndex)(
+        THIS_
+        _Out_ PULONG Index
+        ) PURE;
+    // SetNextEventIndex works like seek in that
+    // it can set an absolute or relative index.
+    // SetNextEventIndex works similarly to SetExecutionStatus
+    // by putting the session into a running state, after
+    // which the caller must call WaitForEvent.  The
+    // current event index only changes when WaitForEvent
+    // is called.
+    STDMETHOD(SetNextEventIndex)(
+        THIS_
+        _In_ ULONG Relation,
+        _In_ ULONG Value,
+        _Out_ PULONG NextIndex
+        ) PURE;
+
+    // IDebugControl4.
+
+    STDMETHOD(GetLogFileWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    STDMETHOD(OpenLogFileWide)(
+        THIS_
+        _In_ PCWSTR File,
+        _In_ BOOL Append
+        ) PURE;
+
+    STDMETHOD(InputWide)(
+        THIS_
+        _Out_writes_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    STDMETHOD(ReturnInputWide)(
+        THIS_
+        _In_ PCWSTR Buffer
+        ) PURE;
+
+    STDMETHODV(OutputWide)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaListWide)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    STDMETHODV(ControlledOutputWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaListWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    STDMETHODV(OutputPromptWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaListWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    STDMETHOD(GetPromptTextWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+
+    STDMETHOD(AssembleWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCWSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(DisassembleWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+
+    STDMETHOD(GetProcessorTypeNamesWide)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PWSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    STDMETHOD(GetTextMacroWide)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacroWide)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCWSTR Macro
+        ) PURE;
+
+    STDMETHOD(EvaluateWide)(
+        THIS_
+        _In_ PCWSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+
+    STDMETHOD(ExecuteWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(ExecuteCommandFileWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetBreakpointByIndex2)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById2)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(AddBreakpoint2)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(RemoveBreakpoint2)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT2 Bp
+        ) PURE;
+
+    STDMETHOD(AddExtensionWide)(
+        THIS_
+        _In_ PCWSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPathWide)(
+        THIS_
+        _In_ PCWSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(CallExtensionWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCWSTR Function,
+        _In_opt_ PCWSTR Arguments
+        ) PURE;
+    STDMETHOD(GetExtensionFunctionWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCWSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+
+    STDMETHOD(GetEventFilterTextWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    STDMETHOD(GetEventFilterCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterArgumentWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgumentWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Argument
+        ) PURE;
+    STDMETHOD(GetExceptionFilterSecondCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Command
+        ) PURE;
+
+    STDMETHOD(GetLastEventInformationWide)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PWSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    STDMETHOD(GetTextReplacementWide)(
+        THIS_
+        _In_opt_ PCWSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PWSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PWSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    STDMETHOD(SetTextReplacementWide)(
+        THIS_
+        _In_ PCWSTR SrcText,
+        _In_opt_ PCWSTR DstText
+        ) PURE;
+
+    STDMETHOD(SetExpressionSyntaxByNameWide)(
+        THIS_
+        _In_ PCWSTR AbbrevName
+        ) PURE;
+    STDMETHOD(GetExpressionSyntaxNamesWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(FullNameBufferSize) PWSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    STDMETHOD(GetEventIndexDescriptionWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG Which,
+        _In_opt_ PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DescSize
+        ) PURE;
+
+    STDMETHOD(GetLogFile2)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(OpenLogFile2)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(GetLogFile2Wide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(OpenLogFile2Wide)(
+        THIS_
+        _In_ PCWSTR File,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // GetSystemVersion always returns the kd
+    // major/minor version numbers, which are
+    // different than the Win32 version numbers.
+    // GetSystemVersionValues can be used
+    // to determine the Win32 version values.
+    STDMETHOD(GetSystemVersionValues)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Win32Major,
+        _Out_ PULONG Win32Minor,
+        _Out_opt_ PULONG KdMajor,
+        _Out_opt_ PULONG KdMinor
+        ) PURE;
+    // Strings are selected with DEBUG_SYSVERSTR_*.
+    STDMETHOD(GetSystemVersionString)(
+        THIS_
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSystemVersionStringWide)(
+        THIS_
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+
+    // Stack tracing with a full initial context
+    // and full context return for each frame.
+    // The FrameContextsSize parameter is the total
+    // byte size of FrameContexts.  FrameContextsEntrySize
+    // gives the byte size of each entry in
+    // FrameContexts.
+    STDMETHOD(GetContextStackTrace)(
+        THIS_
+        _In_reads_bytes_opt_(StartContextSize) PVOID StartContext,
+        _In_ ULONG StartContextSize,
+        _Out_writes_opt_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_writes_bytes_opt_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    STDMETHOD(OutputContextStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_reads_bytes_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Some targets, such as user-mode minidump files,
+    // have separate "event of interest" information
+    // stored within them.  This method allows
+    // access to that information.
+    STDMETHOD(GetStoredEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize,
+        _Out_opt_ PULONG ContextUsed,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed
+        ) PURE;
+
+    // Managed debugging support relies on debugging
+    // functionality provided by the Common Language Runtime.
+    // This method provides feedback on the engine's
+    // use of the runtime debugging APIs.
+    STDMETHOD(GetManagedStatus)(
+        THIS_
+        _Out_opt_ PULONG Flags,
+        _In_ ULONG WhichString,
+        _Out_writes_opt_(StringSize) PSTR String,
+        _In_ ULONG StringSize,
+        _Out_opt_ PULONG StringNeeded
+        ) PURE;
+    STDMETHOD(GetManagedStatusWide)(
+        THIS_
+        _Out_opt_ PULONG Flags,
+        _In_ ULONG WhichString,
+        _Out_writes_opt_(StringSize) PWSTR String,
+        _In_ ULONG StringSize,
+        _Out_opt_ PULONG StringNeeded
+        ) PURE;
+    // Clears and reinitializes the engine's
+    // managed code debugging support.
+    STDMETHOD(ResetManagedStatus)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugControl5
+DECLARE_INTERFACE_(IDebugControl5, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugControl.
+
+    // Checks for a user interrupt, such a Ctrl-C
+    // or stop button.
+    // This method is reentrant.
+    STDMETHOD(GetInterrupt)(
+        THIS
+        ) PURE;
+    // Registers a user interrupt.
+    // This method is reentrant.
+    STDMETHOD(SetInterrupt)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Interrupting a user-mode process requires
+    // access to some system resources that the
+    // process may hold itself, preventing the
+    // interrupt from occurring.  The engine
+    // will time-out pending interrupt requests
+    // and simulate an interrupt if necessary.
+    // These methods control the interrupt timeout.
+    STDMETHOD(GetInterruptTimeout)(
+        THIS_
+        _Out_ PULONG Seconds
+        ) PURE;
+    STDMETHOD(SetInterruptTimeout)(
+        THIS_
+        _In_ ULONG Seconds
+        ) PURE;
+
+    STDMETHOD(GetLogFile)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    // Opens a log file which collects all
+    // output.  Output from every client except
+    // those that explicitly disable logging
+    // goes into the log.
+    // Opening a log file closes any log file
+    // already open.
+    STDMETHOD(OpenLogFile)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ BOOL Append
+        ) PURE;
+    STDMETHOD(CloseLogFile)(
+        THIS
+        ) PURE;
+    // Controls what output is logged.
+    STDMETHOD(GetLogMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetLogMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+
+    // Input requests input from all clients.
+    // The first input that is returned is used
+    // to satisfy the call.  Other returned
+    // input is discarded.
+    STDMETHOD(Input)(
+        THIS_
+        _Out_writes_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    // This method is used by clients to return
+    // input when it is available.  It will
+    // return S_OK if the input is used to
+    // satisfy an Input call and S_FALSE if
+    // the input is ignored.
+    // This method is reentrant.
+    STDMETHOD(ReturnInput)(
+        THIS_
+        _In_ PCSTR Buffer
+        ) PURE;
+
+    // Sends output through clients
+    // output callbacks if the mask is allowed
+    // by the current output control mask and
+    // according to the output distribution
+    // settings.
+    STDMETHODV(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaList)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // The following methods allow direct control
+    // over the distribution of the given output
+    // for situations where something other than
+    // the default is desired.  These methods require
+    // extra work in the engine so they should
+    // only be used when necessary.
+    STDMETHODV(ControlledOutput)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    // Displays the standard command-line prompt
+    // followed by the given output.  If Format
+    // is NULL no additional output is produced.
+    // Output is produced under the
+    // DEBUG_OUTPUT_PROMPT mask.
+    // This method only outputs the prompt; it
+    // does not get input.
+    STDMETHODV(OutputPrompt)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // Gets the text that would be displayed by OutputPrompt.
+    STDMETHOD(GetPromptText)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // Outputs information about the current
+    // debuggee state such as a register
+    // summary, disassembly at the current PC,
+    // closest symbol and others.
+    // Uses the line prefix.
+    STDMETHOD(OutputCurrentState)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Outputs the debugger and extension version
+    // information.  This method is reentrant.
+    // Uses the line prefix.
+    STDMETHOD(OutputVersionInformation)(
+        THIS_
+        _In_ ULONG OutputControl
+        ) PURE;
+
+    // In user-mode debugging sessions the
+    // engine will set an event when
+    // exceptions are continued.  This can
+    // be used to synchronize other processes
+    // with the debuggers handling of events.
+    // For example, this is used to support
+    // the e argument to ntsd.
+    STDMETHOD(GetNotifyEventHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(SetNotifyEventHandle)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Assemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(Disassemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Returns the value of the effective address
+    // computed for the last Disassemble, if there
+    // was one.
+    STDMETHOD(GetDisassembleEffectiveOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Uses the line prefix if necessary.
+    STDMETHOD(OutputDisassembly)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Produces multiple lines of disassembly output.
+    // There will be PreviousLines of disassembly before
+    // the given offset if a valid disassembly exists.
+    // In all, there will be TotalLines of output produced.
+    // The first and last line offsets are returned
+    // specially and all lines offsets can be retrieved
+    // through LineOffsets.  LineOffsets will contain
+    // offsets for each line where disassembly started.
+    // When disassembly of a single instruction takes
+    // multiple lines the initial offset will be followed
+    // by DEBUG_INVALID_OFFSET.
+    // Uses the line prefix.
+    STDMETHOD(OutputDisassemblyLines)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG PreviousLines,
+        _In_ ULONG TotalLines,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG OffsetLine,
+        _Out_opt_ PULONG64 StartOffset,
+        _Out_opt_ PULONG64 EndOffset,
+        _Out_writes_opt_(TotalLines) PULONG64 LineOffsets
+        ) PURE;
+    // Returns the offset of the start of
+    // the instruction thats the given
+    // delta away from the instruction
+    // at the initial offset.
+    // This routine does not check for
+    // validity of the instruction or
+    // the memory containing it.
+    STDMETHOD(GetNearInstruction)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_ PULONG64 NearOffset
+        ) PURE;
+
+    // Offsets can be passed in as zero to use the current
+    // thread state.
+    STDMETHOD(GetStackTrace)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_to_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    // Does a simple stack trace to determine
+    // what the current return address is.
+    STDMETHOD(GetReturnOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // If Frames is NULL OutputStackTrace will
+    // use GetStackTrace to get FramesSize frames
+    // and then output them.  The current register
+    // values for frame, stack and instruction offsets
+    // are used.
+    // Uses the line prefix.
+    STDMETHOD(OutputStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Returns information about the debuggee such
+    // as user vs. kernel, dump vs. live, etc.
+    STDMETHOD(GetDebuggeeType)(
+        THIS_
+        _Out_ PULONG Class,
+        _Out_ PULONG Qualifier
+        ) PURE;
+    // Returns the type of physical processors in
+    // the machine.
+    // Returns one of the IMAGE_FILE_MACHINE values.
+    STDMETHOD(GetActualProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Returns the type of processor used in the
+    // current processor context.
+    STDMETHOD(GetExecutingProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Query all the possible processor types that
+    // may be encountered during this debug session.
+    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetPossibleExecutingProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Get the number of actual processors in
+    // the machine.
+    STDMETHOD(GetNumberProcessors)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // PlatformId is one of the VER_PLATFORM values.
+    // Major and minor are as given in the NT
+    // kernel debugger protocol.
+    // ServicePackString and ServicePackNumber indicate the
+    // system service pack level.  ServicePackNumber is not
+    // available in some sessions where the service pack level
+    // is only expressed as a string.  The service pack information
+    // will be empty if the system does not have a service pack
+    // applied.
+    // The build string is string information identifying the
+    // particular build of the system.  The build string is
+    // empty if the system has no particular identifying
+    // information.
+    STDMETHOD(GetSystemVersion)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Major,
+        _Out_ PULONG Minor,
+        _Out_writes_opt_(ServicePackStringSize) PSTR ServicePackString,
+        _In_ ULONG ServicePackStringSize,
+        _Out_opt_ PULONG ServicePackStringUsed,
+        _Out_ PULONG ServicePackNumber,
+        _Out_writes_opt_(BuildStringSize) PSTR BuildString,
+        _In_ ULONG BuildStringSize,
+        _Out_opt_ PULONG BuildStringUsed
+        ) PURE;
+    // Returns the page size for the currently executing
+    // processor context.  The page size may vary between
+    // processor types.
+    STDMETHOD(GetPageSize)(
+        THIS_
+        _Out_ PULONG Size
+        ) PURE;
+    // Returns S_OK if the current processor context uses
+    // 64-bit addresses, otherwise S_FALSE.
+    STDMETHOD(IsPointer64Bit)(
+        THIS
+        ) PURE;
+    // Reads the bugcheck data area and returns the
+    // current contents.  This method only works
+    // in kernel debugging sessions.
+    STDMETHOD(ReadBugCheckData)(
+        THIS_
+        _Out_ PULONG Code,
+        _Out_ PULONG64 Arg1,
+        _Out_ PULONG64 Arg2,
+        _Out_ PULONG64 Arg3,
+        _Out_ PULONG64 Arg4
+        ) PURE;
+
+    // Query all the processor types supported by
+    // the engine.  This is a complete list and is
+    // not related to the machine running the engine
+    // or the debuggee.
+    STDMETHOD(GetNumberSupportedProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetSupportedProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Returns a full, descriptive name and an
+    // abbreviated name for a processor type.
+    STDMETHOD(GetProcessorTypeNames)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    // Gets and sets the type of processor to
+    // use when doing things like setting
+    // breakpoints, accessing registers,
+    // getting stack traces and so on.
+    STDMETHOD(GetEffectiveProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(SetEffectiveProcessorType)(
+        THIS_
+        _In_ ULONG Type
+        ) PURE;
+
+    // Returns information about whether and how
+    // the debuggee is running.  Status will
+    // be GO if the debuggee is running and
+    // BREAK if it isnt.
+    // If no debuggee exists the status is
+    // NO_DEBUGGEE.
+    // This method is reentrant.
+    STDMETHOD(GetExecutionStatus)(
+        THIS_
+        _Out_ PULONG Status
+        ) PURE;
+    // Changes the execution status of the
+    // engine from stopped to running.
+    // Status must be one of the go or step
+    // status values.
+    STDMETHOD(SetExecutionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // Controls what code interpretation level the debugger
+    // runs at.  The debugger checks the code level when
+    // deciding whether to step by a source line or
+    // assembly instruction along with other related operations.
+    STDMETHOD(GetCodeLevel)(
+        THIS_
+        _Out_ PULONG Level
+        ) PURE;
+    STDMETHOD(SetCodeLevel)(
+        THIS_
+        _In_ ULONG Level
+        ) PURE;
+
+    // Gets and sets engine control flags.
+    // These methods are reentrant.
+    STDMETHOD(GetEngineOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Gets and sets control values for
+    // handling system error events.
+    // If the system error level is less
+    // than or equal to the given levels
+    // the error may be displayed and
+    // the default break for the event
+    // may be set.
+    STDMETHOD(GetSystemErrorControl)(
+        THIS_
+        _Out_ PULONG OutputLevel,
+        _Out_ PULONG BreakLevel
+        ) PURE;
+    STDMETHOD(SetSystemErrorControl)(
+        THIS_
+        _In_ ULONG OutputLevel,
+        _In_ ULONG BreakLevel
+        ) PURE;
+
+    // The command processor supports simple
+    // string replacement macros in Evaluate and
+    // Execute.  There are currently ten macro
+    // slots available.  Slots 0-9 map to
+    // the command invocations $u0-$u9.
+    STDMETHOD(GetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCSTR Macro
+        ) PURE;
+
+    // Controls the default number radix used
+    // in expressions and commands.
+    STDMETHOD(GetRadix)(
+        THIS_
+        _Out_ PULONG Radix
+        ) PURE;
+    STDMETHOD(SetRadix)(
+        THIS_
+        _In_ ULONG Radix
+        ) PURE;
+
+    // Evaluates the given expression string and
+    // returns the resulting value.
+    // If DesiredType is DEBUG_VALUE_INVALID then
+    // the natural type is used.
+    // RemainderIndex, if provided, is set to the index
+    // of the first character in the input string that was
+    // not used when evaluating the expression.
+    STDMETHOD(Evaluate)(
+        THIS_
+        _In_ PCSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+    // Attempts to convert the input value to a value
+    // of the requested type in the output value.
+    // Conversions can fail if no conversion exists.
+    // Successful conversions may be lossy.
+    STDMETHOD(CoerceValue)(
+        THIS_
+        _In_ PDEBUG_VALUE In,
+        _In_ ULONG OutType,
+        _Out_ PDEBUG_VALUE Out
+        ) PURE;
+    STDMETHOD(CoerceValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_VALUE In,
+        _In_reads_(Count) PULONG OutTypes,
+        _Out_writes_(Count) PDEBUG_VALUE Out
+        ) PURE;
+
+    // Executes the given command string.
+    // If the string has multiple commands
+    // Execute will not return until all
+    // of them have been executed.  If this
+    // requires waiting for the debuggee to
+    // execute an internal wait will be done
+    // so Execute can take an arbitrary amount
+    // of time.
+    STDMETHOD(Execute)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    // Executes the given command file by
+    // reading a line at a time and processing
+    // it with Execute.
+    STDMETHOD(ExecuteCommandFile)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Breakpoint interfaces are described
+    // elsewhere in this section.
+    STDMETHOD(GetNumberBreakpoints)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // It is possible for this retrieval function to
+    // fail even with an index within the number of
+    // existing breakpoints if the breakpoint is
+    // a private breakpoint.
+    STDMETHOD(GetBreakpointByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // If Ids is non-NULL the Count breakpoints
+    // referred to in the Ids array are returned,
+    // otherwise breakpoints from index Start to
+    // Start + Count  1 are returned.
+    STDMETHOD(GetBreakpointParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Ids,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+    // Breakpoints are created empty and disabled.
+    // When their parameters have been set they
+    // should be enabled by setting the ENABLE flag.
+    // If DesiredId is DEBUG_ANY_ID then the
+    // engine picks an unused ID.  If DesiredId
+    // is any other number the engine attempts
+    // to use the given ID for the breakpoint.
+    // If another breakpoint exists with that ID
+    // the call will fail.
+    STDMETHOD(AddBreakpoint)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // Breakpoint interface is invalid after this call.
+    STDMETHOD(RemoveBreakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT Bp
+        ) PURE;
+
+    // Control and use extension DLLs.
+    STDMETHOD(AddExtension)(
+        THIS_
+        _In_ PCSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(RemoveExtension)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPath)(
+        THIS_
+        _In_ PCSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Handle is zero the extension
+    // chain is walked searching for the
+    // function.
+    STDMETHOD(CallExtension)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR Function,
+        _In_opt_ PCSTR Arguments
+        ) PURE;
+    // GetExtensionFunction works like
+    // GetProcAddress on extension DLLs
+    // to allow raw function-call-level
+    // interaction with extension DLLs.
+    // Such functions do not need to
+    // follow the standard extension prototype
+    // if they are not going to be called
+    // through the text extension interface.
+    // This function cannot be called remotely.
+    STDMETHOD(GetExtensionFunction)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+    // These methods return alternate
+    // extension interfaces in order to allow
+    // interface-style extension DLLs to mix in
+    // older extension calls.
+    // Structure sizes must be initialized before
+    // the call.
+    // These methods cannot be called remotely.
+    STDMETHOD(GetWindbgExtensionApis32)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS32 Api
+        ) PURE;
+    STDMETHOD(GetWindbgExtensionApis64)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS64 Api
+        ) PURE;
+
+    // The engine provides a simple mechanism
+    // to filter common events.  Arbitrarily complicated
+    // filtering can be done by registering event callbacks
+    // but simple event filtering only requires
+    // setting the options of one of the predefined
+    // event filters.
+    // Simple event filters are either for specific
+    // events and therefore have an enumerant or
+    // they are for an exception and are based on
+    // the exceptions code.  Exception filters
+    // are further divided into exceptions specially
+    // handled by the engine, which is a fixed set,
+    // and arbitrary exceptions.
+    // All three groups of filters are indexed together
+    // with the specific filters first, then the specific
+    // exception filters and finally the arbitrary
+    // exception filters.
+    // The first specific exception is the default
+    // exception.  If an exception event occurs for
+    // an exception without settings the default
+    // exception settings are used.
+    STDMETHOD(GetNumberEventFilters)(
+        THIS_
+        _Out_ PULONG SpecificEvents,
+        _Out_ PULONG SpecificExceptions,
+        _Out_ PULONG ArbitraryExceptions
+        ) PURE;
+    // Some filters have descriptive text associated with them.
+    STDMETHOD(GetEventFilterText)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // All filters support executing a command when the
+    // event occurs.
+    STDMETHOD(GetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    STDMETHOD(SetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    // Some specific filters have arguments to further
+    // qualify their operation.
+    STDMETHOD(GetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Argument
+        ) PURE;
+    // If Codes is non-NULL Start is ignored.
+    STDMETHOD(GetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Codes,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // The codes in the parameter data control the application
+    // of the parameter data.  If a code is not already in
+    // the set of filters it is added.  If the ExecutionOption
+    // for a code is REMOVE then the filter is removed.
+    // Specific exception filters cannot be removed.
+    STDMETHOD(SetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // Exception filters support an additional command for
+    // second-chance events.
+    STDMETHOD(GetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Yields processing to the engine until
+    // an event occurs.  This method may
+    // only be called by the thread that started
+    // the debug session.
+    // When an event occurs the engine carries
+    // out all event processing such as calling
+    // callbacks.
+    // If the callbacks indicate that execution should
+    // break the wait will return, otherwise it
+    // goes back to waiting for a new event.
+    // If the timeout expires, S_FALSE is returned.
+    // The timeout is not currently supported for
+    // kernel debugging.
+    STDMETHOD(WaitForEvent)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Retrieves information about the last event that occurred.
+    // EventType is one of the event callback mask bits.
+    // ExtraInformation contains additional event-specific
+    // information.  Not all events have additional information.
+    STDMETHOD(GetLastEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    // IDebugControl2.
+
+    STDMETHOD(GetCurrentTimeDate)(
+        THIS_
+        _Out_ PULONG TimeDate
+        ) PURE;
+    // Retrieves the number of seconds since the
+    // machine started running.
+    STDMETHOD(GetCurrentSystemUpTime)(
+        THIS_
+        _Out_ PULONG UpTime
+        ) PURE;
+
+    // If the current session is a dump session,
+    // retrieves any extended format information.
+    STDMETHOD(GetDumpFormatFlags)(
+        THIS_
+        _Out_ PULONG FormatFlags
+        ) PURE;
+
+    // The debugger has been enhanced to allow
+    // arbitrary text replacements in addition
+    // to the simple $u0-$u9 text macros.
+    // Text replacement takes a given source
+    // text in commands and converts it to the
+    // given destination text.  Replacements
+    // are named by their source text so that
+    // only one replacement for a source text
+    // string can exist.
+    STDMETHOD(GetNumberTextReplacements)(
+        THIS_
+        _Out_ PULONG NumRepl
+        ) PURE;
+    // If SrcText is non-NULL the replacement
+    // is looked up by source text, otherwise
+    // Index is used to get the Nth replacement.
+    STDMETHOD(GetTextReplacement)(
+        THIS_
+        _In_opt_ PCSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    // Setting the destination text to
+    // NULL removes the alias.
+    STDMETHOD(SetTextReplacement)(
+        THIS_
+        _In_ PCSTR SrcText,
+        _In_opt_ PCSTR DstText
+        ) PURE;
+    STDMETHOD(RemoveTextReplacements)(
+        THIS
+        ) PURE;
+    // Outputs the complete list of current
+    // replacements.
+    STDMETHOD(OutputTextReplacements)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // IDebugControl3.
+
+    // Control options for assembly and disassembly.
+    STDMETHOD(GetAssemblyOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Control the expression syntax.
+    STDMETHOD(GetExpressionSyntax)(
+        THIS_
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(SetExpressionSyntax)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Look up a syntax by its abbreviated
+    // name and set it.
+    STDMETHOD(SetExpressionSyntaxByName)(
+        THIS_
+        _In_ PCSTR AbbrevName
+        ) PURE;
+    STDMETHOD(GetNumberExpressionSyntaxes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetExpressionSyntaxNames)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    //
+    // Some debug sessions have only a single
+    // possible event, such as a snapshot dump
+    // file; some have dynamic events, such as
+    // a live debug session; and others may have
+    // multiple events, such as a dump file that
+    // contains snapshots from different points
+    // in time.  The following methods allow
+    // discovery and selection of the available
+    // events for a session.
+    // Sessions with one or more static events
+    // will be able to report all of the events
+    // when queried.  Sessions with dynamic events
+    // will only report a single event representing
+    // the current event.
+    // Switching events constitutes execution and
+    // changing the current event will alter the
+    // execution status to a running state, after
+    // which WaitForEvent must be used to process
+    // the selected event.
+    //
+
+    // GetNumberEvents returns S_OK if this is the
+    // complete set of events possible, such as for
+    // a static session; or S_FALSE if other events
+    // may be possible, such as for a dynamic session.
+    STDMETHOD(GetNumberEvents)(
+        THIS_
+        _Out_ PULONG Events
+        ) PURE;
+    // Sessions may have descriptive information for
+    // the various events available.  The amount of
+    // information varies according to the specific
+    // session and data.
+    STDMETHOD(GetEventIndexDescription)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG Which,
+        _In_opt_ PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DescSize
+        ) PURE;
+    STDMETHOD(GetCurrentEventIndex)(
+        THIS_
+        _Out_ PULONG Index
+        ) PURE;
+    // SetNextEventIndex works like seek in that
+    // it can set an absolute or relative index.
+    // SetNextEventIndex works similarly to SetExecutionStatus
+    // by putting the session into a running state, after
+    // which the caller must call WaitForEvent.  The
+    // current event index only changes when WaitForEvent
+    // is called.
+    STDMETHOD(SetNextEventIndex)(
+        THIS_
+        _In_ ULONG Relation,
+        _In_ ULONG Value,
+        _Out_ PULONG NextIndex
+        ) PURE;
+
+    // IDebugControl4.
+
+    STDMETHOD(GetLogFileWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    STDMETHOD(OpenLogFileWide)(
+        THIS_
+        _In_ PCWSTR File,
+        _In_ BOOL Append
+        ) PURE;
+
+    STDMETHOD(InputWide)(
+        THIS_
+        _Out_writes_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    STDMETHOD(ReturnInputWide)(
+        THIS_
+        _In_ PCWSTR Buffer
+        ) PURE;
+
+    STDMETHODV(OutputWide)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaListWide)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    STDMETHODV(ControlledOutputWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaListWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    STDMETHODV(OutputPromptWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaListWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    STDMETHOD(GetPromptTextWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+
+    STDMETHOD(AssembleWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCWSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(DisassembleWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+
+    STDMETHOD(GetProcessorTypeNamesWide)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PWSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    STDMETHOD(GetTextMacroWide)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacroWide)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCWSTR Macro
+        ) PURE;
+
+    STDMETHOD(EvaluateWide)(
+        THIS_
+        _In_ PCWSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+
+    STDMETHOD(ExecuteWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(ExecuteCommandFileWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetBreakpointByIndex2)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById2)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(AddBreakpoint2)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(RemoveBreakpoint2)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT2 Bp
+        ) PURE;
+
+    STDMETHOD(AddExtensionWide)(
+        THIS_
+        _In_ PCWSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPathWide)(
+        THIS_
+        _In_ PCWSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(CallExtensionWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCWSTR Function,
+        _In_opt_ PCWSTR Arguments
+        ) PURE;
+    STDMETHOD(GetExtensionFunctionWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCWSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+
+    STDMETHOD(GetEventFilterTextWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    STDMETHOD(GetEventFilterCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterArgumentWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgumentWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Argument
+        ) PURE;
+    STDMETHOD(GetExceptionFilterSecondCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Command
+        ) PURE;
+
+    STDMETHOD(GetLastEventInformationWide)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PWSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    STDMETHOD(GetTextReplacementWide)(
+        THIS_
+        _In_opt_ PCWSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PWSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PWSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    STDMETHOD(SetTextReplacementWide)(
+        THIS_
+        _In_ PCWSTR SrcText,
+        _In_opt_ PCWSTR DstText
+        ) PURE;
+
+    STDMETHOD(SetExpressionSyntaxByNameWide)(
+        THIS_
+        _In_ PCWSTR AbbrevName
+        ) PURE;
+    STDMETHOD(GetExpressionSyntaxNamesWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(FullNameBufferSize) PWSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    STDMETHOD(GetEventIndexDescriptionWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG Which,
+        _In_opt_ PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DescSize
+        ) PURE;
+
+    STDMETHOD(GetLogFile2)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(OpenLogFile2)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(GetLogFile2Wide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(OpenLogFile2Wide)(
+        THIS_
+        _In_ PCWSTR File,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // GetSystemVersion always returns the kd
+    // major/minor version numbers, which are
+    // different than the Win32 version numbers.
+    // GetSystemVersionValues can be used
+    // to determine the Win32 version values.
+    STDMETHOD(GetSystemVersionValues)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Win32Major,
+        _Out_ PULONG Win32Minor,
+        _Out_opt_ PULONG KdMajor,
+        _Out_opt_ PULONG KdMinor
+        ) PURE;
+    // Strings are selected with DEBUG_SYSVERSTR_*.
+    STDMETHOD(GetSystemVersionString)(
+        THIS_
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSystemVersionStringWide)(
+        THIS_
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+
+    // Stack tracing with a full initial context
+    // and full context return for each frame.
+    // The FrameContextsSize parameter is the total
+    // byte size of FrameContexts.  FrameContextsEntrySize
+    // gives the byte size of each entry in
+    // FrameContexts.
+    STDMETHOD(GetContextStackTrace)(
+        THIS_
+        _In_reads_bytes_opt_(StartContextSize) PVOID StartContext,
+        _In_ ULONG StartContextSize,
+        _Out_writes_to_opt_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_writes_bytes_opt_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    STDMETHOD(OutputContextStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_reads_bytes_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Some targets, such as user-mode minidump files,
+    // have separate "event of interest" information
+    // stored within them.  This method allows
+    // access to that information.
+    STDMETHOD(GetStoredEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize,
+        _Out_opt_ PULONG ContextUsed,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed
+        ) PURE;
+
+    // Managed debugging support relies on debugging
+    // functionality provided by the Common Language Runtime.
+    // This method provides feedback on the engine's
+    // use of the runtime debugging APIs.
+    STDMETHOD(GetManagedStatus)(
+        THIS_
+        _Out_opt_ PULONG Flags,
+        _In_ ULONG WhichString,
+        _Out_writes_opt_(StringSize) PSTR String,
+        _In_ ULONG StringSize,
+        _Out_opt_ PULONG StringNeeded
+        ) PURE;
+    STDMETHOD(GetManagedStatusWide)(
+        THIS_
+        _Out_opt_ PULONG Flags,
+        _In_ ULONG WhichString,
+        _Out_writes_opt_(StringSize) PWSTR String,
+        _In_ ULONG StringSize,
+        _Out_opt_ PULONG StringNeeded
+        ) PURE;
+    // Clears and reinitializes the engine's
+    // managed code debugging support.
+    STDMETHOD(ResetManagedStatus)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+
+    // IDebugControl5
+    STDMETHOD(GetStackTraceEx)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_to_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+
+    STDMETHOD(OutputStackTraceEx)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetContextStackTraceEx)(
+        THIS_
+        _In_reads_bytes_opt_(StartContextSize) PVOID StartContext,
+        _In_ ULONG StartContextSize,
+        _Out_writes_to_opt_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _Out_writes_bytes_opt_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+
+    STDMETHOD(OutputContextStackTraceEx)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_(FramesSize) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _In_reads_bytes_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _In_ ULONG Flags
+        ) PURE;
+        
+    STDMETHOD(GetBreakpointByGuid)(
+        THIS_
+        _In_ LPGUID Guid,
+        _Out_ PDEBUG_BREAKPOINT3* Bp
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugControl6
+DECLARE_INTERFACE_(IDebugControl6, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugControl.
+
+    // Checks for a user interrupt, such a Ctrl-C
+    // or stop button.
+    // This method is reentrant.
+    STDMETHOD(GetInterrupt)(
+        THIS
+        ) PURE;
+    // Registers a user interrupt.
+    // This method is reentrant.
+    STDMETHOD(SetInterrupt)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Interrupting a user-mode process requires
+    // access to some system resources that the
+    // process may hold itself, preventing the
+    // interrupt from occurring.  The engine
+    // will time-out pending interrupt requests
+    // and simulate an interrupt if necessary.
+    // These methods control the interrupt timeout.
+    STDMETHOD(GetInterruptTimeout)(
+        THIS_
+        _Out_ PULONG Seconds
+        ) PURE;
+    STDMETHOD(SetInterruptTimeout)(
+        THIS_
+        _In_ ULONG Seconds
+        ) PURE;
+
+    STDMETHOD(GetLogFile)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    // Opens a log file which collects all
+    // output.  Output from every client except
+    // those that explicitly disable logging
+    // goes into the log.
+    // Opening a log file closes any log file
+    // already open.
+    STDMETHOD(OpenLogFile)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ BOOL Append
+        ) PURE;
+    STDMETHOD(CloseLogFile)(
+        THIS
+        ) PURE;
+    // Controls what output is logged.
+    STDMETHOD(GetLogMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetLogMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+
+    // Input requests input from all clients.
+    // The first input that is returned is used
+    // to satisfy the call.  Other returned
+    // input is discarded.
+    STDMETHOD(Input)(
+        THIS_
+        _Out_writes_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    // This method is used by clients to return
+    // input when it is available.  It will
+    // return S_OK if the input is used to
+    // satisfy an Input call and S_FALSE if
+    // the input is ignored.
+    // This method is reentrant.
+    STDMETHOD(ReturnInput)(
+        THIS_
+        _In_ PCSTR Buffer
+        ) PURE;
+
+    // Sends output through clients
+    // output callbacks if the mask is allowed
+    // by the current output control mask and
+    // according to the output distribution
+    // settings.
+    STDMETHODV(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaList)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // The following methods allow direct control
+    // over the distribution of the given output
+    // for situations where something other than
+    // the default is desired.  These methods require
+    // extra work in the engine so they should
+    // only be used when necessary.
+    STDMETHODV(ControlledOutput)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    // Displays the standard command-line prompt
+    // followed by the given output.  If Format
+    // is NULL no additional output is produced.
+    // Output is produced under the
+    // DEBUG_OUTPUT_PROMPT mask.
+    // This method only outputs the prompt; it
+    // does not get input.
+    STDMETHODV(OutputPrompt)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // Gets the text that would be displayed by OutputPrompt.
+    STDMETHOD(GetPromptText)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // Outputs information about the current
+    // debuggee state such as a register
+    // summary, disassembly at the current PC,
+    // closest symbol and others.
+    // Uses the line prefix.
+    STDMETHOD(OutputCurrentState)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Outputs the debugger and extension version
+    // information.  This method is reentrant.
+    // Uses the line prefix.
+    STDMETHOD(OutputVersionInformation)(
+        THIS_
+        _In_ ULONG OutputControl
+        ) PURE;
+
+    // In user-mode debugging sessions the
+    // engine will set an event when
+    // exceptions are continued.  This can
+    // be used to synchronize other processes
+    // with the debuggers handling of events.
+    // For example, this is used to support
+    // the e argument to ntsd.
+    STDMETHOD(GetNotifyEventHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(SetNotifyEventHandle)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Assemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(Disassemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Returns the value of the effective address
+    // computed for the last Disassemble, if there
+    // was one.
+    STDMETHOD(GetDisassembleEffectiveOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Uses the line prefix if necessary.
+    STDMETHOD(OutputDisassembly)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Produces multiple lines of disassembly output.
+    // There will be PreviousLines of disassembly before
+    // the given offset if a valid disassembly exists.
+    // In all, there will be TotalLines of output produced.
+    // The first and last line offsets are returned
+    // specially and all lines offsets can be retrieved
+    // through LineOffsets.  LineOffsets will contain
+    // offsets for each line where disassembly started.
+    // When disassembly of a single instruction takes
+    // multiple lines the initial offset will be followed
+    // by DEBUG_INVALID_OFFSET.
+    // Uses the line prefix.
+    STDMETHOD(OutputDisassemblyLines)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG PreviousLines,
+        _In_ ULONG TotalLines,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG OffsetLine,
+        _Out_opt_ PULONG64 StartOffset,
+        _Out_opt_ PULONG64 EndOffset,
+        _Out_writes_opt_(TotalLines) PULONG64 LineOffsets
+        ) PURE;
+    // Returns the offset of the start of
+    // the instruction thats the given
+    // delta away from the instruction
+    // at the initial offset.
+    // This routine does not check for
+    // validity of the instruction or
+    // the memory containing it.
+    STDMETHOD(GetNearInstruction)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_ PULONG64 NearOffset
+        ) PURE;
+
+    // Offsets can be passed in as zero to use the current
+    // thread state.
+    STDMETHOD(GetStackTrace)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_to_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    // Does a simple stack trace to determine
+    // what the current return address is.
+    STDMETHOD(GetReturnOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // If Frames is NULL OutputStackTrace will
+    // use GetStackTrace to get FramesSize frames
+    // and then output them.  The current register
+    // values for frame, stack and instruction offsets
+    // are used.
+    // Uses the line prefix.
+    STDMETHOD(OutputStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Returns information about the debuggee such
+    // as user vs. kernel, dump vs. live, etc.
+    STDMETHOD(GetDebuggeeType)(
+        THIS_
+        _Out_ PULONG Class,
+        _Out_ PULONG Qualifier
+        ) PURE;
+    // Returns the type of physical processors in
+    // the machine.
+    // Returns one of the IMAGE_FILE_MACHINE values.
+    STDMETHOD(GetActualProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Returns the type of processor used in the
+    // current processor context.
+    STDMETHOD(GetExecutingProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Query all the possible processor types that
+    // may be encountered during this debug session.
+    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetPossibleExecutingProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Get the number of actual processors in
+    // the machine.
+    STDMETHOD(GetNumberProcessors)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // PlatformId is one of the VER_PLATFORM values.
+    // Major and minor are as given in the NT
+    // kernel debugger protocol.
+    // ServicePackString and ServicePackNumber indicate the
+    // system service pack level.  ServicePackNumber is not
+    // available in some sessions where the service pack level
+    // is only expressed as a string.  The service pack information
+    // will be empty if the system does not have a service pack
+    // applied.
+    // The build string is string information identifying the
+    // particular build of the system.  The build string is
+    // empty if the system has no particular identifying
+    // information.
+    STDMETHOD(GetSystemVersion)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Major,
+        _Out_ PULONG Minor,
+        _Out_writes_opt_(ServicePackStringSize) PSTR ServicePackString,
+        _In_ ULONG ServicePackStringSize,
+        _Out_opt_ PULONG ServicePackStringUsed,
+        _Out_ PULONG ServicePackNumber,
+        _Out_writes_opt_(BuildStringSize) PSTR BuildString,
+        _In_ ULONG BuildStringSize,
+        _Out_opt_ PULONG BuildStringUsed
+        ) PURE;
+    // Returns the page size for the currently executing
+    // processor context.  The page size may vary between
+    // processor types.
+    STDMETHOD(GetPageSize)(
+        THIS_
+        _Out_ PULONG Size
+        ) PURE;
+    // Returns S_OK if the current processor context uses
+    // 64-bit addresses, otherwise S_FALSE.
+    STDMETHOD(IsPointer64Bit)(
+        THIS
+        ) PURE;
+    // Reads the bugcheck data area and returns the
+    // current contents.  This method only works
+    // in kernel debugging sessions.
+    STDMETHOD(ReadBugCheckData)(
+        THIS_
+        _Out_ PULONG Code,
+        _Out_ PULONG64 Arg1,
+        _Out_ PULONG64 Arg2,
+        _Out_ PULONG64 Arg3,
+        _Out_ PULONG64 Arg4
+        ) PURE;
+
+    // Query all the processor types supported by
+    // the engine.  This is a complete list and is
+    // not related to the machine running the engine
+    // or the debuggee.
+    STDMETHOD(GetNumberSupportedProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetSupportedProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Returns a full, descriptive name and an
+    // abbreviated name for a processor type.
+    STDMETHOD(GetProcessorTypeNames)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    // Gets and sets the type of processor to
+    // use when doing things like setting
+    // breakpoints, accessing registers,
+    // getting stack traces and so on.
+    STDMETHOD(GetEffectiveProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(SetEffectiveProcessorType)(
+        THIS_
+        _In_ ULONG Type
+        ) PURE;
+
+    // Returns information about whether and how
+    // the debuggee is running.  Status will
+    // be GO if the debuggee is running and
+    // BREAK if it isnt.
+    // If no debuggee exists the status is
+    // NO_DEBUGGEE.
+    // This method is reentrant.
+    STDMETHOD(GetExecutionStatus)(
+        THIS_
+        _Out_ PULONG Status
+        ) PURE;
+    // Changes the execution status of the
+    // engine from stopped to running.
+    // Status must be one of the go or step
+    // status values.
+    STDMETHOD(SetExecutionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // Controls what code interpretation level the debugger
+    // runs at.  The debugger checks the code level when
+    // deciding whether to step by a source line or
+    // assembly instruction along with other related operations.
+    STDMETHOD(GetCodeLevel)(
+        THIS_
+        _Out_ PULONG Level
+        ) PURE;
+    STDMETHOD(SetCodeLevel)(
+        THIS_
+        _In_ ULONG Level
+        ) PURE;
+
+    // Gets and sets engine control flags.
+    // These methods are reentrant.
+    STDMETHOD(GetEngineOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Gets and sets control values for
+    // handling system error events.
+    // If the system error level is less
+    // than or equal to the given levels
+    // the error may be displayed and
+    // the default break for the event
+    // may be set.
+    STDMETHOD(GetSystemErrorControl)(
+        THIS_
+        _Out_ PULONG OutputLevel,
+        _Out_ PULONG BreakLevel
+        ) PURE;
+    STDMETHOD(SetSystemErrorControl)(
+        THIS_
+        _In_ ULONG OutputLevel,
+        _In_ ULONG BreakLevel
+        ) PURE;
+
+    // The command processor supports simple
+    // string replacement macros in Evaluate and
+    // Execute.  There are currently ten macro
+    // slots available.  Slots 0-9 map to
+    // the command invocations $u0-$u9.
+    STDMETHOD(GetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCSTR Macro
+        ) PURE;
+
+    // Controls the default number radix used
+    // in expressions and commands.
+    STDMETHOD(GetRadix)(
+        THIS_
+        _Out_ PULONG Radix
+        ) PURE;
+    STDMETHOD(SetRadix)(
+        THIS_
+        _In_ ULONG Radix
+        ) PURE;
+
+    // Evaluates the given expression string and
+    // returns the resulting value.
+    // If DesiredType is DEBUG_VALUE_INVALID then
+    // the natural type is used.
+    // RemainderIndex, if provided, is set to the index
+    // of the first character in the input string that was
+    // not used when evaluating the expression.
+    STDMETHOD(Evaluate)(
+        THIS_
+        _In_ PCSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+    // Attempts to convert the input value to a value
+    // of the requested type in the output value.
+    // Conversions can fail if no conversion exists.
+    // Successful conversions may be lossy.
+    STDMETHOD(CoerceValue)(
+        THIS_
+        _In_ PDEBUG_VALUE In,
+        _In_ ULONG OutType,
+        _Out_ PDEBUG_VALUE Out
+        ) PURE;
+    STDMETHOD(CoerceValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_VALUE In,
+        _In_reads_(Count) PULONG OutTypes,
+        _Out_writes_(Count) PDEBUG_VALUE Out
+        ) PURE;
+
+    // Executes the given command string.
+    // If the string has multiple commands
+    // Execute will not return until all
+    // of them have been executed.  If this
+    // requires waiting for the debuggee to
+    // execute an internal wait will be done
+    // so Execute can take an arbitrary amount
+    // of time.
+    STDMETHOD(Execute)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    // Executes the given command file by
+    // reading a line at a time and processing
+    // it with Execute.
+    STDMETHOD(ExecuteCommandFile)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Breakpoint interfaces are described
+    // elsewhere in this section.
+    STDMETHOD(GetNumberBreakpoints)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // It is possible for this retrieval function to
+    // fail even with an index within the number of
+    // existing breakpoints if the breakpoint is
+    // a private breakpoint.
+    STDMETHOD(GetBreakpointByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // If Ids is non-NULL the Count breakpoints
+    // referred to in the Ids array are returned,
+    // otherwise breakpoints from index Start to
+    // Start + Count  1 are returned.
+    STDMETHOD(GetBreakpointParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Ids,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+    // Breakpoints are created empty and disabled.
+    // When their parameters have been set they
+    // should be enabled by setting the ENABLE flag.
+    // If DesiredId is DEBUG_ANY_ID then the
+    // engine picks an unused ID.  If DesiredId
+    // is any other number the engine attempts
+    // to use the given ID for the breakpoint.
+    // If another breakpoint exists with that ID
+    // the call will fail.
+    STDMETHOD(AddBreakpoint)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // Breakpoint interface is invalid after this call.
+    STDMETHOD(RemoveBreakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT Bp
+        ) PURE;
+
+    // Control and use extension DLLs.
+    STDMETHOD(AddExtension)(
+        THIS_
+        _In_ PCSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(RemoveExtension)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPath)(
+        THIS_
+        _In_ PCSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Handle is zero the extension
+    // chain is walked searching for the
+    // function.
+    STDMETHOD(CallExtension)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR Function,
+        _In_opt_ PCSTR Arguments
+        ) PURE;
+    // GetExtensionFunction works like
+    // GetProcAddress on extension DLLs
+    // to allow raw function-call-level
+    // interaction with extension DLLs.
+    // Such functions do not need to
+    // follow the standard extension prototype
+    // if they are not going to be called
+    // through the text extension interface.
+    // This function cannot be called remotely.
+    STDMETHOD(GetExtensionFunction)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+    // These methods return alternate
+    // extension interfaces in order to allow
+    // interface-style extension DLLs to mix in
+    // older extension calls.
+    // Structure sizes must be initialized before
+    // the call.
+    // These methods cannot be called remotely.
+    STDMETHOD(GetWindbgExtensionApis32)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS32 Api
+        ) PURE;
+    STDMETHOD(GetWindbgExtensionApis64)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS64 Api
+        ) PURE;
+
+    // The engine provides a simple mechanism
+    // to filter common events.  Arbitrarily complicated
+    // filtering can be done by registering event callbacks
+    // but simple event filtering only requires
+    // setting the options of one of the predefined
+    // event filters.
+    // Simple event filters are either for specific
+    // events and therefore have an enumerant or
+    // they are for an exception and are based on
+    // the exceptions code.  Exception filters
+    // are further divided into exceptions specially
+    // handled by the engine, which is a fixed set,
+    // and arbitrary exceptions.
+    // All three groups of filters are indexed together
+    // with the specific filters first, then the specific
+    // exception filters and finally the arbitrary
+    // exception filters.
+    // The first specific exception is the default
+    // exception.  If an exception event occurs for
+    // an exception without settings the default
+    // exception settings are used.
+    STDMETHOD(GetNumberEventFilters)(
+        THIS_
+        _Out_ PULONG SpecificEvents,
+        _Out_ PULONG SpecificExceptions,
+        _Out_ PULONG ArbitraryExceptions
+        ) PURE;
+    // Some filters have descriptive text associated with them.
+    STDMETHOD(GetEventFilterText)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // All filters support executing a command when the
+    // event occurs.
+    STDMETHOD(GetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    STDMETHOD(SetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    // Some specific filters have arguments to further
+    // qualify their operation.
+    STDMETHOD(GetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Argument
+        ) PURE;
+    // If Codes is non-NULL Start is ignored.
+    STDMETHOD(GetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Codes,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // The codes in the parameter data control the application
+    // of the parameter data.  If a code is not already in
+    // the set of filters it is added.  If the ExecutionOption
+    // for a code is REMOVE then the filter is removed.
+    // Specific exception filters cannot be removed.
+    STDMETHOD(SetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // Exception filters support an additional command for
+    // second-chance events.
+    STDMETHOD(GetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Yields processing to the engine until
+    // an event occurs.  This method may
+    // only be called by the thread that started
+    // the debug session.
+    // When an event occurs the engine carries
+    // out all event processing such as calling
+    // callbacks.
+    // If the callbacks indicate that execution should
+    // break the wait will return, otherwise it
+    // goes back to waiting for a new event.
+    // If the timeout expires, S_FALSE is returned.
+    // The timeout is not currently supported for
+    // kernel debugging.
+    STDMETHOD(WaitForEvent)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Retrieves information about the last event that occurred.
+    // EventType is one of the event callback mask bits.
+    // ExtraInformation contains additional event-specific
+    // information.  Not all events have additional information.
+    STDMETHOD(GetLastEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    // IDebugControl2.
+
+    STDMETHOD(GetCurrentTimeDate)(
+        THIS_
+        _Out_ PULONG TimeDate
+        ) PURE;
+    // Retrieves the number of seconds since the
+    // machine started running.
+    STDMETHOD(GetCurrentSystemUpTime)(
+        THIS_
+        _Out_ PULONG UpTime
+        ) PURE;
+
+    // If the current session is a dump session,
+    // retrieves any extended format information.
+    STDMETHOD(GetDumpFormatFlags)(
+        THIS_
+        _Out_ PULONG FormatFlags
+        ) PURE;
+
+    // The debugger has been enhanced to allow
+    // arbitrary text replacements in addition
+    // to the simple $u0-$u9 text macros.
+    // Text replacement takes a given source
+    // text in commands and converts it to the
+    // given destination text.  Replacements
+    // are named by their source text so that
+    // only one replacement for a source text
+    // string can exist.
+    STDMETHOD(GetNumberTextReplacements)(
+        THIS_
+        _Out_ PULONG NumRepl
+        ) PURE;
+    // If SrcText is non-NULL the replacement
+    // is looked up by source text, otherwise
+    // Index is used to get the Nth replacement.
+    STDMETHOD(GetTextReplacement)(
+        THIS_
+        _In_opt_ PCSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    // Setting the destination text to
+    // NULL removes the alias.
+    STDMETHOD(SetTextReplacement)(
+        THIS_
+        _In_ PCSTR SrcText,
+        _In_opt_ PCSTR DstText
+        ) PURE;
+    STDMETHOD(RemoveTextReplacements)(
+        THIS
+        ) PURE;
+    // Outputs the complete list of current
+    // replacements.
+    STDMETHOD(OutputTextReplacements)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // IDebugControl3.
+
+    // Control options for assembly and disassembly.
+    STDMETHOD(GetAssemblyOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Control the expression syntax.
+    STDMETHOD(GetExpressionSyntax)(
+        THIS_
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(SetExpressionSyntax)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Look up a syntax by its abbreviated
+    // name and set it.
+    STDMETHOD(SetExpressionSyntaxByName)(
+        THIS_
+        _In_ PCSTR AbbrevName
+        ) PURE;
+    STDMETHOD(GetNumberExpressionSyntaxes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetExpressionSyntaxNames)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    //
+    // Some debug sessions have only a single
+    // possible event, such as a snapshot dump
+    // file; some have dynamic events, such as
+    // a live debug session; and others may have
+    // multiple events, such as a dump file that
+    // contains snapshots from different points
+    // in time.  The following methods allow
+    // discovery and selection of the available
+    // events for a session.
+    // Sessions with one or more static events
+    // will be able to report all of the events
+    // when queried.  Sessions with dynamic events
+    // will only report a single event representing
+    // the current event.
+    // Switching events constitutes execution and
+    // changing the current event will alter the
+    // execution status to a running state, after
+    // which WaitForEvent must be used to process
+    // the selected event.
+    //
+
+    // GetNumberEvents returns S_OK if this is the
+    // complete set of events possible, such as for
+    // a static session; or S_FALSE if other events
+    // may be possible, such as for a dynamic session.
+    STDMETHOD(GetNumberEvents)(
+        THIS_
+        _Out_ PULONG Events
+        ) PURE;
+    // Sessions may have descriptive information for
+    // the various events available.  The amount of
+    // information varies according to the specific
+    // session and data.
+    STDMETHOD(GetEventIndexDescription)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG Which,
+        _In_opt_ PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DescSize
+        ) PURE;
+    STDMETHOD(GetCurrentEventIndex)(
+        THIS_
+        _Out_ PULONG Index
+        ) PURE;
+    // SetNextEventIndex works like seek in that
+    // it can set an absolute or relative index.
+    // SetNextEventIndex works similarly to SetExecutionStatus
+    // by putting the session into a running state, after
+    // which the caller must call WaitForEvent.  The
+    // current event index only changes when WaitForEvent
+    // is called.
+    STDMETHOD(SetNextEventIndex)(
+        THIS_
+        _In_ ULONG Relation,
+        _In_ ULONG Value,
+        _Out_ PULONG NextIndex
+        ) PURE;
+
+    // IDebugControl4.
+
+    STDMETHOD(GetLogFileWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    STDMETHOD(OpenLogFileWide)(
+        THIS_
+        _In_ PCWSTR File,
+        _In_ BOOL Append
+        ) PURE;
+
+    STDMETHOD(InputWide)(
+        THIS_
+        _Out_writes_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    STDMETHOD(ReturnInputWide)(
+        THIS_
+        _In_ PCWSTR Buffer
+        ) PURE;
+
+    STDMETHODV(OutputWide)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaListWide)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    STDMETHODV(ControlledOutputWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaListWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    STDMETHODV(OutputPromptWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaListWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    STDMETHOD(GetPromptTextWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+
+    STDMETHOD(AssembleWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCWSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(DisassembleWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+
+    STDMETHOD(GetProcessorTypeNamesWide)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PWSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    STDMETHOD(GetTextMacroWide)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacroWide)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCWSTR Macro
+        ) PURE;
+
+    STDMETHOD(EvaluateWide)(
+        THIS_
+        _In_ PCWSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+
+    STDMETHOD(ExecuteWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(ExecuteCommandFileWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetBreakpointByIndex2)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById2)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(AddBreakpoint2)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(RemoveBreakpoint2)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT2 Bp
+        ) PURE;
+
+    STDMETHOD(AddExtensionWide)(
+        THIS_
+        _In_ PCWSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPathWide)(
+        THIS_
+        _In_ PCWSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(CallExtensionWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCWSTR Function,
+        _In_opt_ PCWSTR Arguments
+        ) PURE;
+    STDMETHOD(GetExtensionFunctionWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCWSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+
+    STDMETHOD(GetEventFilterTextWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    STDMETHOD(GetEventFilterCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterArgumentWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgumentWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Argument
+        ) PURE;
+    STDMETHOD(GetExceptionFilterSecondCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Command
+        ) PURE;
+
+    STDMETHOD(GetLastEventInformationWide)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PWSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    STDMETHOD(GetTextReplacementWide)(
+        THIS_
+        _In_opt_ PCWSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PWSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PWSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    STDMETHOD(SetTextReplacementWide)(
+        THIS_
+        _In_ PCWSTR SrcText,
+        _In_opt_ PCWSTR DstText
+        ) PURE;
+
+    STDMETHOD(SetExpressionSyntaxByNameWide)(
+        THIS_
+        _In_ PCWSTR AbbrevName
+        ) PURE;
+    STDMETHOD(GetExpressionSyntaxNamesWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(FullNameBufferSize) PWSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    STDMETHOD(GetEventIndexDescriptionWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG Which,
+        _In_opt_ PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DescSize
+        ) PURE;
+
+    STDMETHOD(GetLogFile2)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(OpenLogFile2)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(GetLogFile2Wide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(OpenLogFile2Wide)(
+        THIS_
+        _In_ PCWSTR File,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // GetSystemVersion always returns the kd
+    // major/minor version numbers, which are
+    // different than the Win32 version numbers.
+    // GetSystemVersionValues can be used
+    // to determine the Win32 version values.
+    STDMETHOD(GetSystemVersionValues)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Win32Major,
+        _Out_ PULONG Win32Minor,
+        _Out_opt_ PULONG KdMajor,
+        _Out_opt_ PULONG KdMinor
+        ) PURE;
+    // Strings are selected with DEBUG_SYSVERSTR_*.
+    STDMETHOD(GetSystemVersionString)(
+        THIS_
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSystemVersionStringWide)(
+        THIS_
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+
+    // Stack tracing with a full initial context
+    // and full context return for each frame.
+    // The FrameContextsSize parameter is the total
+    // byte size of FrameContexts.  FrameContextsEntrySize
+    // gives the byte size of each entry in
+    // FrameContexts.
+    STDMETHOD(GetContextStackTrace)(
+        THIS_
+        _In_reads_bytes_opt_(StartContextSize) PVOID StartContext,
+        _In_ ULONG StartContextSize,
+        _Out_writes_to_opt_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_writes_bytes_opt_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    STDMETHOD(OutputContextStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_reads_bytes_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Some targets, such as user-mode minidump files,
+    // have separate "event of interest" information
+    // stored within them.  This method allows
+    // access to that information.
+    STDMETHOD(GetStoredEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize,
+        _Out_opt_ PULONG ContextUsed,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed
+        ) PURE;
+
+    // Managed debugging support relies on debugging
+    // functionality provided by the Common Language Runtime.
+    // This method provides feedback on the engine's
+    // use of the runtime debugging APIs.
+    STDMETHOD(GetManagedStatus)(
+        THIS_
+        _Out_opt_ PULONG Flags,
+        _In_ ULONG WhichString,
+        _Out_writes_opt_(StringSize) PSTR String,
+        _In_ ULONG StringSize,
+        _Out_opt_ PULONG StringNeeded
+        ) PURE;
+    STDMETHOD(GetManagedStatusWide)(
+        THIS_
+        _Out_opt_ PULONG Flags,
+        _In_ ULONG WhichString,
+        _Out_writes_opt_(StringSize) PWSTR String,
+        _In_ ULONG StringSize,
+        _Out_opt_ PULONG StringNeeded
+        ) PURE;
+    // Clears and reinitializes the engine's
+    // managed code debugging support.
+    STDMETHOD(ResetManagedStatus)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+
+    // IDebugControl5
+    STDMETHOD(GetStackTraceEx)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_to_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+
+    STDMETHOD(OutputStackTraceEx)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetContextStackTraceEx)(
+        THIS_
+        _In_reads_bytes_opt_(StartContextSize) PVOID StartContext,
+        _In_ ULONG StartContextSize,
+        _Out_writes_to_opt_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _Out_writes_bytes_opt_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+
+    STDMETHOD(OutputContextStackTraceEx)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_(FramesSize) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _In_reads_bytes_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetBreakpointByGuid)(
+        THIS_
+        _In_ LPGUID Guid,
+        _Out_ PDEBUG_BREAKPOINT3* Bp
+        ) PURE;
+
+    // IDebugControl6
+
+    // Returns additional info states for 
+    STDMETHOD(GetExecutionStatusEx)(
+        THIS_
+        _Out_ PULONG Status
+        ) PURE;
+
+    STDMETHOD(GetSynchronizationStatus)(
+        THIS_
+        _Out_ PULONG SendsAttempted,
+        _Out_ PULONG SecondsSinceLastResponse
+        ) PURE;
+
+};
+
+#define DEBUG_EXEC_FLAGS_NONBLOCK 0x00000001
+
+#undef INTERFACE
+#define INTERFACE IDebugControl7
+DECLARE_INTERFACE_(IDebugControl7, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugControl.
+
+    // Checks for a user interrupt, such a Ctrl-C
+    // or stop button.
+    // This method is reentrant.
+    STDMETHOD(GetInterrupt)(
+        THIS
+        ) PURE;
+    // Registers a user interrupt.
+    // This method is reentrant.
+    STDMETHOD(SetInterrupt)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Interrupting a user-mode process requires
+    // access to some system resources that the
+    // process may hold itself, preventing the
+    // interrupt from occurring.  The engine
+    // will time-out pending interrupt requests
+    // and simulate an interrupt if necessary.
+    // These methods control the interrupt timeout.
+    STDMETHOD(GetInterruptTimeout)(
+        THIS_
+        _Out_ PULONG Seconds
+        ) PURE;
+    STDMETHOD(SetInterruptTimeout)(
+        THIS_
+        _In_ ULONG Seconds
+        ) PURE;
+
+    STDMETHOD(GetLogFile)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    // Opens a log file which collects all
+    // output.  Output from every client except
+    // those that explicitly disable logging
+    // goes into the log.
+    // Opening a log file closes any log file
+    // already open.
+    STDMETHOD(OpenLogFile)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ BOOL Append
+        ) PURE;
+    STDMETHOD(CloseLogFile)(
+        THIS
+        ) PURE;
+    // Controls what output is logged.
+    STDMETHOD(GetLogMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    STDMETHOD(SetLogMask)(
+        THIS_
+        _In_ ULONG Mask
+        ) PURE;
+
+    // Input requests input from all clients.
+    // The first input that is returned is used
+    // to satisfy the call.  Other returned
+    // input is discarded.
+    STDMETHOD(Input)(
+        THIS_
+        _Out_writes_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    // This method is used by clients to return
+    // input when it is available.  It will
+    // return S_OK if the input is used to
+    // satisfy an Input call and S_FALSE if
+    // the input is ignored.
+    // This method is reentrant.
+    STDMETHOD(ReturnInput)(
+        THIS_
+        _In_ PCSTR Buffer
+        ) PURE;
+
+    // Sends output through clients
+    // output callbacks if the mask is allowed
+    // by the current output control mask and
+    // according to the output distribution
+    // settings.
+    STDMETHODV(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaList)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // The following methods allow direct control
+    // over the distribution of the given output
+    // for situations where something other than
+    // the default is desired.  These methods require
+    // extra work in the engine so they should
+    // only be used when necessary.
+    STDMETHODV(ControlledOutput)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    // Displays the standard command-line prompt
+    // followed by the given output.  If Format
+    // is NULL no additional output is produced.
+    // Output is produced under the
+    // DEBUG_OUTPUT_PROMPT mask.
+    // This method only outputs the prompt; it
+    // does not get input.
+    STDMETHODV(OutputPrompt)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaList)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    // Gets the text that would be displayed by OutputPrompt.
+    STDMETHOD(GetPromptText)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // Outputs information about the current
+    // debuggee state such as a register
+    // summary, disassembly at the current PC,
+    // closest symbol and others.
+    // Uses the line prefix.
+    STDMETHOD(OutputCurrentState)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Outputs the debugger and extension version
+    // information.  This method is reentrant.
+    // Uses the line prefix.
+    STDMETHOD(OutputVersionInformation)(
+        THIS_
+        _In_ ULONG OutputControl
+        ) PURE;
+
+    // In user-mode debugging sessions the
+    // engine will set an event when
+    // exceptions are continued.  This can
+    // be used to synchronize other processes
+    // with the debuggers handling of events.
+    // For example, this is used to support
+    // the e argument to ntsd.
+    STDMETHOD(GetNotifyEventHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(SetNotifyEventHandle)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Assemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(Disassemble)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Returns the value of the effective address
+    // computed for the last Disassemble, if there
+    // was one.
+    STDMETHOD(GetDisassembleEffectiveOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Uses the line prefix if necessary.
+    STDMETHOD(OutputDisassembly)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    // Produces multiple lines of disassembly output.
+    // There will be PreviousLines of disassembly before
+    // the given offset if a valid disassembly exists.
+    // In all, there will be TotalLines of output produced.
+    // The first and last line offsets are returned
+    // specially and all lines offsets can be retrieved
+    // through LineOffsets.  LineOffsets will contain
+    // offsets for each line where disassembly started.
+    // When disassembly of a single instruction takes
+    // multiple lines the initial offset will be followed
+    // by DEBUG_INVALID_OFFSET.
+    // Uses the line prefix.
+    STDMETHOD(OutputDisassemblyLines)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG PreviousLines,
+        _In_ ULONG TotalLines,
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG OffsetLine,
+        _Out_opt_ PULONG64 StartOffset,
+        _Out_opt_ PULONG64 EndOffset,
+        _Out_writes_opt_(TotalLines) PULONG64 LineOffsets
+        ) PURE;
+    // Returns the offset of the start of
+    // the instruction thats the given
+    // delta away from the instruction
+    // at the initial offset.
+    // This routine does not check for
+    // validity of the instruction or
+    // the memory containing it.
+    STDMETHOD(GetNearInstruction)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_ PULONG64 NearOffset
+        ) PURE;
+
+    // Offsets can be passed in as zero to use the current
+    // thread state.
+    STDMETHOD(GetStackTrace)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_to_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    // Does a simple stack trace to determine
+    // what the current return address is.
+    STDMETHOD(GetReturnOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // If Frames is NULL OutputStackTrace will
+    // use GetStackTrace to get FramesSize frames
+    // and then output them.  The current register
+    // values for frame, stack and instruction offsets
+    // are used.
+    // Uses the line prefix.
+    STDMETHOD(OutputStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Returns information about the debuggee such
+    // as user vs. kernel, dump vs. live, etc.
+    STDMETHOD(GetDebuggeeType)(
+        THIS_
+        _Out_ PULONG Class,
+        _Out_ PULONG Qualifier
+        ) PURE;
+    // Returns the type of physical processors in
+    // the machine.
+    // Returns one of the IMAGE_FILE_MACHINE values.
+    STDMETHOD(GetActualProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Returns the type of processor used in the
+    // current processor context.
+    STDMETHOD(GetExecutingProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    // Query all the possible processor types that
+    // may be encountered during this debug session.
+    STDMETHOD(GetNumberPossibleExecutingProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetPossibleExecutingProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Get the number of actual processors in
+    // the machine.
+    STDMETHOD(GetNumberProcessors)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // PlatformId is one of the VER_PLATFORM values.
+    // Major and minor are as given in the NT
+    // kernel debugger protocol.
+    // ServicePackString and ServicePackNumber indicate the
+    // system service pack level.  ServicePackNumber is not
+    // available in some sessions where the service pack level
+    // is only expressed as a string.  The service pack information
+    // will be empty if the system does not have a service pack
+    // applied.
+    // The build string is string information identifying the
+    // particular build of the system.  The build string is
+    // empty if the system has no particular identifying
+    // information.
+    STDMETHOD(GetSystemVersion)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Major,
+        _Out_ PULONG Minor,
+        _Out_writes_opt_(ServicePackStringSize) PSTR ServicePackString,
+        _In_ ULONG ServicePackStringSize,
+        _Out_opt_ PULONG ServicePackStringUsed,
+        _Out_ PULONG ServicePackNumber,
+        _Out_writes_opt_(BuildStringSize) PSTR BuildString,
+        _In_ ULONG BuildStringSize,
+        _Out_opt_ PULONG BuildStringUsed
+        ) PURE;
+    // Returns the page size for the currently executing
+    // processor context.  The page size may vary between
+    // processor types.
+    STDMETHOD(GetPageSize)(
+        THIS_
+        _Out_ PULONG Size
+        ) PURE;
+    // Returns S_OK if the current processor context uses
+    // 64-bit addresses, otherwise S_FALSE.
+    STDMETHOD(IsPointer64Bit)(
+        THIS
+        ) PURE;
+    // Reads the bugcheck data area and returns the
+    // current contents.  This method only works
+    // in kernel debugging sessions.
+    STDMETHOD(ReadBugCheckData)(
+        THIS_
+        _Out_ PULONG Code,
+        _Out_ PULONG64 Arg1,
+        _Out_ PULONG64 Arg2,
+        _Out_ PULONG64 Arg3,
+        _Out_ PULONG64 Arg4
+        ) PURE;
+
+    // Query all the processor types supported by
+    // the engine.  This is a complete list and is
+    // not related to the machine running the engine
+    // or the debuggee.
+    STDMETHOD(GetNumberSupportedProcessorTypes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetSupportedProcessorTypes)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Types
+        ) PURE;
+    // Returns a full, descriptive name and an
+    // abbreviated name for a processor type.
+    STDMETHOD(GetProcessorTypeNames)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    // Gets and sets the type of processor to
+    // use when doing things like setting
+    // breakpoints, accessing registers,
+    // getting stack traces and so on.
+    STDMETHOD(GetEffectiveProcessorType)(
+        THIS_
+        _Out_ PULONG Type
+        ) PURE;
+    STDMETHOD(SetEffectiveProcessorType)(
+        THIS_
+        _In_ ULONG Type
+        ) PURE;
+
+    // Returns information about whether and how
+    // the debuggee is running.  Status will
+    // be GO if the debuggee is running and
+    // BREAK if it isnt.
+    // If no debuggee exists the status is
+    // NO_DEBUGGEE.
+    // This method is reentrant.
+    STDMETHOD(GetExecutionStatus)(
+        THIS_
+        _Out_ PULONG Status
+        ) PURE;
+    // Changes the execution status of the
+    // engine from stopped to running.
+    // Status must be one of the go or step
+    // status values.
+    STDMETHOD(SetExecutionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // Controls what code interpretation level the debugger
+    // runs at.  The debugger checks the code level when
+    // deciding whether to step by a source line or
+    // assembly instruction along with other related operations.
+    STDMETHOD(GetCodeLevel)(
+        THIS_
+        _Out_ PULONG Level
+        ) PURE;
+    STDMETHOD(SetCodeLevel)(
+        THIS_
+        _In_ ULONG Level
+        ) PURE;
+
+    // Gets and sets engine control flags.
+    // These methods are reentrant.
+    STDMETHOD(GetEngineOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetEngineOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Gets and sets control values for
+    // handling system error events.
+    // If the system error level is less
+    // than or equal to the given levels
+    // the error may be displayed and
+    // the default break for the event
+    // may be set.
+    STDMETHOD(GetSystemErrorControl)(
+        THIS_
+        _Out_ PULONG OutputLevel,
+        _Out_ PULONG BreakLevel
+        ) PURE;
+    STDMETHOD(SetSystemErrorControl)(
+        THIS_
+        _In_ ULONG OutputLevel,
+        _In_ ULONG BreakLevel
+        ) PURE;
+
+    // The command processor supports simple
+    // string replacement macros in Evaluate and
+    // Execute.  There are currently ten macro
+    // slots available.  Slots 0-9 map to
+    // the command invocations $u0-$u9.
+    STDMETHOD(GetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacro)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCSTR Macro
+        ) PURE;
+
+    // Controls the default number radix used
+    // in expressions and commands.
+    STDMETHOD(GetRadix)(
+        THIS_
+        _Out_ PULONG Radix
+        ) PURE;
+    STDMETHOD(SetRadix)(
+        THIS_
+        _In_ ULONG Radix
+        ) PURE;
+
+    // Evaluates the given expression string and
+    // returns the resulting value.
+    // If DesiredType is DEBUG_VALUE_INVALID then
+    // the natural type is used.
+    // RemainderIndex, if provided, is set to the index
+    // of the first character in the input string that was
+    // not used when evaluating the expression.
+    STDMETHOD(Evaluate)(
+        THIS_
+        _In_ PCSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+    // Attempts to convert the input value to a value
+    // of the requested type in the output value.
+    // Conversions can fail if no conversion exists.
+    // Successful conversions may be lossy.
+    STDMETHOD(CoerceValue)(
+        THIS_
+        _In_ PDEBUG_VALUE In,
+        _In_ ULONG OutType,
+        _Out_ PDEBUG_VALUE Out
+        ) PURE;
+    STDMETHOD(CoerceValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_VALUE In,
+        _In_reads_(Count) PULONG OutTypes,
+        _Out_writes_(Count) PDEBUG_VALUE Out
+        ) PURE;
+
+    // Executes the given command string.
+    // If the string has multiple commands
+    // Execute will not return until all
+    // of them have been executed.  If this
+    // requires waiting for the debuggee to
+    // execute an internal wait will be done
+    // so Execute can take an arbitrary amount
+    // of time.
+    STDMETHOD(Execute)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    // Executes the given command file by
+    // reading a line at a time and processing
+    // it with Execute.
+    STDMETHOD(ExecuteCommandFile)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Breakpoint interfaces are described
+    // elsewhere in this section.
+    STDMETHOD(GetNumberBreakpoints)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // It is possible for this retrieval function to
+    // fail even with an index within the number of
+    // existing breakpoints if the breakpoint is
+    // a private breakpoint.
+    STDMETHOD(GetBreakpointByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // If Ids is non-NULL the Count breakpoints
+    // referred to in the Ids array are returned,
+    // otherwise breakpoints from index Start to
+    // Start + Count  1 are returned.
+    STDMETHOD(GetBreakpointParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Ids,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_BREAKPOINT_PARAMETERS Params
+        ) PURE;
+    // Breakpoints are created empty and disabled.
+    // When their parameters have been set they
+    // should be enabled by setting the ENABLE flag.
+    // If DesiredId is DEBUG_ANY_ID then the
+    // engine picks an unused ID.  If DesiredId
+    // is any other number the engine attempts
+    // to use the given ID for the breakpoint.
+    // If another breakpoint exists with that ID
+    // the call will fail.
+    STDMETHOD(AddBreakpoint)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT* Bp
+        ) PURE;
+    // Breakpoint interface is invalid after this call.
+    STDMETHOD(RemoveBreakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT Bp
+        ) PURE;
+
+    // Control and use extension DLLs.
+    STDMETHOD(AddExtension)(
+        THIS_
+        _In_ PCSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(RemoveExtension)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPath)(
+        THIS_
+        _In_ PCSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Handle is zero the extension
+    // chain is walked searching for the
+    // function.
+    STDMETHOD(CallExtension)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR Function,
+        _In_opt_ PCSTR Arguments
+        ) PURE;
+    // GetExtensionFunction works like
+    // GetProcAddress on extension DLLs
+    // to allow raw function-call-level
+    // interaction with extension DLLs.
+    // Such functions do not need to
+    // follow the standard extension prototype
+    // if they are not going to be called
+    // through the text extension interface.
+    // This function cannot be called remotely.
+    STDMETHOD(GetExtensionFunction)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+    // These methods return alternate
+    // extension interfaces in order to allow
+    // interface-style extension DLLs to mix in
+    // older extension calls.
+    // Structure sizes must be initialized before
+    // the call.
+    // These methods cannot be called remotely.
+    STDMETHOD(GetWindbgExtensionApis32)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS32 Api
+        ) PURE;
+    STDMETHOD(GetWindbgExtensionApis64)(
+        THIS_
+        _Inout_ PWINDBG_EXTENSION_APIS64 Api
+        ) PURE;
+
+    // The engine provides a simple mechanism
+    // to filter common events.  Arbitrarily complicated
+    // filtering can be done by registering event callbacks
+    // but simple event filtering only requires
+    // setting the options of one of the predefined
+    // event filters.
+    // Simple event filters are either for specific
+    // events and therefore have an enumerant or
+    // they are for an exception and are based on
+    // the exceptions code.  Exception filters
+    // are further divided into exceptions specially
+    // handled by the engine, which is a fixed set,
+    // and arbitrary exceptions.
+    // All three groups of filters are indexed together
+    // with the specific filters first, then the specific
+    // exception filters and finally the arbitrary
+    // exception filters.
+    // The first specific exception is the default
+    // exception.  If an exception event occurs for
+    // an exception without settings the default
+    // exception settings are used.
+    STDMETHOD(GetNumberEventFilters)(
+        THIS_
+        _Out_ PULONG SpecificEvents,
+        _Out_ PULONG SpecificExceptions,
+        _Out_ PULONG ArbitraryExceptions
+        ) PURE;
+    // Some filters have descriptive text associated with them.
+    STDMETHOD(GetEventFilterText)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    // All filters support executing a command when the
+    // event occurs.
+    STDMETHOD(GetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    STDMETHOD(SetSpecificFilterParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_SPECIFIC_FILTER_PARAMETERS Params
+        ) PURE;
+    // Some specific filters have arguments to further
+    // qualify their operation.
+    STDMETHOD(GetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgument)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Argument
+        ) PURE;
+    // If Codes is non-NULL Start is ignored.
+    STDMETHOD(GetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Codes,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // The codes in the parameter data control the application
+    // of the parameter data.  If a code is not already in
+    // the set of filters it is added.  If the ExecutionOption
+    // for a code is REMOVE then the filter is removed.
+    // Specific exception filters cannot be removed.
+    STDMETHOD(SetExceptionFilterParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_(Count) PDEBUG_EXCEPTION_FILTER_PARAMETERS Params
+        ) PURE;
+    // Exception filters support an additional command for
+    // second-chance events.
+    STDMETHOD(GetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommand)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Command
+        ) PURE;
+
+    // Yields processing to the engine until
+    // an event occurs.  This method may
+    // only be called by the thread that started
+    // the debug session.
+    // When an event occurs the engine carries
+    // out all event processing such as calling
+    // callbacks.
+    // If the callbacks indicate that execution should
+    // break the wait will return, otherwise it
+    // goes back to waiting for a new event.
+    // If the timeout expires, S_FALSE is returned.
+    // The timeout is not currently supported for
+    // kernel debugging.
+    STDMETHOD(WaitForEvent)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG Timeout
+        ) PURE;
+
+    // Retrieves information about the last event that occurred.
+    // EventType is one of the event callback mask bits.
+    // ExtraInformation contains additional event-specific
+    // information.  Not all events have additional information.
+    STDMETHOD(GetLastEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    // IDebugControl2.
+
+    STDMETHOD(GetCurrentTimeDate)(
+        THIS_
+        _Out_ PULONG TimeDate
+        ) PURE;
+    // Retrieves the number of seconds since the
+    // machine started running.
+    STDMETHOD(GetCurrentSystemUpTime)(
+        THIS_
+        _Out_ PULONG UpTime
+        ) PURE;
+
+    // If the current session is a dump session,
+    // retrieves any extended format information.
+    STDMETHOD(GetDumpFormatFlags)(
+        THIS_
+        _Out_ PULONG FormatFlags
+        ) PURE;
+
+    // The debugger has been enhanced to allow
+    // arbitrary text replacements in addition
+    // to the simple $u0-$u9 text macros.
+    // Text replacement takes a given source
+    // text in commands and converts it to the
+    // given destination text.  Replacements
+    // are named by their source text so that
+    // only one replacement for a source text
+    // string can exist.
+    STDMETHOD(GetNumberTextReplacements)(
+        THIS_
+        _Out_ PULONG NumRepl
+        ) PURE;
+    // If SrcText is non-NULL the replacement
+    // is looked up by source text, otherwise
+    // Index is used to get the Nth replacement.
+    STDMETHOD(GetTextReplacement)(
+        THIS_
+        _In_opt_ PCSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    // Setting the destination text to
+    // NULL removes the alias.
+    STDMETHOD(SetTextReplacement)(
+        THIS_
+        _In_ PCSTR SrcText,
+        _In_opt_ PCSTR DstText
+        ) PURE;
+    STDMETHOD(RemoveTextReplacements)(
+        THIS
+        ) PURE;
+    // Outputs the complete list of current
+    // replacements.
+    STDMETHOD(OutputTextReplacements)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // IDebugControl3.
+
+    // Control options for assembly and disassembly.
+    STDMETHOD(GetAssemblyOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetAssemblyOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // Control the expression syntax.
+    STDMETHOD(GetExpressionSyntax)(
+        THIS_
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(SetExpressionSyntax)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+    // Look up a syntax by its abbreviated
+    // name and set it.
+    STDMETHOD(SetExpressionSyntaxByName)(
+        THIS_
+        _In_ PCSTR AbbrevName
+        ) PURE;
+    STDMETHOD(GetNumberExpressionSyntaxes)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetExpressionSyntaxNames)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(FullNameBufferSize) PSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    //
+    // Some debug sessions have only a single
+    // possible event, such as a snapshot dump
+    // file; some have dynamic events, such as
+    // a live debug session; and others may have
+    // multiple events, such as a dump file that
+    // contains snapshots from different points
+    // in time.  The following methods allow
+    // discovery and selection of the available
+    // events for a session.
+    // Sessions with one or more static events
+    // will be able to report all of the events
+    // when queried.  Sessions with dynamic events
+    // will only report a single event representing
+    // the current event.
+    // Switching events constitutes execution and
+    // changing the current event will alter the
+    // execution status to a running state, after
+    // which WaitForEvent must be used to process
+    // the selected event.
+    //
+
+    // GetNumberEvents returns S_OK if this is the
+    // complete set of events possible, such as for
+    // a static session; or S_FALSE if other events
+    // may be possible, such as for a dynamic session.
+    STDMETHOD(GetNumberEvents)(
+        THIS_
+        _Out_ PULONG Events
+        ) PURE;
+    // Sessions may have descriptive information for
+    // the various events available.  The amount of
+    // information varies according to the specific
+    // session and data.
+    STDMETHOD(GetEventIndexDescription)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG Which,
+        _In_opt_ PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DescSize
+        ) PURE;
+    STDMETHOD(GetCurrentEventIndex)(
+        THIS_
+        _Out_ PULONG Index
+        ) PURE;
+    // SetNextEventIndex works like seek in that
+    // it can set an absolute or relative index.
+    // SetNextEventIndex works similarly to SetExecutionStatus
+    // by putting the session into a running state, after
+    // which the caller must call WaitForEvent.  The
+    // current event index only changes when WaitForEvent
+    // is called.
+    STDMETHOD(SetNextEventIndex)(
+        THIS_
+        _In_ ULONG Relation,
+        _In_ ULONG Value,
+        _Out_ PULONG NextIndex
+        ) PURE;
+
+    // IDebugControl4.
+
+    STDMETHOD(GetLogFileWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PBOOL Append
+        ) PURE;
+    STDMETHOD(OpenLogFileWide)(
+        THIS_
+        _In_ PCWSTR File,
+        _In_ BOOL Append
+        ) PURE;
+
+    STDMETHOD(InputWide)(
+        THIS_
+        _Out_writes_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InputSize
+        ) PURE;
+    STDMETHOD(ReturnInputWide)(
+        THIS_
+        _In_ PCWSTR Buffer
+        ) PURE;
+
+    STDMETHODV(OutputWide)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputVaListWide)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    STDMETHODV(ControlledOutputWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(ControlledOutputVaListWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Mask,
+        _In_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+
+    STDMETHODV(OutputPromptWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCWSTR Format,
+        ...
+        ) PURE;
+    STDMETHOD(OutputPromptVaListWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_opt_ PCWSTR Format,
+        _In_ va_list Args
+        ) PURE;
+    STDMETHOD(GetPromptTextWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+
+    STDMETHOD(AssembleWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ PCWSTR Instr,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+    STDMETHOD(DisassembleWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DisassemblySize,
+        _Out_ PULONG64 EndOffset
+        ) PURE;
+
+    STDMETHOD(GetProcessorTypeNamesWide)(
+        THIS_
+        _In_ ULONG Type,
+        _Out_writes_opt_(FullNameBufferSize) PWSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    STDMETHOD(GetTextMacroWide)(
+        THIS_
+        _In_ ULONG Slot,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MacroSize
+        ) PURE;
+    STDMETHOD(SetTextMacroWide)(
+        THIS_
+        _In_ ULONG Slot,
+        _In_ PCWSTR Macro
+        ) PURE;
+
+    STDMETHOD(EvaluateWide)(
+        THIS_
+        _In_ PCWSTR Expression,
+        _In_ ULONG DesiredType,
+        _Out_ PDEBUG_VALUE Value,
+        _Out_opt_ PULONG RemainderIndex
+        ) PURE;
+
+    STDMETHOD(ExecuteWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR Command,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(ExecuteCommandFileWide)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ PCWSTR CommandFile,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetBreakpointByIndex2)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(GetBreakpointById2)(
+        THIS_
+        _In_ ULONG Id,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(AddBreakpoint2)(
+        THIS_
+        _In_ ULONG Type,
+        _In_ ULONG DesiredId,
+        _Out_ PDEBUG_BREAKPOINT2* Bp
+        ) PURE;
+    STDMETHOD(RemoveBreakpoint2)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT2 Bp
+        ) PURE;
+
+    STDMETHOD(AddExtensionWide)(
+        THIS_
+        _In_ PCWSTR Path,
+        _In_ ULONG Flags,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetExtensionByPathWide)(
+        THIS_
+        _In_ PCWSTR Path,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(CallExtensionWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCWSTR Function,
+        _In_opt_ PCWSTR Arguments
+        ) PURE;
+    STDMETHOD(GetExtensionFunctionWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ PCWSTR FuncName,
+        _Out_ FARPROC* Function
+        ) PURE;
+
+    STDMETHOD(GetEventFilterTextWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TextSize
+        ) PURE;
+    STDMETHOD(GetEventFilterCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetEventFilterCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Command
+        ) PURE;
+    STDMETHOD(GetSpecificFilterArgumentWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ArgumentSize
+        ) PURE;
+    STDMETHOD(SetSpecificFilterArgumentWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Argument
+        ) PURE;
+    STDMETHOD(GetExceptionFilterSecondCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG CommandSize
+        ) PURE;
+    STDMETHOD(SetExceptionFilterSecondCommandWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Command
+        ) PURE;
+
+    STDMETHOD(GetLastEventInformationWide)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed,
+        _Out_writes_opt_(DescriptionSize) PWSTR Description,
+        _In_ ULONG DescriptionSize,
+        _Out_opt_ PULONG DescriptionUsed
+        ) PURE;
+
+    STDMETHOD(GetTextReplacementWide)(
+        THIS_
+        _In_opt_ PCWSTR SrcText,
+        _In_ ULONG Index,
+        _Out_writes_opt_(SrcBufferSize) PWSTR SrcBuffer,
+        _In_ ULONG SrcBufferSize,
+        _Out_opt_ PULONG SrcSize,
+        _Out_writes_opt_(DstBufferSize) PWSTR DstBuffer,
+        _In_ ULONG DstBufferSize,
+        _Out_opt_ PULONG DstSize
+        ) PURE;
+    STDMETHOD(SetTextReplacementWide)(
+        THIS_
+        _In_ PCWSTR SrcText,
+        _In_opt_ PCWSTR DstText
+        ) PURE;
+
+    STDMETHOD(SetExpressionSyntaxByNameWide)(
+        THIS_
+        _In_ PCWSTR AbbrevName
+        ) PURE;
+    STDMETHOD(GetExpressionSyntaxNamesWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(FullNameBufferSize) PWSTR FullNameBuffer,
+        _In_ ULONG FullNameBufferSize,
+        _Out_opt_ PULONG FullNameSize,
+        _Out_writes_opt_(AbbrevNameBufferSize) PWSTR AbbrevNameBuffer,
+        _In_ ULONG AbbrevNameBufferSize,
+        _Out_opt_ PULONG AbbrevNameSize
+        ) PURE;
+
+    STDMETHOD(GetEventIndexDescriptionWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG Which,
+        _In_opt_ PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DescSize
+        ) PURE;
+
+    STDMETHOD(GetLogFile2)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(OpenLogFile2)(
+        THIS_
+        _In_ PCSTR File,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(GetLogFile2Wide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_ PULONG Flags
+        ) PURE;
+    STDMETHOD(OpenLogFile2Wide)(
+        THIS_
+        _In_ PCWSTR File,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // GetSystemVersion always returns the kd
+    // major/minor version numbers, which are
+    // different than the Win32 version numbers.
+    // GetSystemVersionValues can be used
+    // to determine the Win32 version values.
+    STDMETHOD(GetSystemVersionValues)(
+        THIS_
+        _Out_ PULONG PlatformId,
+        _Out_ PULONG Win32Major,
+        _Out_ PULONG Win32Minor,
+        _Out_opt_ PULONG KdMajor,
+        _Out_opt_ PULONG KdMinor
+        ) PURE;
+    // Strings are selected with DEBUG_SYSVERSTR_*.
+    STDMETHOD(GetSystemVersionString)(
+        THIS_
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSystemVersionStringWide)(
+        THIS_
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+
+    // Stack tracing with a full initial context
+    // and full context return for each frame.
+    // The FrameContextsSize parameter is the total
+    // byte size of FrameContexts.  FrameContextsEntrySize
+    // gives the byte size of each entry in
+    // FrameContexts.
+    STDMETHOD(GetContextStackTrace)(
+        THIS_
+        _In_reads_bytes_opt_(StartContextSize) PVOID StartContext,
+        _In_ ULONG StartContextSize,
+        _Out_writes_to_opt_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _Out_writes_bytes_opt_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+    STDMETHOD(OutputContextStackTrace)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_(FramesSize) PDEBUG_STACK_FRAME Frames,
+        _In_ ULONG FramesSize,
+        _In_reads_bytes_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Some targets, such as user-mode minidump files,
+    // have separate "event of interest" information
+    // stored within them.  This method allows
+    // access to that information.
+    STDMETHOD(GetStoredEventInformation)(
+        THIS_
+        _Out_ PULONG Type,
+        _Out_ PULONG ProcessId,
+        _Out_ PULONG ThreadId,
+        _Out_writes_bytes_opt_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize,
+        _Out_opt_ PULONG ContextUsed,
+        _Out_writes_bytes_opt_(ExtraInformationSize) PVOID ExtraInformation,
+        _In_ ULONG ExtraInformationSize,
+        _Out_opt_ PULONG ExtraInformationUsed
+        ) PURE;
+
+    // Managed debugging support relies on debugging
+    // functionality provided by the Common Language Runtime.
+    // This method provides feedback on the engine's
+    // use of the runtime debugging APIs.
+    STDMETHOD(GetManagedStatus)(
+        THIS_
+        _Out_opt_ PULONG Flags,
+        _In_ ULONG WhichString,
+        _Out_writes_opt_(StringSize) PSTR String,
+        _In_ ULONG StringSize,
+        _Out_opt_ PULONG StringNeeded
+        ) PURE;
+    STDMETHOD(GetManagedStatusWide)(
+        THIS_
+        _Out_opt_ PULONG Flags,
+        _In_ ULONG WhichString,
+        _Out_writes_opt_(StringSize) PWSTR String,
+        _In_ ULONG StringSize,
+        _Out_opt_ PULONG StringNeeded
+        ) PURE;
+    // Clears and reinitializes the engine's
+    // managed code debugging support.
+    STDMETHOD(ResetManagedStatus)(
+        THIS_
+        _In_ ULONG Flags
+        ) PURE;
+
+    // IDebugControl5
+    STDMETHOD(GetStackTraceEx)(
+        THIS_
+        _In_ ULONG64 FrameOffset,
+        _In_ ULONG64 StackOffset,
+        _In_ ULONG64 InstructionOffset,
+        _Out_writes_to_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+
+    STDMETHOD(OutputStackTraceEx)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_opt_(FramesSize) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetContextStackTraceEx)(
+        THIS_
+        _In_reads_bytes_opt_(StartContextSize) PVOID StartContext,
+        _In_ ULONG StartContextSize,
+        _Out_writes_to_opt_(FramesSize,*FramesFilled) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _Out_writes_bytes_opt_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _Out_opt_ PULONG FramesFilled
+        ) PURE;
+
+    STDMETHOD(OutputContextStackTraceEx)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_reads_(FramesSize) PDEBUG_STACK_FRAME_EX Frames,
+        _In_ ULONG FramesSize,
+        _In_reads_bytes_(FrameContextsSize) PVOID FrameContexts,
+        _In_ ULONG FrameContextsSize,
+        _In_ ULONG FrameContextsEntrySize,
+        _In_ ULONG Flags
+        ) PURE;
+
+    STDMETHOD(GetBreakpointByGuid)(
+        THIS_
+        _In_ LPGUID Guid,
+        _Out_ PDEBUG_BREAKPOINT3* Bp
+        ) PURE;
+
+    // IDebugControl6
+
+    // Returns additional info states for 
+    STDMETHOD(GetExecutionStatusEx)(
+        THIS_
+        _Out_ PULONG Status
+        ) PURE;
+
+    STDMETHOD(GetSynchronizationStatus)(
+        THIS_
+        _Out_ PULONG SendsAttempted,
+        _Out_ PULONG SecondsSinceLastResponse
+        ) PURE;
+
+    // IDebugControl7
+
+    STDMETHOD(GetDebuggeeType2)(
+        THIS_
+        _In_ ULONG Flags,
+        _Out_ PULONG Class,
+        _Out_ PULONG Qualifier
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugDataSpaces.
+//
+//----------------------------------------------------------------------------
+
+// Data space indices for callbacks and other methods.
+#define DEBUG_DATA_SPACE_VIRTUAL       0
+#define DEBUG_DATA_SPACE_PHYSICAL      1
+#define DEBUG_DATA_SPACE_CONTROL       2
+#define DEBUG_DATA_SPACE_IO            3
+#define DEBUG_DATA_SPACE_MSR           4
+#define DEBUG_DATA_SPACE_BUS_DATA      5
+#define DEBUG_DATA_SPACE_DEBUGGER_DATA 6
+// Count of data spaces.
+#define DEBUG_DATA_SPACE_COUNT         7
+
+// Indices for ReadDebuggerData interface
+#define DEBUG_DATA_KernBase                              24
+#define DEBUG_DATA_BreakpointWithStatusAddr              32
+#define DEBUG_DATA_SavedContextAddr                      40
+#define DEBUG_DATA_KiCallUserModeAddr                    56
+#define DEBUG_DATA_KeUserCallbackDispatcherAddr          64
+#define DEBUG_DATA_PsLoadedModuleListAddr                72
+#define DEBUG_DATA_PsActiveProcessHeadAddr               80
+#define DEBUG_DATA_PspCidTableAddr                       88
+#define DEBUG_DATA_ExpSystemResourcesListAddr            96
+#define DEBUG_DATA_ExpPagedPoolDescriptorAddr           104
+#define DEBUG_DATA_ExpNumberOfPagedPoolsAddr            112
+#define DEBUG_DATA_KeTimeIncrementAddr                  120
+#define DEBUG_DATA_KeBugCheckCallbackListHeadAddr       128
+#define DEBUG_DATA_KiBugcheckDataAddr                   136
+#define DEBUG_DATA_IopErrorLogListHeadAddr              144
+#define DEBUG_DATA_ObpRootDirectoryObjectAddr           152
+#define DEBUG_DATA_ObpTypeObjectTypeAddr                160
+#define DEBUG_DATA_MmSystemCacheStartAddr               168
+#define DEBUG_DATA_MmSystemCacheEndAddr                 176
+#define DEBUG_DATA_MmSystemCacheWsAddr                  184
+#define DEBUG_DATA_MmPfnDatabaseAddr                    192
+#define DEBUG_DATA_MmSystemPtesStartAddr                200
+#define DEBUG_DATA_MmSystemPtesEndAddr                  208
+#define DEBUG_DATA_MmSubsectionBaseAddr                 216
+#define DEBUG_DATA_MmNumberOfPagingFilesAddr            224
+#define DEBUG_DATA_MmLowestPhysicalPageAddr             232
+#define DEBUG_DATA_MmHighestPhysicalPageAddr            240
+#define DEBUG_DATA_MmNumberOfPhysicalPagesAddr          248
+#define DEBUG_DATA_MmMaximumNonPagedPoolInBytesAddr     256
+#define DEBUG_DATA_MmNonPagedSystemStartAddr            264
+#define DEBUG_DATA_MmNonPagedPoolStartAddr              272
+#define DEBUG_DATA_MmNonPagedPoolEndAddr                280
+#define DEBUG_DATA_MmPagedPoolStartAddr                 288
+#define DEBUG_DATA_MmPagedPoolEndAddr                   296
+#define DEBUG_DATA_MmPagedPoolInformationAddr           304
+#define DEBUG_DATA_MmPageSize                           312
+#define DEBUG_DATA_MmSizeOfPagedPoolInBytesAddr         320
+#define DEBUG_DATA_MmTotalCommitLimitAddr               328
+#define DEBUG_DATA_MmTotalCommittedPagesAddr            336
+#define DEBUG_DATA_MmSharedCommitAddr                   344
+#define DEBUG_DATA_MmDriverCommitAddr                   352
+#define DEBUG_DATA_MmProcessCommitAddr                  360
+#define DEBUG_DATA_MmPagedPoolCommitAddr                368
+#define DEBUG_DATA_MmExtendedCommitAddr                 376
+#define DEBUG_DATA_MmZeroedPageListHeadAddr             384
+#define DEBUG_DATA_MmFreePageListHeadAddr               392
+#define DEBUG_DATA_MmStandbyPageListHeadAddr            400
+#define DEBUG_DATA_MmModifiedPageListHeadAddr           408
+#define DEBUG_DATA_MmModifiedNoWritePageListHeadAddr    416
+#define DEBUG_DATA_MmAvailablePagesAddr                 424
+#define DEBUG_DATA_MmResidentAvailablePagesAddr         432
+#define DEBUG_DATA_PoolTrackTableAddr                   440
+#define DEBUG_DATA_NonPagedPoolDescriptorAddr           448
+#define DEBUG_DATA_MmHighestUserAddressAddr             456
+#define DEBUG_DATA_MmSystemRangeStartAddr               464
+#define DEBUG_DATA_MmUserProbeAddressAddr               472
+#define DEBUG_DATA_KdPrintCircularBufferAddr            480
+#define DEBUG_DATA_KdPrintCircularBufferEndAddr         488
+#define DEBUG_DATA_KdPrintWritePointerAddr              496
+#define DEBUG_DATA_KdPrintRolloverCountAddr             504
+#define DEBUG_DATA_MmLoadedUserImageListAddr            512
+#define DEBUG_DATA_NtBuildLabAddr                       520
+#define DEBUG_DATA_KiNormalSystemCall                   528
+#define DEBUG_DATA_KiProcessorBlockAddr                 536
+#define DEBUG_DATA_MmUnloadedDriversAddr                544
+#define DEBUG_DATA_MmLastUnloadedDriverAddr             552
+#define DEBUG_DATA_MmTriageActionTakenAddr              560
+#define DEBUG_DATA_MmSpecialPoolTagAddr                 568
+#define DEBUG_DATA_KernelVerifierAddr                   576
+#define DEBUG_DATA_MmVerifierDataAddr                   584
+#define DEBUG_DATA_MmAllocatedNonPagedPoolAddr          592
+#define DEBUG_DATA_MmPeakCommitmentAddr                 600
+#define DEBUG_DATA_MmTotalCommitLimitMaximumAddr        608
+#define DEBUG_DATA_CmNtCSDVersionAddr                   616
+#define DEBUG_DATA_MmPhysicalMemoryBlockAddr            624
+#define DEBUG_DATA_MmSessionBase                        632
+#define DEBUG_DATA_MmSessionSize                        640
+#define DEBUG_DATA_MmSystemParentTablePage              648
+#define DEBUG_DATA_MmVirtualTranslationBase             656
+#define DEBUG_DATA_OffsetKThreadNextProcessor           664
+#define DEBUG_DATA_OffsetKThreadTeb                     666
+#define DEBUG_DATA_OffsetKThreadKernelStack             668
+#define DEBUG_DATA_OffsetKThreadInitialStack            670
+#define DEBUG_DATA_OffsetKThreadApcProcess              672
+#define DEBUG_DATA_OffsetKThreadState                   674
+#define DEBUG_DATA_OffsetKThreadBStore                  676
+#define DEBUG_DATA_OffsetKThreadBStoreLimit             678
+#define DEBUG_DATA_SizeEProcess                         680
+#define DEBUG_DATA_OffsetEprocessPeb                    682
+#define DEBUG_DATA_OffsetEprocessParentCID              684
+#define DEBUG_DATA_OffsetEprocessDirectoryTableBase     686
+#define DEBUG_DATA_SizePrcb                             688
+#define DEBUG_DATA_OffsetPrcbDpcRoutine                 690
+#define DEBUG_DATA_OffsetPrcbCurrentThread              692
+#define DEBUG_DATA_OffsetPrcbMhz                        694
+#define DEBUG_DATA_OffsetPrcbCpuType                    696
+#define DEBUG_DATA_OffsetPrcbVendorString               698
+#define DEBUG_DATA_OffsetPrcbProcessorState             700
+#define DEBUG_DATA_OffsetPrcbNumber                     702
+#define DEBUG_DATA_SizeEThread                          704
+#define DEBUG_DATA_KdPrintCircularBufferPtrAddr         712
+#define DEBUG_DATA_KdPrintBufferSizeAddr                720
+#define DEBUG_DATA_MmBadPagesDetected                   800
+#define DEBUG_DATA_EtwpDebuggerData                     816
+#define DEBUG_DATA_PteBase                              864
+
+#define DEBUG_DATA_PaeEnabled                        100000
+#define DEBUG_DATA_SharedUserData                    100008
+#define DEBUG_DATA_ProductType                       100016
+#define DEBUG_DATA_SuiteMask                         100024
+#define DEBUG_DATA_DumpWriterStatus                  100032
+#define DEBUG_DATA_DumpFormatVersion                 100040
+#define DEBUG_DATA_DumpWriterVersion                 100048
+#define DEBUG_DATA_DumpPowerState                    100056
+#define DEBUG_DATA_DumpMmStorage                     100064
+#define DEBUG_DATA_DumpAttributes                    100072
+
+//
+// Processor information structures.
+//
+
+typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_ALPHA
+{
+    ULONG Type;
+    ULONG Revision;
+} DEBUG_PROCESSOR_IDENTIFICATION_ALPHA, *PDEBUG_PROCESSOR_IDENTIFICATION_ALPHA;
+
+typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_AMD64
+{
+    ULONG Family;
+    ULONG Model;
+    ULONG Stepping;
+    CHAR  VendorString[16];
+} DEBUG_PROCESSOR_IDENTIFICATION_AMD64, *PDEBUG_PROCESSOR_IDENTIFICATION_AMD64;
+
+typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_IA64
+{
+    ULONG Model;
+    ULONG Revision;
+    ULONG Family;
+    ULONG ArchRev;
+    CHAR  VendorString[16];
+} DEBUG_PROCESSOR_IDENTIFICATION_IA64, *PDEBUG_PROCESSOR_IDENTIFICATION_IA64;
+
+typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_X86
+{
+    ULONG Family;
+    ULONG Model;
+    ULONG Stepping;
+    CHAR  VendorString[16];
+} DEBUG_PROCESSOR_IDENTIFICATION_X86, *PDEBUG_PROCESSOR_IDENTIFICATION_X86;
+
+typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_ARM
+{
+    ULONG Model;
+    ULONG Revision;
+    CHAR  VendorString[16];
+} DEBUG_PROCESSOR_IDENTIFICATION_ARM, *PDEBUG_PROCESSOR_IDENTIFICATION_ARM;
+
+typedef struct _DEBUG_PROCESSOR_IDENTIFICATION_ARM64
+{
+    ULONG Model;
+    ULONG Revision;
+    CHAR  VendorString[16];
+} DEBUG_PROCESSOR_IDENTIFICATION_ARM64, *PDEBUG_PROCESSOR_IDENTIFICATION_ARM64;
+
+typedef union _DEBUG_PROCESSOR_IDENTIFICATION_ALL
+{
+    DEBUG_PROCESSOR_IDENTIFICATION_ALPHA Alpha;
+    DEBUG_PROCESSOR_IDENTIFICATION_AMD64 Amd64;
+    DEBUG_PROCESSOR_IDENTIFICATION_IA64  Ia64;
+    DEBUG_PROCESSOR_IDENTIFICATION_X86   X86;
+    DEBUG_PROCESSOR_IDENTIFICATION_ARM   Arm;
+    DEBUG_PROCESSOR_IDENTIFICATION_ARM64 Arm64;
+} DEBUG_PROCESSOR_IDENTIFICATION_ALL, *PDEBUG_PROCESSOR_IDENTIFICATION_ALL;
+
+// Indices for ReadProcessorSystemData.
+#define DEBUG_DATA_KPCR_OFFSET                          0
+#define DEBUG_DATA_KPRCB_OFFSET                         1
+#define DEBUG_DATA_KTHREAD_OFFSET                       2
+#define DEBUG_DATA_BASE_TRANSLATION_VIRTUAL_OFFSET      3
+#define DEBUG_DATA_PROCESSOR_IDENTIFICATION             4
+#define DEBUG_DATA_PROCESSOR_SPEED                      5
+
+#undef INTERFACE
+#define INTERFACE IDebugDataSpaces
+DECLARE_INTERFACE_(IDebugDataSpaces, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugDataSpaces.
+    STDMETHOD(ReadVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    // SearchVirtual searches the given virtual
+    // address range for the given pattern.  PatternSize
+    // gives the byte length of the pattern and PatternGranularity
+    // controls the granularity of comparisons during
+    // the search.
+    // For example, a DWORD-granular search would
+    // use a pattern granularity of four to search by DWORD
+    // increments.
+    STDMETHOD(SearchVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Length,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _In_ ULONG PatternGranularity,
+        _Out_ PULONG64 MatchOffset
+        ) PURE;
+    // These methods are identical to Read/WriteVirtual
+    // except that they avoid the kernel virtual memory
+    // cache entirely and are therefore useful for reading
+    // virtual memory which is inherently volatile, such
+    // as memory-mapped device areas, without contaminating
+    // or invalidating the cache.
+    // In user-mode they are the same as Read/WriteVirtual.
+    STDMETHOD(ReadVirtualUncached)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteVirtualUncached)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    // The following two methods are convenience
+    // methods for accessing pointer values.
+    // They automatically convert between native pointers
+    // and canonical 64-bit values as necessary.
+    // These routines stop at the first failure.
+    STDMETHOD(ReadPointersVirtual)(
+        THIS_
+        _In_ ULONG Count,
+        _In_ ULONG64 Offset,
+        _Out_writes_(Count) PULONG64 Ptrs
+        ) PURE;
+    STDMETHOD(WritePointersVirtual)(
+        THIS_
+        _In_ ULONG Count,
+        _In_ ULONG64 Offset,
+        _In_reads_(Count) PULONG64 Ptrs
+        ) PURE;
+    // All non-virtual data spaces are only
+    // available when kernel debugging.
+    STDMETHOD(ReadPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WritePhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadControl)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteControl)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadIo)(
+        THIS_
+        _In_ ULONG InterfaceType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG AddressSpace,
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteIo)(
+        THIS_
+        _In_ ULONG InterfaceType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG AddressSpace,
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadMsr)(
+        THIS_
+        _In_ ULONG Msr,
+        _Out_ PULONG64 Value
+        ) PURE;
+    STDMETHOD(WriteMsr)(
+        THIS_
+        _In_ ULONG Msr,
+        _In_ ULONG64 Value
+        ) PURE;
+    STDMETHOD(ReadBusData)(
+        THIS_
+        _In_ ULONG BusDataType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG SlotNumber,
+        _In_ ULONG Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteBusData)(
+        THIS_
+        _In_ ULONG BusDataType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG SlotNumber,
+        _In_ ULONG Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(CheckLowMemory)(
+        THIS
+        ) PURE;
+    STDMETHOD(ReadDebuggerData)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+    STDMETHOD(ReadProcessorSystemData)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG Index,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+};
+
+//
+// Handle data types and structures.
+//
+
+#define DEBUG_HANDLE_DATA_TYPE_BASIC                 0
+#define DEBUG_HANDLE_DATA_TYPE_TYPE_NAME             1
+#define DEBUG_HANDLE_DATA_TYPE_OBJECT_NAME           2
+#define DEBUG_HANDLE_DATA_TYPE_HANDLE_COUNT          3
+#define DEBUG_HANDLE_DATA_TYPE_TYPE_NAME_WIDE        4
+#define DEBUG_HANDLE_DATA_TYPE_OBJECT_NAME_WIDE      5
+#define DEBUG_HANDLE_DATA_TYPE_MINI_THREAD_1         6
+#define DEBUG_HANDLE_DATA_TYPE_MINI_MUTANT_1         7
+#define DEBUG_HANDLE_DATA_TYPE_MINI_MUTANT_2         8
+#define DEBUG_HANDLE_DATA_TYPE_PER_HANDLE_OPERATIONS 9
+#define DEBUG_HANDLE_DATA_TYPE_ALL_HANDLE_OPERATIONS 10
+#define DEBUG_HANDLE_DATA_TYPE_MINI_PROCESS_1        11
+#define DEBUG_HANDLE_DATA_TYPE_MINI_PROCESS_2        12
+#define DEBUG_HANDLE_DATA_TYPE_MINI_EVENT_1          13
+#define DEBUG_HANDLE_DATA_TYPE_MINI_SECTION_1        14
+#define DEBUG_HANDLE_DATA_TYPE_MINI_SEMAPHORE_1      15
+
+typedef struct _DEBUG_HANDLE_DATA_BASIC
+{
+    ULONG TypeNameSize;
+    ULONG ObjectNameSize;
+    ULONG Attributes;
+    ULONG GrantedAccess;
+    ULONG HandleCount;
+    ULONG PointerCount;
+} DEBUG_HANDLE_DATA_BASIC, *PDEBUG_HANDLE_DATA_BASIC;
+
+#undef INTERFACE
+#define INTERFACE IDebugDataSpaces2
+DECLARE_INTERFACE_(IDebugDataSpaces2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugDataSpaces.
+    STDMETHOD(ReadVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    // SearchVirtual searches the given virtual
+    // address range for the given pattern.  PatternSize
+    // gives the byte length of the pattern and PatternGranularity
+    // controls the granularity of comparisons during
+    // the search.
+    // For example, a DWORD-granular search would
+    // use a pattern granularity of four to search by DWORD
+    // increments.
+    STDMETHOD(SearchVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Length,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _In_ ULONG PatternGranularity,
+        _Out_ PULONG64 MatchOffset
+        ) PURE;
+    // These methods are identical to Read/WriteVirtual
+    // except that they avoid the kernel virtual memory
+    // cache entirely and are therefore useful for reading
+    // virtual memory which is inherently volatile, such
+    // as memory-mapped device areas, without contaminating
+    // or invalidating the cache.
+    // In user-mode they are the same as Read/WriteVirtual.
+    STDMETHOD(ReadVirtualUncached)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteVirtualUncached)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    // The following two methods are convenience
+    // methods for accessing pointer values.
+    // They automatically convert between native pointers
+    // and canonical 64-bit values as necessary.
+    // These routines stop at the first failure.
+    STDMETHOD(ReadPointersVirtual)(
+        THIS_
+        _In_ ULONG Count,
+        _In_ ULONG64 Offset,
+        _Out_writes_(Count) PULONG64 Ptrs
+        ) PURE;
+    STDMETHOD(WritePointersVirtual)(
+        THIS_
+        _In_ ULONG Count,
+        _In_ ULONG64 Offset,
+        _In_reads_(Count) PULONG64 Ptrs
+        ) PURE;
+    // All non-virtual data spaces are only
+    // available when kernel debugging.
+    STDMETHOD(ReadPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WritePhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadControl)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteControl)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadIo)(
+        THIS_
+        _In_ ULONG InterfaceType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG AddressSpace,
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteIo)(
+        THIS_
+        _In_ ULONG InterfaceType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG AddressSpace,
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadMsr)(
+        THIS_
+        _In_ ULONG Msr,
+        _Out_ PULONG64 Value
+        ) PURE;
+    STDMETHOD(WriteMsr)(
+        THIS_
+        _In_ ULONG Msr,
+        _In_ ULONG64 Value
+        ) PURE;
+    STDMETHOD(ReadBusData)(
+        THIS_
+        _In_ ULONG BusDataType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG SlotNumber,
+        _In_ ULONG Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteBusData)(
+        THIS_
+        _In_ ULONG BusDataType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG SlotNumber,
+        _In_ ULONG Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(CheckLowMemory)(
+        THIS
+        ) PURE;
+    STDMETHOD(ReadDebuggerData)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+    STDMETHOD(ReadProcessorSystemData)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG Index,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+
+    // IDebugDataSpaces2.
+
+    STDMETHOD(VirtualToPhysical)(
+        THIS_
+        _In_ ULONG64 Virtual,
+        _Out_ PULONG64 Physical
+        ) PURE;
+    // Returns the physical addresses for the
+    // N levels of the systems paging structures.
+    // Level zero is the starting base physical
+    // address for virtual translations.
+    // Levels one-(N-1) will point to the appropriate
+    // paging descriptor for the virtual address at
+    // the given level of the paging hierarchy.  The
+    // exact number of levels depends on many factors.
+    // The last level will be the fully translated
+    // physical address, matching what VirtualToPhysical
+    // returns.  If the address can only be partially
+    // translated S_FALSE is returned.
+    STDMETHOD(GetVirtualTranslationPhysicalOffsets)(
+        THIS_
+        _In_ ULONG64 Virtual,
+        _Out_writes_opt_(OffsetsSize) PULONG64 Offsets,
+        _In_ ULONG OffsetsSize,
+        _Out_opt_ PULONG Levels
+        ) PURE;
+
+    // System handle data is accessible in certain
+    // debug sessions.  The particular data available
+    // varies from session to session and platform
+    // to platform.
+    STDMETHOD(ReadHandleData)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ ULONG DataType,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+
+    // Fills memory with the given pattern.
+    // The fill stops at the first non-writable byte.
+    STDMETHOD(FillVirtual)(
+        THIS_
+        _In_ ULONG64 Start,
+        _In_ ULONG Size,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _Out_opt_ PULONG Filled
+        ) PURE;
+    STDMETHOD(FillPhysical)(
+        THIS_
+        _In_ ULONG64 Start,
+        _In_ ULONG Size,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _Out_opt_ PULONG Filled
+        ) PURE;
+
+    // Queries virtual memory mapping information given
+    // an address similarly to the Win32 API VirtualQuery.
+    // MEMORY_BASIC_INFORMATION64 is defined in crash.h.
+    // This method currently only works for user-mode sessions.
+    STDMETHOD(QueryVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PMEMORY_BASIC_INFORMATION64 Info
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugDataSpaces3
+DECLARE_INTERFACE_(IDebugDataSpaces3, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugDataSpaces.
+    STDMETHOD(ReadVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    // SearchVirtual searches the given virtual
+    // address range for the given pattern.  PatternSize
+    // gives the byte length of the pattern and PatternGranularity
+    // controls the granularity of comparisons during
+    // the search.
+    // For example, a DWORD-granular search would
+    // use a pattern granularity of four to search by DWORD
+    // increments.
+    STDMETHOD(SearchVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Length,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _In_ ULONG PatternGranularity,
+        _Out_ PULONG64 MatchOffset
+        ) PURE;
+    // These methods are identical to Read/WriteVirtual
+    // except that they avoid the kernel virtual memory
+    // cache entirely and are therefore useful for reading
+    // virtual memory which is inherently volatile, such
+    // as memory-mapped device areas, without contaminating
+    // or invalidating the cache.
+    // In user-mode they are the same as Read/WriteVirtual.
+    STDMETHOD(ReadVirtualUncached)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteVirtualUncached)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    // The following two methods are convenience
+    // methods for accessing pointer values.
+    // They automatically convert between native pointers
+    // and canonical 64-bit values as necessary.
+    // These routines stop at the first failure.
+    STDMETHOD(ReadPointersVirtual)(
+        THIS_
+        _In_ ULONG Count,
+        _In_ ULONG64 Offset,
+        _Out_writes_(Count) PULONG64 Ptrs
+        ) PURE;
+    STDMETHOD(WritePointersVirtual)(
+        THIS_
+        _In_ ULONG Count,
+        _In_ ULONG64 Offset,
+        _In_reads_(Count) PULONG64 Ptrs
+        ) PURE;
+    // All non-virtual data spaces are only
+    // available when kernel debugging.
+    STDMETHOD(ReadPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WritePhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadControl)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteControl)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadIo)(
+        THIS_
+        _In_ ULONG InterfaceType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG AddressSpace,
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteIo)(
+        THIS_
+        _In_ ULONG InterfaceType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG AddressSpace,
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadMsr)(
+        THIS_
+        _In_ ULONG Msr,
+        _Out_ PULONG64 Value
+        ) PURE;
+    STDMETHOD(WriteMsr)(
+        THIS_
+        _In_ ULONG Msr,
+        _In_ ULONG64 Value
+        ) PURE;
+    STDMETHOD(ReadBusData)(
+        THIS_
+        _In_ ULONG BusDataType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG SlotNumber,
+        _In_ ULONG Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteBusData)(
+        THIS_
+        _In_ ULONG BusDataType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG SlotNumber,
+        _In_ ULONG Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(CheckLowMemory)(
+        THIS
+        ) PURE;
+    STDMETHOD(ReadDebuggerData)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+    STDMETHOD(ReadProcessorSystemData)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG Index,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+
+    // IDebugDataSpaces2.
+
+    STDMETHOD(VirtualToPhysical)(
+        THIS_
+        _In_ ULONG64 Virtual,
+        _Out_ PULONG64 Physical
+        ) PURE;
+    // Returns the physical addresses for the
+    // N levels of the systems paging structures.
+    // Level zero is the starting base physical
+    // address for virtual translations.
+    // Levels one-(N-1) will point to the appropriate
+    // paging descriptor for the virtual address at
+    // the given level of the paging hierarchy.  The
+    // exact number of levels depends on many factors.
+    // The last level will be the fully translated
+    // physical address, matching what VirtualToPhysical
+    // returns.  If the address can only be partially
+    // translated S_FALSE is returned.
+    STDMETHOD(GetVirtualTranslationPhysicalOffsets)(
+        THIS_
+        _In_ ULONG64 Virtual,
+        _Out_writes_opt_(OffsetsSize) PULONG64 Offsets,
+        _In_ ULONG OffsetsSize,
+        _Out_opt_ PULONG Levels
+        ) PURE;
+
+    // System handle data is accessible in certain
+    // debug sessions.  The particular data available
+    // varies from session to session and platform
+    // to platform.
+    STDMETHOD(ReadHandleData)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ ULONG DataType,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+
+    // Fills memory with the given pattern.
+    // The fill stops at the first non-writable byte.
+    STDMETHOD(FillVirtual)(
+        THIS_
+        _In_ ULONG64 Start,
+        _In_ ULONG Size,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _Out_opt_ PULONG Filled
+        ) PURE;
+    STDMETHOD(FillPhysical)(
+        THIS_
+        _In_ ULONG64 Start,
+        _In_ ULONG Size,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _Out_opt_ PULONG Filled
+        ) PURE;
+
+    // Queries virtual memory mapping information given
+    // an address similarly to the Win32 API VirtualQuery.
+    // MEMORY_BASIC_INFORMATION64 is defined in crash.h.
+    // This method currently only works for user-mode sessions.
+    STDMETHOD(QueryVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PMEMORY_BASIC_INFORMATION64 Info
+        ) PURE;
+
+    // IDebugDataSpaces3.
+
+    // Convenience method for reading an image
+    // header from virtual memory.  Given the
+    // image base, this method determines where
+    // the NT headers are, validates the necessary
+    // markers and converts the headers into
+    // 64-bit form for consistency.
+    // A caller can check whether the headers were
+    // originally 32-bit by checking the optional
+    // header magic value.
+    // This method will not read ROM headers.
+    STDMETHOD(ReadImageNtHeaders)(
+        THIS_
+        _In_ ULONG64 ImageBase,
+        _Out_ PIMAGE_NT_HEADERS64 Headers
+        ) PURE;
+
+    // Some debug sessions have arbitrary additional
+    // data available.  For example, additional dump
+    // information files may contain extra information
+    // gathered at the same time as the primary dump.
+    // Such information is tagged with a unique identifier
+    // and can only be retrieved via the tag.
+    // Tagged data cannot be partially available; the
+    // tagged block is either fully present or completely
+    // absent.
+    STDMETHOD(ReadTagged)(
+        THIS_
+        _In_ LPGUID Tag,
+        _In_ ULONG Offset,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TotalSize
+        ) PURE;
+    STDMETHOD(StartEnumTagged)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetNextTagged)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ LPGUID Tag,
+        _Out_ PULONG Size
+        ) PURE;
+    STDMETHOD(EndEnumTagged)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+};
+
+#define DEBUG_OFFSINFO_VIRTUAL_SOURCE 0x00000001
+
+#define DEBUG_VSOURCE_INVALID              0x00000000
+#define DEBUG_VSOURCE_DEBUGGEE             0x00000001
+#define DEBUG_VSOURCE_MAPPED_IMAGE         0x00000002
+#define DEBUG_VSOURCE_DUMP_WITHOUT_MEMINFO 0x00000003
+
+#define DEBUG_VSEARCH_DEFAULT       0x00000000
+#define DEBUG_VSEARCH_WRITABLE_ONLY 0x00000001
+
+#define DEBUG_PHYSICAL_DEFAULT        0x00000000
+#define DEBUG_PHYSICAL_CACHED         0x00000001
+#define DEBUG_PHYSICAL_UNCACHED       0x00000002
+#define DEBUG_PHYSICAL_WRITE_COMBINED 0x00000003
+
+#undef INTERFACE
+#define INTERFACE IDebugDataSpaces4
+DECLARE_INTERFACE_(IDebugDataSpaces4, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugDataSpaces.
+
+    STDMETHOD(ReadVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    // SearchVirtual searches the given virtual
+    // address range for the given pattern.  PatternSize
+    // gives the byte length of the pattern and PatternGranularity
+    // controls the granularity of comparisons during
+    // the search.
+    // For example, a DWORD-granular search would
+    // use a pattern granularity of four to search by DWORD
+    // increments.
+    STDMETHOD(SearchVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Length,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _In_ ULONG PatternGranularity,
+        _Out_ PULONG64 MatchOffset
+        ) PURE;
+    // These methods are identical to Read/WriteVirtual
+    // except that they avoid the kernel virtual memory
+    // cache entirely and are therefore useful for reading
+    // virtual memory which is inherently volatile, such
+    // as memory-mapped device areas, without contaminating
+    // or invalidating the cache.
+    // In user-mode they are the same as Read/WriteVirtual.
+    STDMETHOD(ReadVirtualUncached)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteVirtualUncached)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    // The following two methods are convenience
+    // methods for accessing pointer values.
+    // They automatically convert between native pointers
+    // and canonical 64-bit values as necessary.
+    // These routines stop at the first failure.
+    STDMETHOD(ReadPointersVirtual)(
+        THIS_
+        _In_ ULONG Count,
+        _In_ ULONG64 Offset,
+        _Out_writes_(Count) PULONG64 Ptrs
+        ) PURE;
+    STDMETHOD(WritePointersVirtual)(
+        THIS_
+        _In_ ULONG Count,
+        _In_ ULONG64 Offset,
+        _In_reads_(Count) PULONG64 Ptrs
+        ) PURE;
+    // All non-virtual data spaces are only
+    // available when kernel debugging.
+    STDMETHOD(ReadPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WritePhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadControl)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteControl)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadIo)(
+        THIS_
+        _In_ ULONG InterfaceType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG AddressSpace,
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteIo)(
+        THIS_
+        _In_ ULONG InterfaceType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG AddressSpace,
+        _In_ ULONG64 Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(ReadMsr)(
+        THIS_
+        _In_ ULONG Msr,
+        _Out_ PULONG64 Value
+        ) PURE;
+    STDMETHOD(WriteMsr)(
+        THIS_
+        _In_ ULONG Msr,
+        _In_ ULONG64 Value
+        ) PURE;
+    STDMETHOD(ReadBusData)(
+        THIS_
+        _In_ ULONG BusDataType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG SlotNumber,
+        _In_ ULONG Offset,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteBusData)(
+        THIS_
+        _In_ ULONG BusDataType,
+        _In_ ULONG BusNumber,
+        _In_ ULONG SlotNumber,
+        _In_ ULONG Offset,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(CheckLowMemory)(
+        THIS
+        ) PURE;
+    STDMETHOD(ReadDebuggerData)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+    STDMETHOD(ReadProcessorSystemData)(
+        THIS_
+        _In_ ULONG Processor,
+        _In_ ULONG Index,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+
+    // IDebugDataSpaces2.
+
+    STDMETHOD(VirtualToPhysical)(
+        THIS_
+        _In_ ULONG64 Virtual,
+        _Out_ PULONG64 Physical
+        ) PURE;
+    // Returns the physical addresses for the
+    // N levels of the systems paging structures.
+    // Level zero is the starting base physical
+    // address for virtual translations.
+    // Levels one-(N-1) will point to the appropriate
+    // paging descriptor for the virtual address at
+    // the given level of the paging hierarchy.  The
+    // exact number of levels depends on many factors.
+    // The last level will be the fully translated
+    // physical address, matching what VirtualToPhysical
+    // returns.  If the address can only be partially
+    // translated S_FALSE is returned.
+    STDMETHOD(GetVirtualTranslationPhysicalOffsets)(
+        THIS_
+        _In_ ULONG64 Virtual,
+        _Out_writes_opt_(OffsetsSize) PULONG64 Offsets,
+        _In_ ULONG OffsetsSize,
+        _Out_opt_ PULONG Levels
+        ) PURE;
+
+    // System handle data is accessible in certain
+    // debug sessions.  The particular data available
+    // varies from session to session and platform
+    // to platform.
+    STDMETHOD(ReadHandleData)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ ULONG DataType,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG DataSize
+        ) PURE;
+
+    // Fills memory with the given pattern.
+    // The fill stops at the first non-writable byte.
+    STDMETHOD(FillVirtual)(
+        THIS_
+        _In_ ULONG64 Start,
+        _In_ ULONG Size,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _Out_opt_ PULONG Filled
+        ) PURE;
+    STDMETHOD(FillPhysical)(
+        THIS_
+        _In_ ULONG64 Start,
+        _In_ ULONG Size,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _Out_opt_ PULONG Filled
+        ) PURE;
+
+    // Queries virtual memory mapping information given
+    // an address similarly to the Win32 API VirtualQuery.
+    // MEMORY_BASIC_INFORMATION64 is defined in crash.h.
+    // This method currently only works for user-mode sessions.
+    STDMETHOD(QueryVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PMEMORY_BASIC_INFORMATION64 Info
+        ) PURE;
+
+    // IDebugDataSpaces3.
+
+    // Convenience method for reading an image
+    // header from virtual memory.  Given the
+    // image base, this method determines where
+    // the NT headers are, validates the necessary
+    // markers and converts the headers into
+    // 64-bit form for consistency.
+    // A caller can check whether the headers were
+    // originally 32-bit by checking the optional
+    // header magic value.
+    // This method will not read ROM headers.
+    STDMETHOD(ReadImageNtHeaders)(
+        THIS_
+        _In_ ULONG64 ImageBase,
+        _Out_ PIMAGE_NT_HEADERS64 Headers
+        ) PURE;
+
+    // Some debug sessions have arbitrary additional
+    // data available.  For example, additional dump
+    // information files may contain extra information
+    // gathered at the same time as the primary dump.
+    // Such information is tagged with a unique identifier
+    // and can only be retrieved via the tag.
+    // Tagged data cannot be partially available; the
+    // tagged block is either fully present or completely
+    // absent.
+    STDMETHOD(ReadTagged)(
+        THIS_
+        _In_ LPGUID Tag,
+        _In_ ULONG Offset,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG TotalSize
+        ) PURE;
+    STDMETHOD(StartEnumTagged)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetNextTagged)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ LPGUID Tag,
+        _Out_ PULONG Size
+        ) PURE;
+    STDMETHOD(EndEnumTagged)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    // IDebugDataSpaces4.
+
+    // General information about an address in the given data space.
+    // Queries are from DEBUG_OFFSINFO_*.
+    STDMETHOD(GetOffsetInformation)(
+        THIS_
+        _In_ ULONG Space,
+        _In_ ULONG Which,
+        _In_ ULONG64 Offset,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG InfoSize
+        ) PURE;
+
+    // Given a particular address, return the
+    // next address which has a different validity.
+    // For example, in debug sessions such as a live
+    // user-mode session where virtual address validity
+    // changes from page to page this will return the
+    // page after the given page.  In sessions such as
+    // a user-mode dump file where validity can change
+    // from byte to byte this will return the start of
+    // the next region that has different validity.
+    STDMETHOD(GetNextDifferentlyValidOffsetVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG64 NextOffset
+        ) PURE;
+
+    // Given a particular range of virtual addresses,
+    // find the first region which is valid memory.
+    STDMETHOD(GetValidRegionVirtual)(
+        THIS_
+        _In_ ULONG64 Base,
+        _In_ ULONG Size,
+        _Out_ PULONG64 ValidBase,
+        _Out_ PULONG ValidSize
+        ) PURE;
+
+    STDMETHOD(SearchVirtual2)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Length,
+        _In_ ULONG Flags,
+        _In_reads_bytes_(PatternSize) PVOID Pattern,
+        _In_ ULONG PatternSize,
+        _In_ ULONG PatternGranularity,
+        _Out_ PULONG64 MatchOffset
+        ) PURE;
+
+    // Attempts to read a multi-byte string
+    // starting at the given virtual address.
+    // The possible string length, including terminator,
+    // is capped at the given max size.
+    // If a return buffer is given it will always
+    // be terminated.
+    STDMETHOD(ReadMultiByteStringVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG MaxBytes,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringBytes
+        ) PURE;
+    // Reads a multi-byte string and converts
+    // it to Unicode using the given code page.
+    STDMETHOD(ReadMultiByteStringVirtualWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG MaxBytes,
+        _In_ ULONG CodePage,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringBytes
+        ) PURE;
+    STDMETHOD(ReadUnicodeStringVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG MaxBytes,
+        _In_ ULONG CodePage,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringBytes
+        ) PURE;
+    STDMETHOD(ReadUnicodeStringVirtualWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG MaxBytes,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringBytes
+        ) PURE;
+
+    STDMETHOD(ReadPhysical2)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WritePhysical2)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugEventCallbacks.
+//
+//----------------------------------------------------------------------------
+
+// Interest mask bits.
+#define DEBUG_EVENT_BREAKPOINT              0x00000001
+#define DEBUG_EVENT_EXCEPTION               0x00000002
+#define DEBUG_EVENT_CREATE_THREAD           0x00000004
+#define DEBUG_EVENT_EXIT_THREAD             0x00000008
+#define DEBUG_EVENT_CREATE_PROCESS          0x00000010
+#define DEBUG_EVENT_EXIT_PROCESS            0x00000020
+#define DEBUG_EVENT_LOAD_MODULE             0x00000040
+#define DEBUG_EVENT_UNLOAD_MODULE           0x00000080
+#define DEBUG_EVENT_SYSTEM_ERROR            0x00000100
+#define DEBUG_EVENT_SESSION_STATUS          0x00000200
+#define DEBUG_EVENT_CHANGE_DEBUGGEE_STATE   0x00000400
+#define DEBUG_EVENT_CHANGE_ENGINE_STATE     0x00000800
+#define DEBUG_EVENT_CHANGE_SYMBOL_STATE     0x00001000
+#define DEBUG_EVENT_SERVICE_EXCEPTION       0x00002000
+
+// SessionStatus flags.
+// A debuggee has been discovered for the session.
+#define DEBUG_SESSION_ACTIVE                       0x00000000
+// The session has been ended by EndSession.
+#define DEBUG_SESSION_END_SESSION_ACTIVE_TERMINATE 0x00000001
+#define DEBUG_SESSION_END_SESSION_ACTIVE_DETACH    0x00000002
+#define DEBUG_SESSION_END_SESSION_PASSIVE          0x00000003
+// The debuggee has run to completion.  User-mode only.
+#define DEBUG_SESSION_END                          0x00000004
+// The target machine has rebooted.  Kernel-mode only.
+#define DEBUG_SESSION_REBOOT                       0x00000005
+// The target machine has hibernated.  Kernel-mode only.
+#define DEBUG_SESSION_HIBERNATE                    0x00000006
+// The engine was unable to continue the session.
+#define DEBUG_SESSION_FAILURE                      0x00000007
+
+// ChangeDebuggeeState flags.
+// The debuggees state has changed generally, such
+// as when the debuggee has been executing.
+// Argument is zero.
+#define DEBUG_CDS_ALL       0xffffffff
+// Registers have changed.  If only a single register
+// changed, argument is the index of the register.
+// Otherwise it is DEBUG_ANY_ID.
+#define DEBUG_CDS_REGISTERS 0x00000001
+// Data spaces have changed.  If only a single
+// space was affected, argument is the data
+// space.  Otherwise it is DEBUG_ANY_ID.
+#define DEBUG_CDS_DATA      0x00000002
+// Inform the GUI clients to refresh debugger windows.
+#define DEBUG_CDS_REFRESH   0x00000004
+
+// DEBUG_CDS_REFRESH IDs
+#define DEBUG_CDS_REFRESH_EVALUATE                  1
+#define DEBUG_CDS_REFRESH_EXECUTE                   2
+#define DEBUG_CDS_REFRESH_EXECUTECOMMANDFILE        3
+#define DEBUG_CDS_REFRESH_ADDBREAKPOINT             4
+#define DEBUG_CDS_REFRESH_REMOVEBREAKPOINT          5
+#define DEBUG_CDS_REFRESH_WRITEVIRTUAL              6
+#define DEBUG_CDS_REFRESH_WRITEVIRTUALUNCACHED      7
+#define DEBUG_CDS_REFRESH_WRITEPHYSICAL             8
+#define DEBUG_CDS_REFRESH_WRITEPHYSICAL2            9
+#define DEBUG_CDS_REFRESH_SETVALUE                 10
+#define DEBUG_CDS_REFRESH_SETVALUE2                11
+#define DEBUG_CDS_REFRESH_SETSCOPE                 12
+#define DEBUG_CDS_REFRESH_SETSCOPEFRAMEBYINDEX     13
+#define DEBUG_CDS_REFRESH_SETSCOPEFROMJITDEBUGINFO 14
+#define DEBUG_CDS_REFRESH_SETSCOPEFROMSTOREDEVENT  15
+#define DEBUG_CDS_REFRESH_INLINESTEP               16
+#define DEBUG_CDS_REFRESH_INLINESTEP_PSEUDO        17
+
+// ChangeEngineState flags.
+// The engine state has changed generally.
+// Argument is zero.
+#define DEBUG_CES_ALL                 0xffffffff
+// Current thread changed.  This may imply a change
+// of system and process also.  Argument is the ID of the new
+// current thread or DEBUG_ANY_ID if no thread is current.
+#define DEBUG_CES_CURRENT_THREAD      0x00000001
+// Effective processor changed.  Argument is the
+// new processor type.
+#define DEBUG_CES_EFFECTIVE_PROCESSOR 0x00000002
+// Breakpoints changed.  If only a single breakpoint
+// changed, argument is the ID of the breakpoint.
+// Otherwise it is DEBUG_ANY_ID.
+#define DEBUG_CES_BREAKPOINTS         0x00000004
+// Code interpretation level changed.  Argument is
+// the new level.
+#define DEBUG_CES_CODE_LEVEL          0x00000008
+// Execution status changed.  Argument is the new
+// execution status.
+#define DEBUG_CES_EXECUTION_STATUS    0x00000010
+// Engine options have changed.  Argument is the new
+// options value.
+#define DEBUG_CES_ENGINE_OPTIONS      0x00000020
+// Log file information has changed.  Argument
+// is TRUE if a log file was opened and FALSE if
+// a log file was closed.
+#define DEBUG_CES_LOG_FILE            0x00000040
+// Default number radix has changed.  Argument
+// is the new radix.
+#define DEBUG_CES_RADIX               0x00000080
+// Event filters changed.  If only a single filter
+// changed the argument is the filter's index,
+// otherwise it is DEBUG_ANY_ID.
+#define DEBUG_CES_EVENT_FILTERS       0x00000100
+// Process options have changed.  Argument is the new
+// options value.
+#define DEBUG_CES_PROCESS_OPTIONS     0x00000200
+// Extensions have been added or removed.
+#define DEBUG_CES_EXTENSIONS          0x00000400
+// Systems have been added or removed.  The argument
+// is the system ID.  Systems, unlike processes and
+// threads, may be created at any time and not
+// just during WaitForEvent.
+#define DEBUG_CES_SYSTEMS             0x00000800
+// Assembly/disassembly options have changed.  Argument
+// is the new options value.
+#define DEBUG_CES_ASSEMBLY_OPTIONS    0x00001000
+// Expression syntax has changed.  Argument
+// is the new syntax value.
+#define DEBUG_CES_EXPRESSION_SYNTAX   0x00002000
+// Text replacements have changed.
+#define DEBUG_CES_TEXT_REPLACEMENTS   0x00004000
+
+// ChangeSymbolState flags.
+// Symbol state has changed generally, such
+// as after reload operations.  Argument is zero.
+#define DEBUG_CSS_ALL            0xffffffff
+// Modules have been loaded.  If only a
+// single module changed, argument is the
+// base address of the module.  Otherwise
+// it is zero.
+#define DEBUG_CSS_LOADS          0x00000001
+// Modules have been unloaded.  If only a
+// single module changed, argument is the
+// base address of the module.  Otherwise
+// it is zero.
+#define DEBUG_CSS_UNLOADS        0x00000002
+// Current symbol scope changed.
+#define DEBUG_CSS_SCOPE          0x00000004
+// Paths have changed.
+#define DEBUG_CSS_PATHS          0x00000008
+// Symbol options have changed.  Argument is the new
+// options value.
+#define DEBUG_CSS_SYMBOL_OPTIONS 0x00000010
+// Type options have changed.  Argument is the new
+// options value.
+#define DEBUG_CSS_TYPE_OPTIONS   0x00000020
+// Inform that the current Scope Symbol format has been changed,
+// so the client needs to update the symbols on Locals/Watch/..
+// and the engine will collapse any expanded child
+#define DEBUG_CSS_COLLAPSE_CHILDREN 0x00000040
+
+
+#undef INTERFACE
+#define INTERFACE IDebugEventCallbacks
+DECLARE_INTERFACE_(IDebugEventCallbacks, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugEventCallbacks.
+
+    // The engine calls GetInterestMask once when
+    // the event callbacks are set for a client.
+    STDMETHOD(GetInterestMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+
+    // A breakpoint event is generated when
+    // a breakpoint exception is received and
+    // it can be mapped to an existing breakpoint.
+    // The callback method is given a reference
+    // to the breakpoint and should release it when
+    // it is done with it.
+    STDMETHOD(Breakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT Bp
+        ) PURE;
+
+    // Exceptions include breaks which cannot
+    // be mapped to an existing breakpoint
+    // instance.
+    STDMETHOD(Exception)(
+        THIS_
+        _In_ PEXCEPTION_RECORD64 Exception,
+        _In_ ULONG FirstChance
+        ) PURE;
+
+    // Any of these values can be zero if they
+    // cannot be provided by the engine.
+    // Currently the kernel does not return thread
+    // or process change events.
+    STDMETHOD(CreateThread)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 DataOffset,
+        _In_ ULONG64 StartOffset
+        ) PURE;
+    STDMETHOD(ExitThread)(
+        THIS_
+        _In_ ULONG ExitCode
+        ) PURE;
+
+    // Any of these values can be zero if they
+    // cannot be provided by the engine.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_opt_ PCSTR ModuleName,
+        _In_opt_ PCSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp,
+        _In_ ULONG64 InitialThreadHandle,
+        _In_ ULONG64 ThreadDataOffset,
+        _In_ ULONG64 StartOffset
+        ) PURE;
+    _Analysis_noreturn_
+    STDMETHOD(ExitProcess)(
+        THIS_
+        _In_ ULONG ExitCode
+        ) PURE;
+
+    // Any of these values may be zero.
+    STDMETHOD(LoadModule)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_opt_ PCSTR ModuleName,
+        _In_opt_ PCSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp
+        ) PURE;
+    STDMETHOD(UnloadModule)(
+        THIS_
+        _In_opt_ PCSTR ImageBaseName,
+        _In_ ULONG64 BaseOffset
+        ) PURE;
+
+    STDMETHOD(SystemError)(
+        THIS_
+        _In_ ULONG Error,
+        _In_ ULONG Level
+        ) PURE;
+
+    // Session status is synchronous like the other
+    // wait callbacks but it is called as the state
+    // of the session is changing rather than at
+    // specific events so its return value does not
+    // influence waiting.  Implementations should just
+    // return DEBUG_STATUS_NO_CHANGE.
+    // Also, because some of the status
+    // notifications are very early or very
+    // late in the session lifetime there may not be
+    // current processes or threads when the notification
+    // is generated.
+    STDMETHOD(SessionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // The following callbacks are informational
+    // callbacks notifying the provider about
+    // changes in debug state.  The return value
+    // of these callbacks is ignored.  Implementations
+    // can not call back into the engine.
+
+    // Debuggee state, such as registers or data spaces,
+    // has changed.
+    STDMETHOD(ChangeDebuggeeState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        ) PURE;
+    // Engine state has changed.
+    STDMETHOD(ChangeEngineState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        ) PURE;
+    // Symbol state has changed.
+    STDMETHOD(ChangeSymbolState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugEventCallbacksWide
+DECLARE_INTERFACE_(IDebugEventCallbacksWide, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugEventCallbacksWide.
+
+    // The engine calls GetInterestMask once when
+    // the event callbacks are set for a client.
+    STDMETHOD(GetInterestMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+
+    // A breakpoint event is generated when
+    // a breakpoint exception is received and
+    // it can be mapped to an existing breakpoint.
+    // The callback method is given a reference
+    // to the breakpoint and should release it when
+    // it is done with it.
+    STDMETHOD(Breakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT2 Bp
+        ) PURE;
+
+    // Exceptions include breaks which cannot
+    // be mapped to an existing breakpoint
+    // instance.
+    STDMETHOD(Exception)(
+        THIS_
+        _In_ PEXCEPTION_RECORD64 Exception,
+        _In_ ULONG FirstChance
+        ) PURE;
+
+    // Any of these values can be zero if they
+    // cannot be provided by the engine.
+    // Currently the kernel does not return thread
+    // or process change events.
+    STDMETHOD(CreateThread)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 DataOffset,
+        _In_ ULONG64 StartOffset
+        ) PURE;
+    _Analysis_noreturn_
+    STDMETHOD(ExitThread)(
+        THIS_
+        _In_ ULONG ExitCode
+        ) PURE;
+
+    // Any of these values can be zero if they
+    // cannot be provided by the engine.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_opt_ PCWSTR ModuleName,
+        _In_opt_ PCWSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp,
+        _In_ ULONG64 InitialThreadHandle,
+        _In_ ULONG64 ThreadDataOffset,
+        _In_ ULONG64 StartOffset
+        ) PURE;
+    STDMETHOD(ExitProcess)(
+        THIS_
+        _In_ ULONG ExitCode
+        ) PURE;
+
+    // Any of these values may be zero.
+    STDMETHOD(LoadModule)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_opt_ PCWSTR ModuleName,
+        _In_opt_ PCWSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp
+        ) PURE;
+    STDMETHOD(UnloadModule)(
+        THIS_
+        _In_opt_ PCWSTR ImageBaseName,
+        _In_ ULONG64 BaseOffset
+        ) PURE;
+
+    STDMETHOD(SystemError)(
+        THIS_
+        _In_ ULONG Error,
+        _In_ ULONG Level
+        ) PURE;
+
+    // Session status is synchronous like the other
+    // wait callbacks but it is called as the state
+    // of the session is changing rather than at
+    // specific events so its return value does not
+    // influence waiting.  Implementations should just
+    // return DEBUG_STATUS_NO_CHANGE.
+    // Also, because some of the status
+    // notifications are very early or very
+    // late in the session lifetime there may not be
+    // current processes or threads when the notification
+    // is generated.
+    STDMETHOD(SessionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // The following callbacks are informational
+    // callbacks notifying the provider about
+    // changes in debug state.  The return value
+    // of these callbacks is ignored.  Implementations
+    // can not call back into the engine.
+
+    // Debuggee state, such as registers or data spaces,
+    // has changed.
+    STDMETHOD(ChangeDebuggeeState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        ) PURE;
+    // Engine state has changed.
+    STDMETHOD(ChangeEngineState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        ) PURE;
+    // Symbol state has changed.
+    STDMETHOD(ChangeSymbolState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        ) PURE;
+};
+
+typedef struct _DEBUG_EVENT_CONTEXT
+{
+    ULONG Size;
+    ULONG ProcessEngineId;
+    ULONG ThreadEngineId;
+    ULONG FrameEngineId;
+} DEBUG_EVENT_CONTEXT, *PDEBUG_EVENT_CONTEXT;
+
+#undef INTERFACE
+#define INTERFACE IDebugEventContextCallbacks
+DECLARE_INTERFACE_(IDebugEventContextCallbacks, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugEventContextCallbacks.
+
+    // The engine calls GetInterestMask once when
+    // the event callbacks are set for a client.
+    STDMETHOD(GetInterestMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+
+    // A breakpoint event is generated when
+    // a breakpoint exception is received and
+    // it can be mapped to an existing breakpoint.
+    // The callback method is given a reference
+    // to the breakpoint and should release it when
+    // it is done with it.
+    STDMETHOD(Breakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT2 Bp,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+
+    // Exceptions include breaks which cannot
+    // be mapped to an existing breakpoint
+    // instance.
+    STDMETHOD(Exception)(
+        THIS_
+        _In_ PEXCEPTION_RECORD64 Exception,
+        _In_ ULONG FirstChance,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+
+    // Any of these values can be zero if they
+    // cannot be provided by the engine.
+    // Currently the kernel does not return thread
+    // or process change events.
+    STDMETHOD(CreateThread)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 DataOffset,
+        _In_ ULONG64 StartOffset,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+    STDMETHOD(ExitThread)(
+        THIS_
+        _In_ ULONG ExitCode,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+
+    // Any of these values can be zero if they
+    // cannot be provided by the engine.
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_opt_ PCWSTR ModuleName,
+        _In_opt_ PCWSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp,
+        _In_ ULONG64 InitialThreadHandle,
+        _In_ ULONG64 ThreadDataOffset,
+        _In_ ULONG64 StartOffset,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+    STDMETHOD(ExitProcess)(
+        THIS_
+        _In_ ULONG ExitCode,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+
+    // Any of these values may be zero.
+    STDMETHOD(LoadModule)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_opt_ PCWSTR ModuleName,
+        _In_opt_ PCWSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+    STDMETHOD(UnloadModule)(
+        THIS_
+        _In_opt_ PCWSTR ImageBaseName,
+        _In_ ULONG64 BaseOffset,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+
+    STDMETHOD(SystemError)(
+        THIS_
+        _In_ ULONG Error,
+        _In_ ULONG Level,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+
+    // Session status is synchronous like the other
+    // wait callbacks but it is called as the state
+    // of the session is changing rather than at
+    // specific events so its return value does not
+    // influence waiting.  Implementations should just
+    // return DEBUG_STATUS_NO_CHANGE.
+    // Also, because some of the status
+    // notifications are very early or very
+    // late in the session lifetime there may not be
+    // current processes or threads when the notification
+    // is generated.
+    STDMETHOD(SessionStatus)(
+        THIS_
+        _In_ ULONG Status
+        ) PURE;
+
+    // The following callbacks are informational
+    // callbacks notifying the provider about
+    // changes in debug state.  The return value
+    // of these callbacks is ignored.  Implementations
+    // can not call back into the engine.
+
+    // Debuggee state, such as registers or data spaces,
+    // has changed.
+    STDMETHOD(ChangeDebuggeeState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+    // Engine state has changed.
+    STDMETHOD(ChangeEngineState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument,
+        _In_reads_bytes_(ContextSize) PVOID Context,
+        _In_ ULONG ContextSize
+        ) PURE;
+    // Symbol state has changed.
+    STDMETHOD(ChangeSymbolState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugInputCallbacks.
+//
+//----------------------------------------------------------------------------
+
+#undef INTERFACE
+#define INTERFACE IDebugInputCallbacks
+DECLARE_INTERFACE_(IDebugInputCallbacks, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugInputCallbacks.
+
+    // A call to the StartInput method is a request for
+    // a line of input from any client.  The returned input
+    // should always be zero-terminated.  The buffer size
+    // provided is only a guideline.  A client can return
+    // more if necessary and the engine will truncate it
+    // before returning from IDebugControl::Input.
+    // The return value is ignored.
+    STDMETHOD(StartInput)(
+        THIS_
+        _In_ ULONG BufferSize
+        ) PURE;
+    // The return value is ignored.
+    STDMETHOD(EndInput)(
+        THIS
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugOutputCallbacks.
+//
+//----------------------------------------------------------------------------
+
+#undef INTERFACE
+#define INTERFACE IDebugOutputCallbacks
+DECLARE_INTERFACE_(IDebugOutputCallbacks, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugOutputCallbacks.
+
+    // This method is only called if the supplied mask
+    // is allowed by the clients output control.
+    // The return value is ignored.
+    STDMETHOD(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Text
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugOutputCallbacksWide
+DECLARE_INTERFACE_(IDebugOutputCallbacksWide, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugOutputCallbacksWide.
+
+    // This method is only called if the supplied mask
+    // is allowed by the clients output control.
+    // The return value is ignored.
+    STDMETHOD(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCWSTR Text
+        ) PURE;
+};
+
+//
+// IDebugOutputCallbacks2 interest mask flags.
+//
+
+// Indicates that the callback wants notifications
+// of all explicit flushes.
+#define DEBUG_OUTCBI_EXPLICIT_FLUSH 0x00000001
+// Indicates that the callback wants
+// content in text form.
+#define DEBUG_OUTCBI_TEXT           0x00000002
+// Indicates that the callback wants
+// content in markup form.
+#define DEBUG_OUTCBI_DML            0x00000004
+
+#define DEBUG_OUTCBI_ANY_FORMAT     0x00000006
+
+//
+// Different kinds of output callback notifications
+// that can be sent to Output2.
+//
+
+// Plain text content, flags are below, argument is mask.
+#define DEBUG_OUTCB_TEXT           0
+// Debugger markup content, flags are below, argument is mask.
+#define DEBUG_OUTCB_DML            1
+// Notification of an explicit output flush, flags and argument are zero.
+#define DEBUG_OUTCB_EXPLICIT_FLUSH 2
+
+//
+// Flags for various Output2 callbacks.
+//
+
+// The content string was followed by an
+// explicit flush.  This flag will be used
+// instead of a separate DEBUG_OUTCB_EXPLICIT_FLUSH
+// callback when a flush has text to flush,
+// thus avoiding two callbacks.
+#define DEBUG_OUTCBF_COMBINED_EXPLICIT_FLUSH    0x00000001
+
+// The markup content string has embedded tags.
+#define DEBUG_OUTCBF_DML_HAS_TAGS               0x00000002
+// The markup content has encoded special characters like ", &, < and >.
+#define DEBUG_OUTCBF_DML_HAS_SPECIAL_CHARACTERS 0x00000004
+
+#undef INTERFACE
+#define INTERFACE IDebugOutputCallbacks2
+DECLARE_INTERFACE_(IDebugOutputCallbacks2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugOutputCallbacks.
+
+    // This method is not used.
+    STDMETHOD(Output)(
+        THIS_
+        _In_ ULONG Mask,
+        _In_ PCSTR Text
+        ) PURE;
+
+    // IDebugOutputCallbacks2.
+
+    // The engine calls GetInterestMask once when
+    // the callbacks are set for a client.
+    STDMETHOD(GetInterestMask)(
+        THIS_
+        _Out_ PULONG Mask
+        ) PURE;
+    
+    STDMETHOD(Output2)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG Flags,
+        _In_ ULONG64 Arg,
+        _In_opt_ PCWSTR Text
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugRegisters.
+//
+//----------------------------------------------------------------------------
+
+#define DEBUG_REGISTERS_DEFAULT 0x00000000
+#define DEBUG_REGISTERS_INT32   0x00000001
+#define DEBUG_REGISTERS_INT64   0x00000002
+#define DEBUG_REGISTERS_FLOAT   0x00000004
+#define DEBUG_REGISTERS_ALL     0x00000007
+
+#define DEBUG_REGISTER_SUB_REGISTER 0x00000001
+
+typedef struct _DEBUG_REGISTER_DESCRIPTION
+{
+    // DEBUG_VALUE type.
+    ULONG Type;
+    ULONG Flags;
+
+    // If this is a subregister the full
+    // registers description index is
+    // given in SubregMaster.  The length, mask
+    // and shift describe how the subregisters
+    // bits fit into the full register.
+    ULONG SubregMaster;
+    ULONG SubregLength;
+    ULONG64 SubregMask;
+    ULONG SubregShift;
+
+    ULONG Reserved0;
+} DEBUG_REGISTER_DESCRIPTION, *PDEBUG_REGISTER_DESCRIPTION;
+
+#undef INTERFACE
+#define INTERFACE IDebugRegisters
+DECLARE_INTERFACE_(IDebugRegisters, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugRegisters.
+    STDMETHOD(GetNumberRegisters)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetDescription)(
+        THIS_
+        _In_ ULONG Register,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PDEBUG_REGISTER_DESCRIPTION Desc
+        ) PURE;
+    STDMETHOD(GetIndexByName)(
+        THIS_
+        _In_ PCSTR Name,
+        _Out_ PULONG Index
+        ) PURE;
+
+    STDMETHOD(GetValue)(
+        THIS_
+        _In_ ULONG Register,
+        _Out_ PDEBUG_VALUE Value
+        ) PURE;
+    // SetValue makes a best effort at coercing
+    // the given value into the given registers
+    // value type.  If the given value is larger
+    // than the register can hold the least
+    // significant bits will be dropped.  Float
+    // to int and int to float will be done
+    // if necessary.  Subregister bits will be
+    // inserted into the master register.
+    STDMETHOD(SetValue)(
+        THIS_
+        _In_ ULONG Register,
+        _In_ PDEBUG_VALUE Value
+        ) PURE;
+    // Gets Count register values.  If Indices is
+    // non-NULL it must contain Count register
+    // indices which control the registers affected.
+    // If Indices is NULL the registers from Start
+    // to Start + Count  1 are retrieved.
+    STDMETHOD(GetValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Indices,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_VALUE Values
+        ) PURE;
+    STDMETHOD(SetValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Indices,
+        _In_ ULONG Start,
+        _In_reads_(Count) PDEBUG_VALUE Values
+        ) PURE;
+
+    // Outputs a group of registers in a well-formatted
+    // way thats specific to the platforms register set.
+    // Uses the line prefix.
+    STDMETHOD(OutputRegisters)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Abstracted pieces of processor information.
+    // The mapping of these values to architectural
+    // registers is architecture-specific and their
+    // interpretation and existence may vary.  They
+    // are intended to be directly compatible with
+    // calls which take this information, such as
+    // stack walking.
+    STDMETHOD(GetInstructionOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetStackOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetFrameOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+};
+
+//
+// The engine maintains several separate
+// pieces of context information.  There is
+// the current debuggee context, a possible
+// override context, such as from .cxr,
+// a context for the current scope frame and so on.
+//
+
+// Get register information from the debuggee.
+#define DEBUG_REGSRC_DEBUGGEE 0x00000000
+// Get register information from an explicit
+// override context, such as one set by .cxr.
+// If there is no override context the request will fail.
+#define DEBUG_REGSRC_EXPLICIT 0x00000001
+// Get register information from the current scope
+// frame.  Note that stack unwinding does not guarantee
+// accurate updating of the register context,
+// so scope frame register context may not be accurate
+// in all cases.
+#define DEBUG_REGSRC_FRAME    0x00000002
+
+#undef INTERFACE
+#define INTERFACE IDebugRegisters2
+DECLARE_INTERFACE_(IDebugRegisters2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugRegisters.
+
+    STDMETHOD(GetNumberRegisters)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetDescription)(
+        THIS_
+        _In_ ULONG Register,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PDEBUG_REGISTER_DESCRIPTION Desc
+        ) PURE;
+    STDMETHOD(GetIndexByName)(
+        THIS_
+        _In_ PCSTR Name,
+        _Out_ PULONG Index
+        ) PURE;
+
+    STDMETHOD(GetValue)(
+        THIS_
+        _In_ ULONG Register,
+        _Out_ PDEBUG_VALUE Value
+        ) PURE;
+    // SetValue makes a best effort at coercing
+    // the given value into the given registers
+    // value type.  If the given value is larger
+    // than the register can hold the least
+    // significant bits will be dropped.  Float
+    // to int and int to float will be done
+    // if necessary.  Subregister bits will be
+    // inserted into the master register.
+    STDMETHOD(SetValue)(
+        THIS_
+        _In_ ULONG Register,
+        _In_ PDEBUG_VALUE Value
+        ) PURE;
+    // Gets Count register values.  If Indices is
+    // non-NULL it must contain Count register
+    // indices which control the registers affected.
+    // If Indices is NULL the registers from Start
+    // to Start + Count  1 are retrieved.
+    STDMETHOD(GetValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Indices,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_VALUE Values
+        ) PURE;
+    STDMETHOD(SetValues)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Indices,
+        _In_ ULONG Start,
+        _In_reads_(Count) PDEBUG_VALUE Values
+        ) PURE;
+
+    // Outputs a group of registers in a well-formatted
+    // way thats specific to the platforms register set.
+    // Uses the line prefix.
+    STDMETHOD(OutputRegisters)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Abstracted pieces of processor information.
+    // The mapping of these values to architectural
+    // registers is architecture-specific and their
+    // interpretation and existence may vary.  They
+    // are intended to be directly compatible with
+    // calls which take this information, such as
+    // stack walking.
+    STDMETHOD(GetInstructionOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetStackOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetFrameOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+
+    // IDebugRegisters2.
+
+    STDMETHOD(GetDescriptionWide)(
+        THIS_
+        _In_ ULONG Register,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PDEBUG_REGISTER_DESCRIPTION Desc
+        ) PURE;
+    STDMETHOD(GetIndexByNameWide)(
+        THIS_
+        _In_ PCWSTR Name,
+        _Out_ PULONG Index
+        ) PURE;
+
+    // Pseudo-registers are synthetic values derived
+    // by the engine that are presented in a manner
+    // similar to regular registers.  They are simple
+    // value holders, similar to actual registers.
+    // Pseudo-registers are defined for concepts,
+    // such as current-instruction-pointer or
+    // current-thread-data.  As such they have
+    // types appropriate for their data.
+    STDMETHOD(GetNumberPseudoRegisters)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetPseudoDescription)(
+        THIS_
+        _In_ ULONG Register,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 TypeModule,
+        _Out_opt_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetPseudoDescriptionWide)(
+        THIS_
+        _In_ ULONG Register,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 TypeModule,
+        _Out_opt_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetPseudoIndexByName)(
+        THIS_
+        _In_ PCSTR Name,
+        _Out_ PULONG Index
+        ) PURE;
+    STDMETHOD(GetPseudoIndexByNameWide)(
+        THIS_
+        _In_ PCWSTR Name,
+        _Out_ PULONG Index
+        ) PURE;
+    // Some pseudo-register values are affected
+    // by the register source, others are not.
+    STDMETHOD(GetPseudoValues)(
+        THIS_
+        _In_ ULONG Source,
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Indices,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_VALUE Values
+        ) PURE;
+    // Many pseudo-registers are read-only and cannot be set.
+    STDMETHOD(SetPseudoValues)(
+        THIS_
+        _In_ ULONG Source,
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Indices,
+        _In_ ULONG Start,
+        _In_reads_(Count) PDEBUG_VALUE Values
+        ) PURE;
+
+    // These expanded methods allow selection
+    // of the source of register information.
+    STDMETHOD(GetValues2)(
+        THIS_
+        _In_ ULONG Source,
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Indices,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_VALUE Values
+        ) PURE;
+    STDMETHOD(SetValues2)(
+        THIS_
+        _In_ ULONG Source,
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG Indices,
+        _In_ ULONG Start,
+        _In_reads_(Count) PDEBUG_VALUE Values
+        ) PURE;
+    STDMETHOD(OutputRegisters2)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Source,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(GetInstructionOffset2)(
+        THIS_
+        _In_ ULONG Source,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetStackOffset2)(
+        THIS_
+        _In_ ULONG Source,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetFrameOffset2)(
+        THIS_
+        _In_ ULONG Source,
+        _Out_ PULONG64 Offset
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugSymbolGroup
+//
+//----------------------------------------------------------------------------
+
+// OutputSymbols flags.
+// Default output contains
+//   <Name>**NAME**<Offset>**OFF**<Value>**VALUE**<Type>**TYPE**
+// per symbol.
+#define DEBUG_OUTPUT_SYMBOLS_DEFAULT    0x00000000
+#define DEBUG_OUTPUT_SYMBOLS_NO_NAMES   0x00000001
+#define DEBUG_OUTPUT_SYMBOLS_NO_OFFSETS 0x00000002
+#define DEBUG_OUTPUT_SYMBOLS_NO_VALUES  0x00000004
+#define DEBUG_OUTPUT_SYMBOLS_NO_TYPES   0x00000010
+
+#define DEBUG_OUTPUT_NAME_END           "**NAME**"
+#define DEBUG_OUTPUT_OFFSET_END         "**OFF**"
+#define DEBUG_OUTPUT_VALUE_END          "**VALUE**"
+#define DEBUG_OUTPUT_TYPE_END           "**TYPE**"
+
+#define DEBUG_OUTPUT_NAME_END_WIDE      L"**NAME**"
+#define DEBUG_OUTPUT_OFFSET_END_WIDE    L"**OFF**"
+#define DEBUG_OUTPUT_VALUE_END_WIDE     L"**VALUE**"
+#define DEBUG_OUTPUT_TYPE_END_WIDE      L"**TYPE**"
+
+#ifdef UNICODE
+#define DEBUG_OUTPUT_NAME_END_T DEBUG_OUTPUT_NAME_END_WIDE
+#define DEBUG_OUTPUT_OFFSET_END_T DEBUG_OUTPUT_OFFSET_END_WIDE
+#define DEBUG_OUTPUT_VALUE_END_T DEBUG_OUTPUT_VALUE_END_WIDE
+#define DEBUG_OUTPUT_TYPE_END_T DEBUG_OUTPUT_TYPE_END_WIDE
+#else
+#define DEBUG_OUTPUT_NAME_END_T DEBUG_OUTPUT_NAME_END
+#define DEBUG_OUTPUT_OFFSET_END_T DEBUG_OUTPUT_OFFSET_END
+#define DEBUG_OUTPUT_VALUE_END_T DEBUG_OUTPUT_VALUE_END
+#define DEBUG_OUTPUT_TYPE_END_T DEBUG_OUTPUT_TYPE_END
+#endif
+
+// DEBUG_SYMBOL_PARAMETERS flags.
+// Cumulative expansion level, takes four bits.
+#define DEBUG_SYMBOL_EXPANSION_LEVEL_MASK 0x0000000f
+// Symbols subelements follow.
+#define DEBUG_SYMBOL_EXPANDED             0x00000010
+// Symbols value is read-only.
+#define DEBUG_SYMBOL_READ_ONLY            0x00000020
+// Symbol subelements are array elements.
+#define DEBUG_SYMBOL_IS_ARRAY             0x00000040
+// Symbol is a float value.
+#define DEBUG_SYMBOL_IS_FLOAT             0x00000080
+// Symbol is a scope argument.
+#define DEBUG_SYMBOL_IS_ARGUMENT          0x00000100
+// Symbol is a scope argument.
+#define DEBUG_SYMBOL_IS_LOCAL             0x00000200
+
+typedef struct _DEBUG_SYMBOL_PARAMETERS
+{
+    ULONG64 Module;
+    ULONG TypeId;
+    // ParentSymbol may be DEBUG_ANY_ID when unknown.
+    ULONG ParentSymbol;
+    // A subelement of a symbol can be a field, such
+    // as in structs, unions or classes; or an array
+    // element count for arrays.
+    ULONG SubElements;
+    ULONG Flags;
+    ULONG64 Reserved;
+} DEBUG_SYMBOL_PARAMETERS, *PDEBUG_SYMBOL_PARAMETERS;
+
+#undef INTERFACE
+#define INTERFACE IDebugSymbolGroup
+DECLARE_INTERFACE_(IDebugSymbolGroup, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSymbolGroup.
+    STDMETHOD(GetNumberSymbols)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // On input Index indicates the desired insertion
+    // index.  On output Index contains the actual index.
+    // Use DEBUG_ANY_ID to append a symbol to the end.
+    STDMETHOD(AddSymbol)(
+        THIS_
+        _In_ PCSTR Name,
+        _Inout_ PULONG Index
+        ) PURE;
+    STDMETHOD(RemoveSymbolByName)(
+        THIS_
+        _In_ PCSTR Name
+        ) PURE;
+    STDMETHOD(RemoveSymbolByIndex)(
+        THIS_
+        _In_ ULONG Index
+        ) PURE;
+    STDMETHOD(GetSymbolName)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    STDMETHOD(GetSymbolParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PDEBUG_SYMBOL_PARAMETERS Params
+        ) PURE;
+    STDMETHOD(ExpandSymbol)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ BOOL Expand
+        ) PURE;
+    // Uses the line prefix.
+    STDMETHOD(OutputSymbols)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ ULONG Start,
+        _In_ ULONG Count
+        ) PURE;
+    STDMETHOD(WriteSymbol)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Value
+        ) PURE;
+    STDMETHOD(OutputAsType)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Type
+        ) PURE;
+};
+
+#define DEBUG_SYMENT_IS_CODE      0x00000001
+#define DEBUG_SYMENT_IS_DATA      0x00000002
+#define DEBUG_SYMENT_IS_PARAMETER 0x00000004
+#define DEBUG_SYMENT_IS_LOCAL     0x00000008
+#define DEBUG_SYMENT_IS_MANAGED   0x00000010
+#define DEBUG_SYMENT_IS_SYNTHETIC 0x00000020
+
+typedef struct _DEBUG_SYMBOL_ENTRY
+{
+    ULONG64 ModuleBase;
+    ULONG64 Offset;
+    ULONG64 Id;
+    ULONG64 Arg64;
+    ULONG Size;
+    ULONG Flags;
+    ULONG TypeId;
+    ULONG NameSize;
+    ULONG Token;
+    ULONG Tag;
+    ULONG Arg32;
+    ULONG Reserved;
+} DEBUG_SYMBOL_ENTRY, *PDEBUG_SYMBOL_ENTRY;
+
+#undef INTERFACE
+#define INTERFACE IDebugSymbolGroup2
+DECLARE_INTERFACE_(IDebugSymbolGroup2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSymbolGroup.
+
+    STDMETHOD(GetNumberSymbols)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // On input Index indicates the desired insertion
+    // index.  On output Index contains the actual index.
+    // Use DEBUG_ANY_ID to append a symbol to the end.
+    STDMETHOD(AddSymbol)(
+        THIS_
+        _In_ PCSTR Name,
+        _Inout_ PULONG Index
+        ) PURE;
+    STDMETHOD(RemoveSymbolByName)(
+        THIS_
+        _In_ PCSTR Name
+        ) PURE;
+    STDMETHOD(RemoveSymbolByIndex)(
+        THIS_
+        _In_ ULONG Index
+        ) PURE;
+    STDMETHOD(GetSymbolName)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    STDMETHOD(GetSymbolParameters)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PDEBUG_SYMBOL_PARAMETERS Params
+        ) PURE;
+    STDMETHOD(ExpandSymbol)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ BOOL Expand
+        ) PURE;
+    // Uses the line prefix.
+    STDMETHOD(OutputSymbols)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ ULONG Start,
+        _In_ ULONG Count
+        ) PURE;
+    STDMETHOD(WriteSymbol)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Value
+        ) PURE;
+    STDMETHOD(OutputAsType)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCSTR Type
+        ) PURE;
+
+    // IDebugSymbolGroup2.
+
+    STDMETHOD(AddSymbolWide)(
+        THIS_
+        _In_ PCWSTR Name,
+        _Inout_ PULONG Index
+        ) PURE;
+    STDMETHOD(RemoveSymbolByNameWide)(
+        THIS_
+        _In_ PCWSTR Name
+        ) PURE;
+    STDMETHOD(GetSymbolNameWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    STDMETHOD(WriteSymbolWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Value
+        ) PURE;
+    STDMETHOD(OutputAsTypeWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ PCWSTR Type
+        ) PURE;
+
+    STDMETHOD(GetSymbolTypeName)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    STDMETHOD(GetSymbolTypeNameWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    STDMETHOD(GetSymbolSize)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PULONG Size
+        ) PURE;
+    // If the symbol has an absolute address
+    // this method will retrieve it.
+    STDMETHOD(GetSymbolOffset)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // If the symbol is enregistered this
+    // method will return the register index.
+    STDMETHOD(GetSymbolRegister)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PULONG Register
+        ) PURE;
+    STDMETHOD(GetSymbolValueText)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    STDMETHOD(GetSymbolValueTextWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    STDMETHOD(GetSymbolEntryInformation)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PDEBUG_SYMBOL_ENTRY Entry
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugSymbols.
+//
+//----------------------------------------------------------------------------
+
+//
+// Information about a module.
+//
+
+// Flags.
+#define DEBUG_MODULE_LOADED            0x00000000
+#define DEBUG_MODULE_UNLOADED          0x00000001
+#define DEBUG_MODULE_USER_MODE         0x00000002
+#define DEBUG_MODULE_EXE_MODULE        0x00000004
+#define DEBUG_MODULE_EXPLICIT          0x00000008
+#define DEBUG_MODULE_SECONDARY         0x00000010
+#define DEBUG_MODULE_SYNTHETIC         0x00000020
+#define DEBUG_MODULE_SYM_BAD_CHECKSUM  0x00010000
+
+// Symbol types.
+#define DEBUG_SYMTYPE_NONE     0
+#define DEBUG_SYMTYPE_COFF     1
+#define DEBUG_SYMTYPE_CODEVIEW 2
+#define DEBUG_SYMTYPE_PDB      3
+#define DEBUG_SYMTYPE_EXPORT   4
+#define DEBUG_SYMTYPE_DEFERRED 5
+#define DEBUG_SYMTYPE_SYM      6
+#define DEBUG_SYMTYPE_DIA      7
+
+typedef struct _DEBUG_MODULE_PARAMETERS
+{
+    ULONG64 Base;
+    ULONG Size;
+    ULONG TimeDateStamp;
+    ULONG Checksum;
+    ULONG Flags;
+    ULONG SymbolType;
+    ULONG ImageNameSize;
+    ULONG ModuleNameSize;
+    ULONG LoadedImageNameSize;
+    ULONG SymbolFileNameSize;
+    ULONG MappedImageNameSize;
+    ULONG64 Reserved[2];
+} DEBUG_MODULE_PARAMETERS, *PDEBUG_MODULE_PARAMETERS;
+
+// Scope arguments are function arguments
+// and thus only change when the scope
+// crosses functions.
+#define DEBUG_SCOPE_GROUP_ARGUMENTS    0x00000001
+// Scope locals are locals declared in a particular
+// scope and are only defined within that scope.
+#define DEBUG_SCOPE_GROUP_LOCALS       0x00000002
+// All symbols in the scope.
+#define DEBUG_SCOPE_GROUP_ALL          0x00000003
+// Get Debug Symbols by using Data Model engine
+#define DEBUG_SCOPE_GROUP_BY_DATAMODEL 0x00000004
+// Valid flags for the set of DEBUG_SCOPE_GROUP
+// If you add a new flag, then please add it to DEBUG_SCOPE_GROUP_VALID_FLAGS
+#define DEBUG_SCOPE_GROUP_VALID_FLAGS (DEBUG_SCOPE_GROUP_ALL | DEBUG_SCOPE_GROUP_BY_DATAMODEL)
+
+
+// Typed data output control flags.
+#define DEBUG_OUTTYPE_DEFAULT              0x00000000
+#define DEBUG_OUTTYPE_NO_INDENT            0x00000001
+#define DEBUG_OUTTYPE_NO_OFFSET            0x00000002
+#define DEBUG_OUTTYPE_VERBOSE              0x00000004
+#define DEBUG_OUTTYPE_COMPACT_OUTPUT       0x00000008
+#define DEBUG_OUTTYPE_RECURSION_LEVEL(Max) (((Max) & 0xf) << 4)
+#define DEBUG_OUTTYPE_ADDRESS_OF_FIELD     0x00010000
+#define DEBUG_OUTTYPE_ADDRESS_AT_END       0x00020000
+#define DEBUG_OUTTYPE_BLOCK_RECURSE        0x00200000
+
+// FindSourceFile flags.
+#define DEBUG_FIND_SOURCE_DEFAULT      0x00000000
+// Returns fully-qualified paths only.  If this
+// is not set the path returned may be relative.
+#define DEBUG_FIND_SOURCE_FULL_PATH    0x00000001
+// Scans all the path elements for a match and
+// returns the one that has the most similarity
+// between the given file and the matching element.
+#define DEBUG_FIND_SOURCE_BEST_MATCH   0x00000002
+// Do not search source server paths.
+#define DEBUG_FIND_SOURCE_NO_SRCSRV    0x00000004
+// Restrict FindSourceFileAndToken to token lookup only.
+#define DEBUG_FIND_SOURCE_TOKEN_LOOKUP 0x00000008
+// Indicates that the FileToken/FileTokenSize arguments refer to the checksum
+// information for the source file obtained from a call to the 
+// GetSourceFileInformation method with the 'Which' parameter
+// set to DEBUG_SRCFILE_SYMBOL_CHECKSUMINFO
+#define DEBUG_FIND_SOURCE_WITH_CHECKSUM 0x00000010
+
+// A special value marking an offset that should not
+// be treated as a valid offset.  This is only used
+// in special situations where it is unlikely that
+// this value would be a valid offset.
+#define DEBUG_INVALID_OFFSET ((ULONG64)-1)
+
+// Module index sort order used by GetModuleByIndex() API.
+#define MODULE_ORDERS_MASK       0xF0000000
+#define MODULE_ORDERS_LOADTIME   0x10000000
+#define MODULE_ORDERS_MODULENAME 0x20000000
+
+#undef INTERFACE
+#define INTERFACE IDebugSymbols
+DECLARE_INTERFACE_(IDebugSymbols, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSymbols.
+
+    // Controls the symbol options used during
+    // symbol operations.
+    // Uses the same flags as dbghelps SymSetOptions.
+    STDMETHOD(GetSymbolOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    STDMETHOD(GetNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    // A symbol name may not be unique, particularly
+    // when overloaded functions exist which all
+    // have the same name.  If GetOffsetByName
+    // finds multiple matches for the name it
+    // can return any one of them.  In that
+    // case it will return S_FALSE to indicate
+    // that ambiguity was arbitrarily resolved.
+    // A caller can then use SearchSymbols to
+    // find all of the matches if it wishes to
+    // perform different disambiguation.
+    STDMETHOD(GetOffsetByName)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // GetNearNameByOffset returns symbols
+    // located near the symbol closest to
+    // to the offset, such as the previous
+    // or next symbol.  If Delta is zero it
+    // operates identically to GetNameByOffset.
+    // If Delta is nonzero and such a symbol
+    // does not exist an error is returned.
+    // The next symbol, if one exists, will
+    // always have a higher offset than the
+    // input offset so the displacement is
+    // always negative.  The situation is
+    // reversed for the previous symbol.
+    STDMETHOD(GetNearNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByLine)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCSTR File,
+        _Out_ PULONG64 Offset
+        ) PURE;
+
+    // Enumerates the engines list of modules
+    // loaded for the current process.  This may
+    // or may not match the system module list
+    // for the process.  Reload can be used to
+    // synchronize the engines list with the system
+    // if necessary.
+    // Some sessions also track recently unloaded
+    // code modules for help in analyzing failures
+    // where an attempt is made to call unloaded code.
+    // These modules are indexed after the loaded
+    // modules.
+    STDMETHOD(GetNumberModules)(
+        THIS_
+        _Out_ PULONG Loaded,
+        _Out_ PULONG Unloaded
+        ) PURE;
+    STDMETHOD(GetModuleByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PULONG64 Base
+        ) PURE;
+    // The module name may not be unique.
+    // This method returns the first match.
+    STDMETHOD(GetModuleByModuleName)(
+        THIS_
+        _In_ PCSTR Name,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // Offset can be any offset within
+    // the module extent.  Extents may
+    // not be unique when including unloaded
+    // drivers.  This method returns the
+    // first match.
+    STDMETHOD(GetModuleByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    STDMETHOD(GetModuleNames)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(ImageNameBufferSize) PSTR ImageNameBuffer,
+        _In_ ULONG ImageNameBufferSize,
+        _Out_opt_ PULONG ImageNameSize,
+        _Out_writes_opt_(ModuleNameBufferSize) PSTR ModuleNameBuffer,
+        _In_ ULONG ModuleNameBufferSize,
+        _Out_opt_ PULONG ModuleNameSize,
+        _Out_writes_opt_(LoadedImageNameBufferSize) PSTR LoadedImageNameBuffer,
+        _In_ ULONG LoadedImageNameBufferSize,
+        _Out_opt_ PULONG LoadedImageNameSize
+        ) PURE;
+    STDMETHOD(GetModuleParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG64 Bases,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_MODULE_PARAMETERS Params
+        ) PURE;
+    // Looks up the module from a <Module>!<Symbol>
+    // string.
+    STDMETHOD(GetSymbolModule)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Base
+        ) PURE;
+
+    // Returns the string name of a type.
+    STDMETHOD(GetTypeName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    // Returns the ID for a type name.
+    STDMETHOD(GetTypeId)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ PCSTR Name,
+        _Out_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetTypeSize)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_ PULONG Size
+        ) PURE;
+    // Given a type which can contain members
+    // this method returns the offset of a
+    // particular member within the type.
+    // TypeId should give the container type ID
+    // and Field gives the dot-separated path
+    // to the field of interest.
+    STDMETHOD(GetFieldOffset)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ PCSTR Field,
+        _Out_ PULONG Offset
+        ) PURE;
+
+    STDMETHOD(GetSymbolTypeId)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+    // As with GetOffsetByName a symbol's
+    // name may be ambiguous.  GetOffsetTypeId
+    // returns the type for the symbol closest
+    // to the given offset and can be used
+    // to avoid ambiguity.
+    STDMETHOD(GetOffsetTypeId)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+
+    // Helpers for virtual and physical data
+    // which combine creation of a location with
+    // the actual operation.
+    STDMETHOD(ReadTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataVirtual)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(ReadTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataPhysical)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Function arguments and scope block symbols
+    // can be retrieved relative to currently
+    // executing code.  A caller can provide just
+    // a code offset for scoping purposes and look
+    // up names or the caller can provide a full frame
+    // and look up actual values.  The values for
+    // scoped symbols are best-guess and may or may not
+    // be accurate depending on program optimizations,
+    // the machine architecture, the current point
+    // in the programs execution and so on.
+    // A caller can also provide a complete register
+    // context for setting a scope to a previous
+    // machine state such as a context saved for
+    // an exception.  Usually this isnt necessary
+    // and the current register context is used.
+    STDMETHOD(GetScope)(
+        THIS_
+        _Out_opt_ PULONG64 InstructionOffset,
+        _Out_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _Out_writes_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // If ScopeFrame or ScopeContext is non-NULL then
+    // InstructionOffset is ignored.
+    // If ScopeContext is NULL the current
+    // register context is used.
+    // If the scope identified by the given
+    // information is the same as before
+    // SetScope returns S_OK.  If the scope
+    // information changes, such as when the
+    // scope moves between functions or scope
+    // blocks, SetScope returns S_FALSE.
+    STDMETHOD(SetScope)(
+        THIS_
+        _In_ ULONG64 InstructionOffset,
+        _In_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _In_reads_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // ResetScope clears the scope information
+    // for situations where scoped symbols
+    // mask global symbols or when resetting
+    // from explicit information to the current
+    // information.
+    STDMETHOD(ResetScope)(
+        THIS
+        ) PURE;
+    // A scope symbol is tied to its particular
+    // scope and only is meaningful within the scope.
+    // The returned group can be updated by passing it back
+    // into the method for lower-cost
+    // incremental updates when stepping.
+    STDMETHOD(GetScopeSymbolGroup)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PDEBUG_SYMBOL_GROUP Update,
+        _Out_ PDEBUG_SYMBOL_GROUP* Symbols
+        ) PURE;
+
+    // Create a new symbol group.
+    STDMETHOD(CreateSymbolGroup)(
+        THIS_
+        _Out_ PDEBUG_SYMBOL_GROUP* Group
+        ) PURE;
+
+    // StartSymbolMatch matches symbol names
+    // against the given pattern using simple
+    // regular expressions.  The search results
+    // are iterated through using GetNextSymbolMatch.
+    // When the caller is done examining results
+    // the match should be freed via EndSymbolMatch.
+    // If the match pattern contains a module name
+    // the search is restricted to a single module.
+    // Pattern matching is only done on symbol names,
+    // not module names.
+    // All active symbol match handles are invalidated
+    // when the set of loaded symbols changes.
+    STDMETHOD(StartSymbolMatch)(
+        THIS_
+        _In_ PCSTR Pattern,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Buffer is NULL the match does not
+    // advance.
+    STDMETHOD(GetNextSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MatchSize,
+        _Out_opt_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(EndSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Reload)(
+        THIS_
+        _In_ PCSTR Module
+        ) PURE;
+
+    STDMETHOD(GetSymbolPath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetSymbolPath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSymbolPath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Manipulate the path for executable images.
+    // Some dump files need to load executable images
+    // in order to resolve dump information.  This
+    // path controls where the engine looks for
+    // images.
+    STDMETHOD(GetImagePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetImagePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendImagePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Path routines for source file location
+    // methods.
+    STDMETHOD(GetSourcePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    // Gets the nth part of the source path.
+    STDMETHOD(GetSourcePathElement)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ElementSize
+        ) PURE;
+    STDMETHOD(SetSourcePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSourcePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+    // Uses the given file path and the source path
+    // information to try and locate an existing file.
+    // The given file path is merged with elements
+    // of the source path and checked for existence.
+    // If a match is found the element used is returned.
+    // A starting element can be specified to restrict
+    // the search to a subset of the path elements;
+    // this can be useful when checking for multiple
+    // matches along the source path.
+    // The returned element can be 1, indicating
+    // the file was found directly and not on the path.
+    STDMETHOD(FindSourceFile)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+    // Retrieves all the line offset information
+    // for a particular source file.  Buffer is
+    // first intialized to DEBUG_INVALID_OFFSET for
+    // every entry.  Then for each piece of line
+    // symbol information Buffer[Line] set to
+    // Lines offset.  This produces a per-line
+    // map of the offsets for the lines of the
+    // given file.  Line numbers are decremented
+    // for the map so Buffer[0] contains the offset
+    // for line number 1.
+    // If there is no line information at all for
+    // the given file the method fails rather
+    // than returning a map of invalid offsets.
+    STDMETHOD(GetSourceFileLineOffsets)(
+        THIS_
+        _In_ PCSTR File,
+        _Out_writes_opt_(BufferLines) PULONG64 Buffer,
+        _In_ ULONG BufferLines,
+        _Out_opt_ PULONG FileLines
+        ) PURE;
+};
+
+//
+// GetModuleNameString strings.
+//
+
+#define DEBUG_MODNAME_IMAGE        0x00000000
+#define DEBUG_MODNAME_MODULE       0x00000001
+#define DEBUG_MODNAME_LOADED_IMAGE 0x00000002
+#define DEBUG_MODNAME_SYMBOL_FILE  0x00000003
+#define DEBUG_MODNAME_MAPPED_IMAGE 0x00000004
+
+//
+// Type options, used with Get/SetTypeOptions.
+//
+
+// Display PUSHORT and USHORT arrays in Unicode.
+#define DEBUG_TYPEOPTS_UNICODE_DISPLAY    0x00000001
+// Display LONG types in default base instead of decimal.
+#define DEBUG_TYPEOPTS_LONGSTATUS_DISPLAY 0x00000002
+// Display integer types in default base instead of decimal.
+#define DEBUG_TYPEOPTS_FORCERADIX_OUTPUT  0x00000004
+// Search for the type/symbol with largest size when
+// multiple type/symbol match for a given name
+#define DEBUG_TYPEOPTS_MATCH_MAXSIZE      0x00000008
+
+#undef INTERFACE
+#define INTERFACE IDebugSymbols2
+DECLARE_INTERFACE_(IDebugSymbols2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSymbols.
+
+    // Controls the symbol options used during
+    // symbol operations.
+    // Uses the same flags as dbghelps SymSetOptions.
+    STDMETHOD(GetSymbolOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    STDMETHOD(GetNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    // A symbol name may not be unique, particularly
+    // when overloaded functions exist which all
+    // have the same name.  If GetOffsetByName
+    // finds multiple matches for the name it
+    // can return any one of them.  In that
+    // case it will return S_FALSE to indicate
+    // that ambiguity was arbitrarily resolved.
+    // A caller can then use SearchSymbols to
+    // find all of the matches if it wishes to
+    // perform different disambiguation.
+    STDMETHOD(GetOffsetByName)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // GetNearNameByOffset returns symbols
+    // located near the symbol closest to
+    // to the offset, such as the previous
+    // or next symbol.  If Delta is zero it
+    // operates identically to GetNameByOffset.
+    // If Delta is nonzero and such a symbol
+    // does not exist an error is returned.
+    // The next symbol, if one exists, will
+    // always have a higher offset than the
+    // input offset so the displacement is
+    // always negative.  The situation is
+    // reversed for the previous symbol.
+    STDMETHOD(GetNearNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByLine)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCSTR File,
+        _Out_ PULONG64 Offset
+        ) PURE;
+
+    // Enumerates the engines list of modules
+    // loaded for the current process.  This may
+    // or may not match the system module list
+    // for the process.  Reload can be used to
+    // synchronize the engines list with the system
+    // if necessary.
+    // Some sessions also track recently unloaded
+    // code modules for help in analyzing failures
+    // where an attempt is made to call unloaded code.
+    // These modules are indexed after the loaded
+    // modules.
+    STDMETHOD(GetNumberModules)(
+        THIS_
+        _Out_ PULONG Loaded,
+        _Out_ PULONG Unloaded
+        ) PURE;
+    STDMETHOD(GetModuleByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PULONG64 Base
+        ) PURE;
+    // The module name may not be unique.
+    // This method returns the first match.
+    STDMETHOD(GetModuleByModuleName)(
+        THIS_
+        _In_ PCSTR Name,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // Offset can be any offset within
+    // the module extent.  Extents may
+    // not be unique when including unloaded
+    // drivers.  This method returns the
+    // first match.
+    STDMETHOD(GetModuleByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    STDMETHOD(GetModuleNames)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(ImageNameBufferSize) PSTR ImageNameBuffer,
+        _In_ ULONG ImageNameBufferSize,
+        _Out_opt_ PULONG ImageNameSize,
+        _Out_writes_opt_(ModuleNameBufferSize) PSTR ModuleNameBuffer,
+        _In_ ULONG ModuleNameBufferSize,
+        _Out_opt_ PULONG ModuleNameSize,
+        _Out_writes_opt_(LoadedImageNameBufferSize) PSTR LoadedImageNameBuffer,
+        _In_ ULONG LoadedImageNameBufferSize,
+        _Out_opt_ PULONG LoadedImageNameSize
+        ) PURE;
+    STDMETHOD(GetModuleParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG64 Bases,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_MODULE_PARAMETERS Params
+        ) PURE;
+    // Looks up the module from a <Module>!<Symbol>
+    // string.
+    STDMETHOD(GetSymbolModule)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Base
+        ) PURE;
+
+    // Returns the string name of a type.
+    STDMETHOD(GetTypeName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    // Returns the ID for a type name.
+    STDMETHOD(GetTypeId)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ PCSTR Name,
+        _Out_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetTypeSize)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_ PULONG Size
+        ) PURE;
+    // Given a type which can contain members
+    // this method returns the offset of a
+    // particular member within the type.
+    // TypeId should give the container type ID
+    // and Field gives the dot-separated path
+    // to the field of interest.
+    STDMETHOD(GetFieldOffset)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ PCSTR Field,
+        _Out_ PULONG Offset
+        ) PURE;
+
+    STDMETHOD(GetSymbolTypeId)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+    // As with GetOffsetByName a symbol's
+    // name may be ambiguous.  GetOffsetTypeId
+    // returns the type for the symbol closest
+    // to the given offset and can be used
+    // to avoid ambiguity.
+    STDMETHOD(GetOffsetTypeId)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+
+    // Helpers for virtual and physical data
+    // which combine creation of a location with
+    // the actual operation.
+    STDMETHOD(ReadTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataVirtual)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(ReadTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataPhysical)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Function arguments and scope block symbols
+    // can be retrieved relative to currently
+    // executing code.  A caller can provide just
+    // a code offset for scoping purposes and look
+    // up names or the caller can provide a full frame
+    // and look up actual values.  The values for
+    // scoped symbols are best-guess and may or may not
+    // be accurate depending on program optimizations,
+    // the machine architecture, the current point
+    // in the programs execution and so on.
+    // A caller can also provide a complete register
+    // context for setting a scope to a previous
+    // machine state such as a context saved for
+    // an exception.  Usually this isnt necessary
+    // and the current register context is used.
+    STDMETHOD(GetScope)(
+        THIS_
+        _Out_opt_ PULONG64 InstructionOffset,
+        _Out_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _Out_writes_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // If ScopeFrame or ScopeContext is non-NULL then
+    // InstructionOffset is ignored.
+    // If ScopeContext is NULL the current
+    // register context is used.
+    // If the scope identified by the given
+    // information is the same as before
+    // SetScope returns S_OK.  If the scope
+    // information changes, such as when the
+    // scope moves between functions or scope
+    // blocks, SetScope returns S_FALSE.
+    STDMETHOD(SetScope)(
+        THIS_
+        _In_ ULONG64 InstructionOffset,
+        _In_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _In_reads_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // ResetScope clears the scope information
+    // for situations where scoped symbols
+    // mask global symbols or when resetting
+    // from explicit information to the current
+    // information.
+    STDMETHOD(ResetScope)(
+        THIS
+        ) PURE;
+    // A scope symbol is tied to its particular
+    // scope and only is meaningful within the scope.
+    // The returned group can be updated by passing it back
+    // into the method for lower-cost
+    // incremental updates when stepping.
+    STDMETHOD(GetScopeSymbolGroup)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PDEBUG_SYMBOL_GROUP Update,
+        _Out_ PDEBUG_SYMBOL_GROUP* Symbols
+        ) PURE;
+
+    // Create a new symbol group.
+    STDMETHOD(CreateSymbolGroup)(
+        THIS_
+        _Out_ PDEBUG_SYMBOL_GROUP* Group
+        ) PURE;
+
+    // StartSymbolMatch matches symbol names
+    // against the given pattern using simple
+    // regular expressions.  The search results
+    // are iterated through using GetNextSymbolMatch.
+    // When the caller is done examining results
+    // the match should be freed via EndSymbolMatch.
+    // If the match pattern contains a module name
+    // the search is restricted to a single module.
+    // Pattern matching is only done on symbol names,
+    // not module names.
+    // All active symbol match handles are invalidated
+    // when the set of loaded symbols changes.
+    STDMETHOD(StartSymbolMatch)(
+        THIS_
+        _In_ PCSTR Pattern,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Buffer is NULL the match does not
+    // advance.
+    STDMETHOD(GetNextSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MatchSize,
+        _Out_opt_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(EndSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Reload)(
+        THIS_
+        _In_ PCSTR Module
+        ) PURE;
+
+    STDMETHOD(GetSymbolPath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetSymbolPath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSymbolPath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Manipulate the path for executable images.
+    // Some dump files need to load executable images
+    // in order to resolve dump information.  This
+    // path controls where the engine looks for
+    // images.
+    STDMETHOD(GetImagePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetImagePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendImagePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Path routines for source file location
+    // methods.
+    STDMETHOD(GetSourcePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    // Gets the nth part of the source path.
+    STDMETHOD(GetSourcePathElement)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ElementSize
+        ) PURE;
+    STDMETHOD(SetSourcePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSourcePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+    // Uses the given file path and the source path
+    // information to try and locate an existing file.
+    // The given file path is merged with elements
+    // of the source path and checked for existence.
+    // If a match is found the element used is returned.
+    // A starting element can be specified to restrict
+    // the search to a subset of the path elements;
+    // this can be useful when checking for multiple
+    // matches along the source path.
+    // The returned element can be 1, indicating
+    // the file was found directly and not on the path.
+    STDMETHOD(FindSourceFile)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+    // Retrieves all the line offset information
+    // for a particular source file.  Buffer is
+    // first intialized to DEBUG_INVALID_OFFSET for
+    // every entry.  Then for each piece of line
+    // symbol information Buffer[Line] set to
+    // Lines offset.  This produces a per-line
+    // map of the offsets for the lines of the
+    // given file.  Line numbers are decremented
+    // for the map so Buffer[0] contains the offset
+    // for line number 1.
+    // If there is no line information at all for
+    // the given file the method fails rather
+    // than returning a map of invalid offsets.
+    STDMETHOD(GetSourceFileLineOffsets)(
+        THIS_
+        _In_ PCSTR File,
+        _Out_writes_opt_(BufferLines) PULONG64 Buffer,
+        _In_ ULONG BufferLines,
+        _Out_opt_ PULONG FileLines
+        ) PURE;
+
+    // IDebugSymbols2.
+
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    // Item is specified as in VerQueryValue.
+    // Module version information is only
+    // available for loaded modules and may
+    // not be available in all debug sessions.
+    STDMETHOD(GetModuleVersionInformation)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _In_ PCSTR Item,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG VerInfoSize
+        ) PURE;
+    // Retrieves any available module name string
+    // such as module name or symbol file name.
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    // If symbols are deferred an error will
+    // be returned.
+    // E_NOINTERFACE may be returned, indicating
+    // no information exists.
+    STDMETHOD(GetModuleNameString)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Returns the string name of a constant type.
+    STDMETHOD(GetConstantName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG64 Value,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Gets name of a field in a struct
+    // FieldNumber is 0 based index of field in a struct
+    STDMETHOD(GetFieldName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG FieldIndex,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Control options for typed values.
+    STDMETHOD(GetTypeOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+};
+
+//
+// GetModuleBy* flags.
+//
+
+// Scan all modules, loaded and unloaded.
+#define DEBUG_GETMOD_DEFAULT             0x00000000
+// Do not scan loaded modules.
+#define DEBUG_GETMOD_NO_LOADED_MODULES   0x00000001
+// Do not scan unloaded modules.
+#define DEBUG_GETMOD_NO_UNLOADED_MODULES 0x00000002
+
+//
+// AddSyntheticModule flags.
+//
+#define DEBUG_ADDSYNTHMOD_DEFAULT  0x00000000
+#define DEBUG_ADDSYNTHMOD_ZEROBASE 0x00000001
+
+//
+// AddSyntheticSymbol flags.
+//
+
+#define DEBUG_ADDSYNTHSYM_DEFAULT 0x00000000
+
+//
+// OutputSymbolByOffset flags.
+//
+
+// Use the current debugger settings for symbol output.
+#define DEBUG_OUTSYM_DEFAULT            0x00000000
+// Always display the offset in addition to any symbol hit.
+#define DEBUG_OUTSYM_FORCE_OFFSET       0x00000001
+// Display source line information if found.
+#define DEBUG_OUTSYM_SOURCE_LINE        0x00000002
+// Output symbol hits that don't exactly match.
+#define DEBUG_OUTSYM_ALLOW_DISPLACEMENT 0x00000004
+
+//
+// GetFunctionEntryByOffset flags.
+//
+
+#define DEBUG_GETFNENT_DEFAULT        0x00000000
+// The engine provides artificial entries for well-known
+// cases.  This flag limits the entry search to only
+// the raw entries and disables artificial entry lookup.
+#define DEBUG_GETFNENT_RAW_ENTRY_ONLY 0x00000001
+
+typedef struct _DEBUG_MODULE_AND_ID
+{
+    ULONG64 ModuleBase;
+    ULONG64 Id;
+} DEBUG_MODULE_AND_ID, *PDEBUG_MODULE_AND_ID;
+
+#define DEBUG_SOURCE_IS_STATEMENT 0x00000001
+
+//
+// GetSourceEntriesByLine flags.
+//
+
+#define DEBUG_GSEL_DEFAULT         0x00000000
+// Do not allow any extra symbols to load during the search.
+#define DEBUG_GSEL_NO_SYMBOL_LOADS 0x00000001
+// Allow source hits with lower line numbers.
+#define DEBUG_GSEL_ALLOW_LOWER     0x00000002
+// Allow source hits with higher line numbers.
+#define DEBUG_GSEL_ALLOW_HIGHER    0x00000004
+// Only return the nearest hits.
+#define DEBUG_GSEL_NEAREST_ONLY    0x00000008
+// Only return caller sites of the inline function
+#define DEBUG_GSEL_INLINE_CALLSITE 0x00000010
+
+typedef struct _DEBUG_SYMBOL_SOURCE_ENTRY
+{
+    ULONG64 ModuleBase;
+    ULONG64 Offset;
+    ULONG64 FileNameId;
+    ULONG64 EngineInternal;
+    ULONG Size;
+    ULONG Flags;
+    ULONG FileNameSize;
+    // Line numbers are one-based.
+    // May be DEBUG_ANY_ID if unknown.
+    ULONG StartLine;
+    ULONG EndLine;
+    // Column numbers are one-based byte indices.
+    // May be DEBUG_ANY_ID if unknown.
+    ULONG StartColumn;
+    ULONG EndColumn;
+    ULONG Reserved;
+} DEBUG_SYMBOL_SOURCE_ENTRY, *PDEBUG_SYMBOL_SOURCE_ENTRY;
+
+#undef INTERFACE
+#define INTERFACE IDebugSymbols3
+DECLARE_INTERFACE_(IDebugSymbols3, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSymbols.
+
+    // Controls the symbol options used during
+    // symbol operations.
+    // Uses the same flags as dbghelps SymSetOptions.
+    STDMETHOD(GetSymbolOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    STDMETHOD(GetNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    // A symbol name may not be unique, particularly
+    // when overloaded functions exist which all
+    // have the same name.  If GetOffsetByName
+    // finds multiple matches for the name it
+    // can return any one of them.  In that
+    // case it will return S_FALSE to indicate
+    // that ambiguity was arbitrarily resolved.
+    // A caller can then use SearchSymbols to
+    // find all of the matches if it wishes to
+    // perform different disambiguation.
+    STDMETHOD(GetOffsetByName)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // GetNearNameByOffset returns symbols
+    // located near the symbol closest to
+    // to the offset, such as the previous
+    // or next symbol.  If Delta is zero it
+    // operates identically to GetNameByOffset.
+    // If Delta is nonzero and such a symbol
+    // does not exist an error is returned.
+    // The next symbol, if one exists, will
+    // always have a higher offset than the
+    // input offset so the displacement is
+    // always negative.  The situation is
+    // reversed for the previous symbol.
+    STDMETHOD(GetNearNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByLine)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCSTR File,
+        _Out_ PULONG64 Offset
+        ) PURE;
+
+    // Enumerates the engines list of modules
+    // loaded for the current process.  This may
+    // or may not match the system module list
+    // for the process.  Reload can be used to
+    // synchronize the engines list with the system
+    // if necessary.
+    // Some sessions also track recently unloaded
+    // code modules for help in analyzing failures
+    // where an attempt is made to call unloaded code.
+    // These modules are indexed after the loaded
+    // modules.
+    STDMETHOD(GetNumberModules)(
+        THIS_
+        _Out_ PULONG Loaded,
+        _Out_ PULONG Unloaded
+        ) PURE;
+    STDMETHOD(GetModuleByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PULONG64 Base
+        ) PURE;
+    // The module name may not be unique.
+    // This method returns the first match.
+    STDMETHOD(GetModuleByModuleName)(
+        THIS_
+        _In_ PCSTR Name,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // Offset can be any offset within
+    // the module extent.  Extents may
+    // not be unique when including unloaded
+    // drivers.  This method returns the
+    // first match.
+    STDMETHOD(GetModuleByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    STDMETHOD(GetModuleNames)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(ImageNameBufferSize) PSTR ImageNameBuffer,
+        _In_ ULONG ImageNameBufferSize,
+        _Out_opt_ PULONG ImageNameSize,
+        _Out_writes_opt_(ModuleNameBufferSize) PSTR ModuleNameBuffer,
+        _In_ ULONG ModuleNameBufferSize,
+        _Out_opt_ PULONG ModuleNameSize,
+        _Out_writes_opt_(LoadedImageNameBufferSize) PSTR LoadedImageNameBuffer,
+        _In_ ULONG LoadedImageNameBufferSize,
+        _Out_opt_ PULONG LoadedImageNameSize
+        ) PURE;
+    STDMETHOD(GetModuleParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG64 Bases,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_MODULE_PARAMETERS Params
+        ) PURE;
+    // Looks up the module from a <Module>!<Symbol>
+    // string.
+    STDMETHOD(GetSymbolModule)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Base
+        ) PURE;
+
+    // Returns the string name of a type.
+    STDMETHOD(GetTypeName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    // Returns the ID for a type name.
+    STDMETHOD(GetTypeId)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ PCSTR Name,
+        _Out_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetTypeSize)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_ PULONG Size
+        ) PURE;
+    // Given a type which can contain members
+    // this method returns the offset of a
+    // particular member within the type.
+    // TypeId should give the container type ID
+    // and Field gives the dot-separated path
+    // to the field of interest.
+    STDMETHOD(GetFieldOffset)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ PCSTR Field,
+        _Out_ PULONG Offset
+        ) PURE;
+
+    STDMETHOD(GetSymbolTypeId)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+    // As with GetOffsetByName a symbol's
+    // name may be ambiguous.  GetOffsetTypeId
+    // returns the type for the symbol closest
+    // to the given offset and can be used
+    // to avoid ambiguity.
+    STDMETHOD(GetOffsetTypeId)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+
+    // Helpers for virtual and physical data
+    // which combine creation of a location with
+    // the actual operation.
+    STDMETHOD(ReadTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataVirtual)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(ReadTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataPhysical)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Function arguments and scope block symbols
+    // can be retrieved relative to currently
+    // executing code.  A caller can provide just
+    // a code offset for scoping purposes and look
+    // up names or the caller can provide a full frame
+    // and look up actual values.  The values for
+    // scoped symbols are best-guess and may or may not
+    // be accurate depending on program optimizations,
+    // the machine architecture, the current point
+    // in the programs execution and so on.
+    // A caller can also provide a complete register
+    // context for setting a scope to a previous
+    // machine state such as a context saved for
+    // an exception.  Usually this isnt necessary
+    // and the current register context is used.
+    STDMETHOD(GetScope)(
+        THIS_
+        _Out_opt_ PULONG64 InstructionOffset,
+        _Out_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _Out_writes_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // If ScopeFrame or ScopeContext is non-NULL then
+    // InstructionOffset is ignored.
+    // If ScopeContext is NULL the current
+    // register context is used.
+    // If the scope identified by the given
+    // information is the same as before
+    // SetScope returns S_OK.  If the scope
+    // information changes, such as when the
+    // scope moves between functions or scope
+    // blocks, SetScope returns S_FALSE.
+    STDMETHOD(SetScope)(
+        THIS_
+        _In_ ULONG64 InstructionOffset,
+        _In_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _In_reads_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // ResetScope clears the scope information
+    // for situations where scoped symbols
+    // mask global symbols or when resetting
+    // from explicit information to the current
+    // information.
+    STDMETHOD(ResetScope)(
+        THIS
+        ) PURE;
+    // A scope symbol is tied to its particular
+    // scope and only is meaningful within the scope.
+    // The returned group can be updated by passing it back
+    // into the method for lower-cost
+    // incremental updates when stepping.
+    STDMETHOD(GetScopeSymbolGroup)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PDEBUG_SYMBOL_GROUP Update,
+        _Out_ PDEBUG_SYMBOL_GROUP* Symbols
+        ) PURE;
+
+    // Create a new symbol group.
+    STDMETHOD(CreateSymbolGroup)(
+        THIS_
+        _Out_ PDEBUG_SYMBOL_GROUP* Group
+        ) PURE;
+
+    // StartSymbolMatch matches symbol names
+    // against the given pattern using simple
+    // regular expressions.  The search results
+    // are iterated through using GetNextSymbolMatch.
+    // When the caller is done examining results
+    // the match should be freed via EndSymbolMatch.
+    // If the match pattern contains a module name
+    // the search is restricted to a single module.
+    // Pattern matching is only done on symbol names,
+    // not module names.
+    // All active symbol match handles are invalidated
+    // when the set of loaded symbols changes.
+    STDMETHOD(StartSymbolMatch)(
+        THIS_
+        _In_ PCSTR Pattern,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Buffer is NULL the match does not
+    // advance.
+    STDMETHOD(GetNextSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MatchSize,
+        _Out_opt_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(EndSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Reload)(
+        THIS_
+        _In_ PCSTR Module
+        ) PURE;
+
+    STDMETHOD(GetSymbolPath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetSymbolPath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSymbolPath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Manipulate the path for executable images.
+    // Some dump files need to load executable images
+    // in order to resolve dump information.  This
+    // path controls where the engine looks for
+    // images.
+    STDMETHOD(GetImagePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetImagePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendImagePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Path routines for source file location
+    // methods.
+    STDMETHOD(GetSourcePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    // Gets the nth part of the source path.
+    STDMETHOD(GetSourcePathElement)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ElementSize
+        ) PURE;
+    STDMETHOD(SetSourcePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSourcePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+    // Uses the given file path and the source path
+    // information to try and locate an existing file.
+    // The given file path is merged with elements
+    // of the source path and checked for existence.
+    // If a match is found the element used is returned.
+    // A starting element can be specified to restrict
+    // the search to a subset of the path elements;
+    // this can be useful when checking for multiple
+    // matches along the source path.
+    // The returned element can be 1, indicating
+    // the file was found directly and not on the path.
+    STDMETHOD(FindSourceFile)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+    // Retrieves all the line offset information
+    // for a particular source file.  Buffer is
+    // first intialized to DEBUG_INVALID_OFFSET for
+    // every entry.  Then for each piece of line
+    // symbol information Buffer[Line] set to
+    // Lines offset.  This produces a per-line
+    // map of the offsets for the lines of the
+    // given file.  Line numbers are decremented
+    // for the map so Buffer[0] contains the offset
+    // for line number 1.
+    // If there is no line information at all for
+    // the given file the method fails rather
+    // than returning a map of invalid offsets.
+    STDMETHOD(GetSourceFileLineOffsets)(
+        THIS_
+        _In_ PCSTR File,
+        _Out_writes_opt_(BufferLines) PULONG64 Buffer,
+        _In_ ULONG BufferLines,
+        _Out_opt_ PULONG FileLines
+        ) PURE;
+
+    // IDebugSymbols2.
+
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    // Item is specified as in VerQueryValue.
+    // Module version information is only
+    // available for loaded modules and may
+    // not be available in all debug sessions.
+    STDMETHOD(GetModuleVersionInformation)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _In_ PCSTR Item,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG VerInfoSize
+        ) PURE;
+    // Retrieves any available module name string
+    // such as module name or symbol file name.
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    // If symbols are deferred an error will
+    // be returned.
+    // E_NOINTERFACE may be returned, indicating
+    // no information exists.
+    STDMETHOD(GetModuleNameString)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Returns the string name of a constant type.
+    STDMETHOD(GetConstantName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG64 Value,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Gets name of a field in a struct
+    // FieldNumber is 0 based index of field in a struct
+    STDMETHOD(GetFieldName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG FieldIndex,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Control options for typed values.
+    STDMETHOD(GetTypeOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // IDebugSymbols3.
+
+    STDMETHOD(GetNameByOffsetWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByNameWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetNearNameByOffsetWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByOffsetWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PWSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByLineWide)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCWSTR File,
+        _Out_ PULONG64 Offset
+        ) PURE;
+
+    STDMETHOD(GetModuleByModuleNameWide)(
+        THIS_
+        _In_ PCWSTR Name,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    STDMETHOD(GetSymbolModuleWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _Out_ PULONG64 Base
+        ) PURE;
+
+    STDMETHOD(GetTypeNameWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    // Returns the ID for a type name.
+    STDMETHOD(GetTypeIdWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ PCWSTR Name,
+        _Out_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetFieldOffsetWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ PCWSTR Field,
+        _Out_ PULONG Offset
+        ) PURE;
+
+    STDMETHOD(GetSymbolTypeIdWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+
+    STDMETHOD(GetScopeSymbolGroup2)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PDEBUG_SYMBOL_GROUP2 Update,
+        _Out_ PDEBUG_SYMBOL_GROUP2* Symbols
+        ) PURE;
+
+    STDMETHOD(CreateSymbolGroup2)(
+        THIS_
+        _Out_ PDEBUG_SYMBOL_GROUP2* Group
+        ) PURE;
+
+    STDMETHOD(StartSymbolMatchWide)(
+        THIS_
+        _In_ PCWSTR Pattern,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetNextSymbolMatchWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MatchSize,
+        _Out_opt_ PULONG64 Offset
+        ) PURE;
+
+    STDMETHOD(ReloadWide)(
+        THIS_
+        _In_ PCWSTR Module
+        ) PURE;
+
+    STDMETHOD(GetSymbolPathWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetSymbolPathWide)(
+        THIS_
+        _In_ PCWSTR Path
+        ) PURE;
+    STDMETHOD(AppendSymbolPathWide)(
+        THIS_
+        _In_ PCWSTR Addition
+        ) PURE;
+
+    STDMETHOD(GetImagePathWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetImagePathWide)(
+        THIS_
+        _In_ PCWSTR Path
+        ) PURE;
+    STDMETHOD(AppendImagePathWide)(
+        THIS_
+        _In_ PCWSTR Addition
+        ) PURE;
+
+    STDMETHOD(GetSourcePathWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(GetSourcePathElementWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ElementSize
+        ) PURE;
+    STDMETHOD(SetSourcePathWide)(
+        THIS_
+        _In_ PCWSTR Path
+        ) PURE;
+    STDMETHOD(AppendSourcePathWide)(
+        THIS_
+        _In_ PCWSTR Addition
+        ) PURE;
+    STDMETHOD(FindSourceFileWide)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ PCWSTR File,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+    STDMETHOD(GetSourceFileLineOffsetsWide)(
+        THIS_
+        _In_ PCWSTR File,
+        _Out_writes_opt_(BufferLines) PULONG64 Buffer,
+        _In_ ULONG BufferLines,
+        _Out_opt_ PULONG FileLines
+        ) PURE;
+
+    STDMETHOD(GetModuleVersionInformationWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _In_ PCWSTR Item,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG VerInfoSize
+        ) PURE;
+    STDMETHOD(GetModuleNameStringWide)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    STDMETHOD(GetConstantNameWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG64 Value,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    STDMETHOD(GetFieldNameWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG FieldIndex,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Returns S_OK if the engine is using managed
+    // debugging support when retriving information
+    // for the given module.  This can be expensive
+    // to check.
+    STDMETHOD(IsManagedModule)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base
+        ) PURE;
+
+    // The module name may not be unique.
+    // This method returns the first match.
+    STDMETHOD(GetModuleByModuleName2)(
+        THIS_
+        _In_ PCSTR Name,
+        _In_ ULONG StartIndex,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    STDMETHOD(GetModuleByModuleName2Wide)(
+        THIS_
+        _In_ PCWSTR Name,
+        _In_ ULONG StartIndex,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // Offset can be any offset within
+    // the module extent.  Extents may
+    // not be unique when including unloaded
+    // drivers.  This method returns the
+    // first match.
+    STDMETHOD(GetModuleByOffset2)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG StartIndex,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+
+    // A caller can create artificial loaded modules in
+    // the engine's module list if desired.
+    // These modules only serve as names for
+    // a region of addresses.  They cannot have
+    // real symbols loaded for them; if that
+    // is desired Reload can be used with explicit
+    // parameters to create a true module entry.
+    // The region must not be in use by any other
+    // module.
+    // A general reload will discard any synthetic modules.
+    STDMETHOD(AddSyntheticModule)(
+        THIS_
+        _In_ ULONG64 Base,
+        _In_ ULONG Size,
+        _In_ PCSTR ImagePath,
+        _In_ PCSTR ModuleName,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(AddSyntheticModuleWide)(
+        THIS_
+        _In_ ULONG64 Base,
+        _In_ ULONG Size,
+        _In_ PCWSTR ImagePath,
+        _In_ PCWSTR ModuleName,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(RemoveSyntheticModule)(
+        THIS_
+        _In_ ULONG64 Base
+        ) PURE;
+
+    // Modify the current frame used for scoping.
+    // This is equivalent to the '.frame' command.
+    STDMETHOD(GetCurrentScopeFrameIndex)(
+        THIS_
+        _Out_ PULONG Index
+        ) PURE;
+    STDMETHOD(SetScopeFrameByIndex)(
+        THIS_
+        _In_ ULONG Index
+        ) PURE;
+
+    // Recovers JIT_DEBUG_INFO information at the given
+    // address from the debuggee and sets current
+    // debugger scope context from it.
+    // Equivalent to '.jdinfo' command.
+    STDMETHOD(SetScopeFromJitDebugInfo)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 InfoOffset
+        ) PURE;
+
+    // Switches the current debugger scope to
+    // the stored event information.
+    // Equivalent to the '.ecxr' command.
+    STDMETHOD(SetScopeFromStoredEvent)(
+        THIS
+        ) PURE;
+
+    // Takes the first symbol hit and outputs it.
+    // Controlled with DEBUG_OUTSYM_* flags.
+    STDMETHOD(OutputSymbolByOffset)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ ULONG64 Offset
+        ) PURE;
+
+    // Function entry information for a particular
+    // piece of code can be retrieved by this method.
+    // The actual data returned is system-dependent.
+    STDMETHOD(GetFunctionEntryByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BufferNeeded
+        ) PURE;
+
+    // Given a type which can contain members
+    // this method returns the type ID and offset of a
+    // particular member within the type.
+    // Field gives the dot-separated path
+    // to the field of interest.
+    STDMETHOD(GetFieldTypeAndOffset)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG ContainerTypeId,
+        _In_ PCSTR Field,
+        _Out_opt_ PULONG FieldTypeId,
+        _Out_opt_ PULONG Offset
+        ) PURE;
+    STDMETHOD(GetFieldTypeAndOffsetWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG ContainerTypeId,
+        _In_ PCWSTR Field,
+        _Out_opt_ PULONG FieldTypeId,
+        _Out_opt_ PULONG Offset
+        ) PURE;
+
+    // Artificial symbols can be created in any
+    // existing module as a way to name an address.
+    // The address must not already have symbol
+    // information.
+    // A reload will discard synthetic symbols
+    // for all address regions reloaded.
+    STDMETHOD(AddSyntheticSymbol)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Size,
+        _In_ PCSTR Name,
+        _In_ ULONG Flags,
+        _Out_opt_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+    STDMETHOD(AddSyntheticSymbolWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Size,
+        _In_ PCWSTR Name,
+        _In_ ULONG Flags,
+        _Out_opt_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+    STDMETHOD(RemoveSyntheticSymbol)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+
+    // The following methods can return multiple
+    // hits for symbol lookups to allow for all
+    // possible hits to be returned.
+    STDMETHOD(GetSymbolEntriesByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(IdsCount) PDEBUG_MODULE_AND_ID Ids,
+        _Out_writes_opt_(IdsCount) PULONG64 Displacements,
+        _In_ ULONG IdsCount,
+        _Out_opt_ PULONG Entries
+        ) PURE;
+    STDMETHOD(GetSymbolEntriesByName)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(IdsCount) PDEBUG_MODULE_AND_ID Ids,
+        _In_ ULONG IdsCount,
+        _Out_opt_ PULONG Entries
+        ) PURE;
+    STDMETHOD(GetSymbolEntriesByNameWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(IdsCount) PDEBUG_MODULE_AND_ID Ids,
+        _In_ ULONG IdsCount,
+        _Out_opt_ PULONG Entries
+        ) PURE;
+    // Symbol lookup by managed metadata token.
+    STDMETHOD(GetSymbolEntryByToken)(
+        THIS_
+        _In_ ULONG64 ModuleBase,
+        _In_ ULONG Token,
+        _Out_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+
+    // Retrieves full symbol entry information from an ID.
+    STDMETHOD(GetSymbolEntryInformation)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _Out_ PDEBUG_SYMBOL_ENTRY Info
+        ) PURE;
+    STDMETHOD(GetSymbolEntryString)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSymbolEntryStringWide)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    // Returns all known memory regions associated
+    // with the given symbol.  Simple symbols will
+    // have a single region starting from their base.
+    // More complicated regions, such as functions
+    // with multiple code areas, can have an arbitrarily
+    // large number of regions.
+    // The quality of information returned is highly
+    // dependent on the symbolic information availble.
+    STDMETHOD(GetSymbolEntryOffsetRegions)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(RegionsCount) PDEBUG_OFFSET_REGION Regions,
+        _In_ ULONG RegionsCount,
+        _Out_opt_ PULONG RegionsAvail
+        ) PURE;
+
+    // This method allows navigating within the
+    // symbol entry hierarchy.
+    STDMETHOD(GetSymbolEntryBySymbolEntry)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID FromId,
+        _In_ ULONG Flags,
+        _Out_ PDEBUG_MODULE_AND_ID ToId
+        ) PURE;
+
+    // The following methods can return multiple
+    // hits for source lookups to allow for all
+    // possible hits to be returned.
+    STDMETHOD(GetSourceEntriesByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
+        _In_ ULONG EntriesCount,
+        _Out_opt_ PULONG EntriesAvail
+        ) PURE;
+    STDMETHOD(GetSourceEntriesByLine)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
+        _In_ ULONG EntriesCount,
+        _Out_opt_ PULONG EntriesAvail
+        ) PURE;
+    STDMETHOD(GetSourceEntriesByLineWide)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCWSTR File,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
+        _In_ ULONG EntriesCount,
+        _Out_opt_ PULONG EntriesAvail
+        ) PURE;
+
+    STDMETHOD(GetSourceEntryString)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSourceEntryStringWide)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    // Returns all known memory regions associated
+    // with the given source entry.  As with
+    // GetSymbolEntryOffsetRegions the regions available
+    // are variable.
+    STDMETHOD(GetSourceEntryOffsetRegions)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(RegionsCount) PDEBUG_OFFSET_REGION Regions,
+        _In_ ULONG RegionsCount,
+        _Out_opt_ PULONG RegionsAvail
+        ) PURE;
+
+    // This method allows navigating within the
+    // source entries.
+    STDMETHOD(GetSourceEntryBySourceEntry)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY FromEntry,
+        _In_ ULONG Flags,
+        _Out_ PDEBUG_SYMBOL_SOURCE_ENTRY ToEntry
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugSymbols4
+DECLARE_INTERFACE_(IDebugSymbols4, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSymbols.
+
+    // Controls the symbol options used during
+    // symbol operations.
+    // Uses the same flags as dbghelps SymSetOptions.
+    STDMETHOD(GetSymbolOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    STDMETHOD(GetNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    // A symbol name may not be unique, particularly
+    // when overloaded functions exist which all
+    // have the same name.  If GetOffsetByName
+    // finds multiple matches for the name it
+    // can return any one of them.  In that
+    // case it will return S_FALSE to indicate
+    // that ambiguity was arbitrarily resolved.
+    // A caller can then use SearchSymbols to
+    // find all of the matches if it wishes to
+    // perform different disambiguation.
+    STDMETHOD(GetOffsetByName)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // GetNearNameByOffset returns symbols
+    // located near the symbol closest to
+    // to the offset, such as the previous
+    // or next symbol.  If Delta is zero it
+    // operates identically to GetNameByOffset.
+    // If Delta is nonzero and such a symbol
+    // does not exist an error is returned.
+    // The next symbol, if one exists, will
+    // always have a higher offset than the
+    // input offset so the displacement is
+    // always negative.  The situation is
+    // reversed for the previous symbol.
+    STDMETHOD(GetNearNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByLine)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCSTR File,
+        _Out_ PULONG64 Offset
+        ) PURE;
+
+    // Enumerates the engines list of modules
+    // loaded for the current process.  This may
+    // or may not match the system module list
+    // for the process.  Reload can be used to
+    // synchronize the engines list with the system
+    // if necessary.
+    // Some sessions also track recently unloaded
+    // code modules for help in analyzing failures
+    // where an attempt is made to call unloaded code.
+    // These modules are indexed after the loaded
+    // modules.
+    STDMETHOD(GetNumberModules)(
+        THIS_
+        _Out_ PULONG Loaded,
+        _Out_ PULONG Unloaded
+        ) PURE;
+    STDMETHOD(GetModuleByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PULONG64 Base
+        ) PURE;
+    // The module name may not be unique.
+    // This method returns the first match.
+    STDMETHOD(GetModuleByModuleName)(
+        THIS_
+        _In_ PCSTR Name,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // Offset can be any offset within
+    // the module extent.  Extents may
+    // not be unique when including unloaded
+    // drivers.  This method returns the
+    // first match.
+    STDMETHOD(GetModuleByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    STDMETHOD(GetModuleNames)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(ImageNameBufferSize) PSTR ImageNameBuffer,
+        _In_ ULONG ImageNameBufferSize,
+        _Out_opt_ PULONG ImageNameSize,
+        _Out_writes_opt_(ModuleNameBufferSize) PSTR ModuleNameBuffer,
+        _In_ ULONG ModuleNameBufferSize,
+        _Out_opt_ PULONG ModuleNameSize,
+        _Out_writes_opt_(LoadedImageNameBufferSize) PSTR LoadedImageNameBuffer,
+        _In_ ULONG LoadedImageNameBufferSize,
+        _Out_opt_ PULONG LoadedImageNameSize
+        ) PURE;
+    STDMETHOD(GetModuleParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG64 Bases,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_MODULE_PARAMETERS Params
+        ) PURE;
+    // Looks up the module from a <Module>!<Symbol>
+    // string.
+    STDMETHOD(GetSymbolModule)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Base
+        ) PURE;
+
+    // Returns the string name of a type.
+    STDMETHOD(GetTypeName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    // Returns the ID for a type name.
+    STDMETHOD(GetTypeId)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ PCSTR Name,
+        _Out_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetTypeSize)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_ PULONG Size
+        ) PURE;
+    // Given a type which can contain members
+    // this method returns the offset of a
+    // particular member within the type.
+    // TypeId should give the container type ID
+    // and Field gives the dot-separated path
+    // to the field of interest.
+    STDMETHOD(GetFieldOffset)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ PCSTR Field,
+        _Out_ PULONG Offset
+        ) PURE;
+
+    STDMETHOD(GetSymbolTypeId)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+    // As with GetOffsetByName a symbol's
+    // name may be ambiguous.  GetOffsetTypeId
+    // returns the type for the symbol closest
+    // to the given offset and can be used
+    // to avoid ambiguity.
+    STDMETHOD(GetOffsetTypeId)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+
+    // Helpers for virtual and physical data
+    // which combine creation of a location with
+    // the actual operation.
+    STDMETHOD(ReadTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataVirtual)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(ReadTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataPhysical)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Function arguments and scope block symbols
+    // can be retrieved relative to currently
+    // executing code.  A caller can provide just
+    // a code offset for scoping purposes and look
+    // up names or the caller can provide a full frame
+    // and look up actual values.  The values for
+    // scoped symbols are best-guess and may or may not
+    // be accurate depending on program optimizations,
+    // the machine architecture, the current point
+    // in the programs execution and so on.
+    // A caller can also provide a complete register
+    // context for setting a scope to a previous
+    // machine state such as a context saved for
+    // an exception.  Usually this isnt necessary
+    // and the current register context is used.
+    STDMETHOD(GetScope)(
+        THIS_
+        _Out_opt_ PULONG64 InstructionOffset,
+        _Out_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _Out_writes_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // If ScopeFrame or ScopeContext is non-NULL then
+    // InstructionOffset is ignored.
+    // If ScopeContext is NULL the current
+    // register context is used.
+    // If the scope identified by the given
+    // information is the same as before
+    // SetScope returns S_OK.  If the scope
+    // information changes, such as when the
+    // scope moves between functions or scope
+    // blocks, SetScope returns S_FALSE.
+    STDMETHOD(SetScope)(
+        THIS_
+        _In_ ULONG64 InstructionOffset,
+        _In_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _In_reads_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // ResetScope clears the scope information
+    // for situations where scoped symbols
+    // mask global symbols or when resetting
+    // from explicit information to the current
+    // information.
+    STDMETHOD(ResetScope)(
+        THIS
+        ) PURE;
+    // A scope symbol is tied to its particular
+    // scope and only is meaningful within the scope.
+    // The returned group can be updated by passing it back
+    // into the method for lower-cost
+    // incremental updates when stepping.
+    STDMETHOD(GetScopeSymbolGroup)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PDEBUG_SYMBOL_GROUP Update,
+        _Out_ PDEBUG_SYMBOL_GROUP* Symbols
+        ) PURE;
+
+    // Create a new symbol group.
+    STDMETHOD(CreateSymbolGroup)(
+        THIS_
+        _Out_ PDEBUG_SYMBOL_GROUP* Group
+        ) PURE;
+
+    // StartSymbolMatch matches symbol names
+    // against the given pattern using simple
+    // regular expressions.  The search results
+    // are iterated through using GetNextSymbolMatch.
+    // When the caller is done examining results
+    // the match should be freed via EndSymbolMatch.
+    // If the match pattern contains a module name
+    // the search is restricted to a single module.
+    // Pattern matching is only done on symbol names,
+    // not module names.
+    // All active symbol match handles are invalidated
+    // when the set of loaded symbols changes.
+    STDMETHOD(StartSymbolMatch)(
+        THIS_
+        _In_ PCSTR Pattern,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Buffer is NULL the match does not
+    // advance.
+    STDMETHOD(GetNextSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MatchSize,
+        _Out_opt_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(EndSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Reload)(
+        THIS_
+        _In_ PCSTR Module
+        ) PURE;
+
+    STDMETHOD(GetSymbolPath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetSymbolPath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSymbolPath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Manipulate the path for executable images.
+    // Some dump files need to load executable images
+    // in order to resolve dump information.  This
+    // path controls where the engine looks for
+    // images.
+    STDMETHOD(GetImagePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetImagePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendImagePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Path routines for source file location
+    // methods.
+    STDMETHOD(GetSourcePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    // Gets the nth part of the source path.
+    STDMETHOD(GetSourcePathElement)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ElementSize
+        ) PURE;
+    STDMETHOD(SetSourcePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSourcePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+    // Uses the given file path and the source path
+    // information to try and locate an existing file.
+    // The given file path is merged with elements
+    // of the source path and checked for existence.
+    // If a match is found the element used is returned.
+    // A starting element can be specified to restrict
+    // the search to a subset of the path elements;
+    // this can be useful when checking for multiple
+    // matches along the source path.
+    // The returned element can be 1, indicating
+    // the file was found directly and not on the path.
+    STDMETHOD(FindSourceFile)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+    // Retrieves all the line offset information
+    // for a particular source file.  Buffer is
+    // first intialized to DEBUG_INVALID_OFFSET for
+    // every entry.  Then for each piece of line
+    // symbol information Buffer[Line] set to
+    // Lines offset.  This produces a per-line
+    // map of the offsets for the lines of the
+    // given file.  Line numbers are decremented
+    // for the map so Buffer[0] contains the offset
+    // for line number 1.
+    // If there is no line information at all for
+    // the given file the method fails rather
+    // than returning a map of invalid offsets.
+    STDMETHOD(GetSourceFileLineOffsets)(
+        THIS_
+        _In_ PCSTR File,
+        _Out_writes_opt_(BufferLines) PULONG64 Buffer,
+        _In_ ULONG BufferLines,
+        _Out_opt_ PULONG FileLines
+        ) PURE;
+
+    // IDebugSymbols2.
+
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    // Item is specified as in VerQueryValue.
+    // Module version information is only
+    // available for loaded modules and may
+    // not be available in all debug sessions.
+    STDMETHOD(GetModuleVersionInformation)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _In_ PCSTR Item,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG VerInfoSize
+        ) PURE;
+    // Retrieves any available module name string
+    // such as module name or symbol file name.
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    // If symbols are deferred an error will
+    // be returned.
+    // E_NOINTERFACE may be returned, indicating
+    // no information exists.
+    STDMETHOD(GetModuleNameString)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Returns the string name of a constant type.
+    STDMETHOD(GetConstantName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG64 Value,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Gets name of a field in a struct
+    // FieldNumber is 0 based index of field in a struct
+    STDMETHOD(GetFieldName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG FieldIndex,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Control options for typed values.
+    STDMETHOD(GetTypeOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // IDebugSymbols3.
+
+    STDMETHOD(GetNameByOffsetWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByNameWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetNearNameByOffsetWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByOffsetWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PWSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByLineWide)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCWSTR File,
+        _Out_ PULONG64 Offset
+        ) PURE;
+
+    STDMETHOD(GetModuleByModuleNameWide)(
+        THIS_
+        _In_ PCWSTR Name,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    STDMETHOD(GetSymbolModuleWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _Out_ PULONG64 Base
+        ) PURE;
+
+    STDMETHOD(GetTypeNameWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    // Returns the ID for a type name.
+    STDMETHOD(GetTypeIdWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ PCWSTR Name,
+        _Out_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetFieldOffsetWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ PCWSTR Field,
+        _Out_ PULONG Offset
+        ) PURE;
+
+    STDMETHOD(GetSymbolTypeIdWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+
+    STDMETHOD(GetScopeSymbolGroup2)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PDEBUG_SYMBOL_GROUP2 Update,
+        _Out_ PDEBUG_SYMBOL_GROUP2* Symbols
+        ) PURE;
+
+    STDMETHOD(CreateSymbolGroup2)(
+        THIS_
+        _Out_ PDEBUG_SYMBOL_GROUP2* Group
+        ) PURE;
+
+    STDMETHOD(StartSymbolMatchWide)(
+        THIS_
+        _In_ PCWSTR Pattern,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetNextSymbolMatchWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MatchSize,
+        _Out_opt_ PULONG64 Offset
+        ) PURE;
+
+    STDMETHOD(ReloadWide)(
+        THIS_
+        _In_ PCWSTR Module
+        ) PURE;
+
+    STDMETHOD(GetSymbolPathWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetSymbolPathWide)(
+        THIS_
+        _In_ PCWSTR Path
+        ) PURE;
+    STDMETHOD(AppendSymbolPathWide)(
+        THIS_
+        _In_ PCWSTR Addition
+        ) PURE;
+
+    STDMETHOD(GetImagePathWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetImagePathWide)(
+        THIS_
+        _In_ PCWSTR Path
+        ) PURE;
+    STDMETHOD(AppendImagePathWide)(
+        THIS_
+        _In_ PCWSTR Addition
+        ) PURE;
+
+    STDMETHOD(GetSourcePathWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(GetSourcePathElementWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ElementSize
+        ) PURE;
+    STDMETHOD(SetSourcePathWide)(
+        THIS_
+        _In_ PCWSTR Path
+        ) PURE;
+    STDMETHOD(AppendSourcePathWide)(
+        THIS_
+        _In_ PCWSTR Addition
+        ) PURE;
+    STDMETHOD(FindSourceFileWide)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ PCWSTR File,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+    STDMETHOD(GetSourceFileLineOffsetsWide)(
+        THIS_
+        _In_ PCWSTR File,
+        _Out_writes_opt_(BufferLines) PULONG64 Buffer,
+        _In_ ULONG BufferLines,
+        _Out_opt_ PULONG FileLines
+        ) PURE;
+
+    STDMETHOD(GetModuleVersionInformationWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _In_ PCWSTR Item,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG VerInfoSize
+        ) PURE;
+    STDMETHOD(GetModuleNameStringWide)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    STDMETHOD(GetConstantNameWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG64 Value,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    STDMETHOD(GetFieldNameWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG FieldIndex,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Returns S_OK if the engine is using managed
+    // debugging support when retriving information
+    // for the given module.  This can be expensive
+    // to check.
+    STDMETHOD(IsManagedModule)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base
+        ) PURE;
+
+    // The module name may not be unique.
+    // This method returns the first match.
+    STDMETHOD(GetModuleByModuleName2)(
+        THIS_
+        _In_ PCSTR Name,
+        _In_ ULONG StartIndex,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    STDMETHOD(GetModuleByModuleName2Wide)(
+        THIS_
+        _In_ PCWSTR Name,
+        _In_ ULONG StartIndex,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // Offset can be any offset within
+    // the module extent.  Extents may
+    // not be unique when including unloaded
+    // drivers.  This method returns the
+    // first match.
+    STDMETHOD(GetModuleByOffset2)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG StartIndex,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+
+    // A caller can create artificial loaded modules in
+    // the engine's module list if desired.
+    // These modules only serve as names for
+    // a region of addresses.  They cannot have
+    // real symbols loaded for them; if that
+    // is desired Reload can be used with explicit
+    // parameters to create a true module entry.
+    // The region must not be in use by any other
+    // module.
+    // A general reload will discard any synthetic modules.
+    STDMETHOD(AddSyntheticModule)(
+        THIS_
+        _In_ ULONG64 Base,
+        _In_ ULONG Size,
+        _In_ PCSTR ImagePath,
+        _In_ PCSTR ModuleName,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(AddSyntheticModuleWide)(
+        THIS_
+        _In_ ULONG64 Base,
+        _In_ ULONG Size,
+        _In_ PCWSTR ImagePath,
+        _In_ PCWSTR ModuleName,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(RemoveSyntheticModule)(
+        THIS_
+        _In_ ULONG64 Base
+        ) PURE;
+
+    // Modify the current frame used for scoping.
+    // This is equivalent to the '.frame' command.
+    STDMETHOD(GetCurrentScopeFrameIndex)(
+        THIS_
+        _Out_ PULONG Index
+        ) PURE;
+    STDMETHOD(SetScopeFrameByIndex)(
+        THIS_
+        _In_ ULONG Index
+        ) PURE;
+
+    // Recovers JIT_DEBUG_INFO information at the given
+    // address from the debuggee and sets current
+    // debugger scope context from it.
+    // Equivalent to '.jdinfo' command.
+    STDMETHOD(SetScopeFromJitDebugInfo)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 InfoOffset
+        ) PURE;
+
+    // Switches the current debugger scope to
+    // the stored event information.
+    // Equivalent to the '.ecxr' command.
+    STDMETHOD(SetScopeFromStoredEvent)(
+        THIS
+        ) PURE;
+
+    // Takes the first symbol hit and outputs it.
+    // Controlled with DEBUG_OUTSYM_* flags.
+    STDMETHOD(OutputSymbolByOffset)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ ULONG64 Offset
+        ) PURE;
+
+    // Function entry information for a particular
+    // piece of code can be retrieved by this method.
+    // The actual data returned is system-dependent.
+    STDMETHOD(GetFunctionEntryByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BufferNeeded
+        ) PURE;
+
+    // Given a type which can contain members
+    // this method returns the type ID and offset of a
+    // particular member within the type.
+    // Field gives the dot-separated path
+    // to the field of interest.
+    STDMETHOD(GetFieldTypeAndOffset)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG ContainerTypeId,
+        _In_ PCSTR Field,
+        _Out_opt_ PULONG FieldTypeId,
+        _Out_opt_ PULONG Offset
+        ) PURE;
+    STDMETHOD(GetFieldTypeAndOffsetWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG ContainerTypeId,
+        _In_ PCWSTR Field,
+        _Out_opt_ PULONG FieldTypeId,
+        _Out_opt_ PULONG Offset
+        ) PURE;
+
+    // Artificial symbols can be created in any
+    // existing module as a way to name an address.
+    // The address must not already have symbol
+    // information.
+    // A reload will discard synthetic symbols
+    // for all address regions reloaded.
+    STDMETHOD(AddSyntheticSymbol)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Size,
+        _In_ PCSTR Name,
+        _In_ ULONG Flags,
+        _Out_opt_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+    STDMETHOD(AddSyntheticSymbolWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Size,
+        _In_ PCWSTR Name,
+        _In_ ULONG Flags,
+        _Out_opt_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+    STDMETHOD(RemoveSyntheticSymbol)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+
+    // The following methods can return multiple
+    // hits for symbol lookups to allow for all
+    // possible hits to be returned.
+    STDMETHOD(GetSymbolEntriesByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(IdsCount) PDEBUG_MODULE_AND_ID Ids,
+        _Out_writes_opt_(IdsCount) PULONG64 Displacements,
+        _In_ ULONG IdsCount,
+        _Out_opt_ PULONG Entries
+        ) PURE;
+    STDMETHOD(GetSymbolEntriesByName)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(IdsCount) PDEBUG_MODULE_AND_ID Ids,
+        _In_ ULONG IdsCount,
+        _Out_opt_ PULONG Entries
+        ) PURE;
+    STDMETHOD(GetSymbolEntriesByNameWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(IdsCount) PDEBUG_MODULE_AND_ID Ids,
+        _In_ ULONG IdsCount,
+        _Out_opt_ PULONG Entries
+        ) PURE;
+    // Symbol lookup by managed metadata token.
+    STDMETHOD(GetSymbolEntryByToken)(
+        THIS_
+        _In_ ULONG64 ModuleBase,
+        _In_ ULONG Token,
+        _Out_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+
+    // Retrieves full symbol entry information from an ID.
+    STDMETHOD(GetSymbolEntryInformation)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _Out_ PDEBUG_SYMBOL_ENTRY Info
+        ) PURE;
+    STDMETHOD(GetSymbolEntryString)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSymbolEntryStringWide)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    // Returns all known memory regions associated
+    // with the given symbol.  Simple symbols will
+    // have a single region starting from their base.
+    // More complicated regions, such as functions
+    // with multiple code areas, can have an arbitrarily
+    // large number of regions.
+    // The quality of information returned is highly
+    // dependent on the symbolic information availble.
+    STDMETHOD(GetSymbolEntryOffsetRegions)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(RegionsCount) PDEBUG_OFFSET_REGION Regions,
+        _In_ ULONG RegionsCount,
+        _Out_opt_ PULONG RegionsAvail
+        ) PURE;
+
+    // This method allows navigating within the
+    // symbol entry hierarchy.
+    STDMETHOD(GetSymbolEntryBySymbolEntry)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID FromId,
+        _In_ ULONG Flags,
+        _Out_ PDEBUG_MODULE_AND_ID ToId
+        ) PURE;
+
+    // The following methods can return multiple
+    // hits for source lookups to allow for all
+    // possible hits to be returned.
+    STDMETHOD(GetSourceEntriesByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
+        _In_ ULONG EntriesCount,
+        _Out_opt_ PULONG EntriesAvail
+        ) PURE;
+    STDMETHOD(GetSourceEntriesByLine)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
+        _In_ ULONG EntriesCount,
+        _Out_opt_ PULONG EntriesAvail
+        ) PURE;
+    STDMETHOD(GetSourceEntriesByLineWide)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCWSTR File,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
+        _In_ ULONG EntriesCount,
+        _Out_opt_ PULONG EntriesAvail
+        ) PURE;
+
+    STDMETHOD(GetSourceEntryString)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSourceEntryStringWide)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    // Returns all known memory regions associated
+    // with the given source entry.  As with
+    // GetSymbolEntryOffsetRegions the regions available
+    // are variable.
+    STDMETHOD(GetSourceEntryOffsetRegions)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(RegionsCount) PDEBUG_OFFSET_REGION Regions,
+        _In_ ULONG RegionsCount,
+        _Out_opt_ PULONG RegionsAvail
+        ) PURE;
+
+    // This method allows navigating within the
+    // source entries.
+    STDMETHOD(GetSourceEntryBySourceEntry)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY FromEntry,
+        _In_ ULONG Flags,
+        _Out_ PDEBUG_SYMBOL_SOURCE_ENTRY ToEntry
+        ) PURE;
+
+    // IDebugSymbols4
+    STDMETHOD(GetScopeEx)(
+        THIS_
+        _Out_opt_ PULONG64 InstructionOffset,
+        _Out_opt_ PDEBUG_STACK_FRAME_EX ScopeFrame,
+        _Out_writes_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+
+    STDMETHOD(SetScopeEx)(
+        THIS_
+        _In_ ULONG64 InstructionOffset,
+        _In_opt_ PDEBUG_STACK_FRAME_EX ScopeFrame,
+        _In_reads_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+
+    STDMETHOD(GetNameByInlineContext)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetNameByInlineContextWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByInlineContext)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByInlineContextWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PWSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(OutputSymbolByInlineContext)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext
+        ) PURE;
+};
+
+#define DEBUG_FRAME_DEFAULT                0
+#define DEBUG_FRAME_IGNORE_INLINE 0x00000001
+
+#undef INTERFACE
+#define INTERFACE IDebugSymbols5
+DECLARE_INTERFACE_(IDebugSymbols5, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSymbols.
+
+    // Controls the symbol options used during
+    // symbol operations.
+    // Uses the same flags as dbghelps SymSetOptions.
+    STDMETHOD(GetSymbolOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetSymbolOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    STDMETHOD(GetNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    // A symbol name may not be unique, particularly
+    // when overloaded functions exist which all
+    // have the same name.  If GetOffsetByName
+    // finds multiple matches for the name it
+    // can return any one of them.  In that
+    // case it will return S_FALSE to indicate
+    // that ambiguity was arbitrarily resolved.
+    // A caller can then use SearchSymbols to
+    // find all of the matches if it wishes to
+    // perform different disambiguation.
+    STDMETHOD(GetOffsetByName)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // GetNearNameByOffset returns symbols
+    // located near the symbol closest to
+    // to the offset, such as the previous
+    // or next symbol.  If Delta is zero it
+    // operates identically to GetNameByOffset.
+    // If Delta is nonzero and such a symbol
+    // does not exist an error is returned.
+    // The next symbol, if one exists, will
+    // always have a higher offset than the
+    // input offset so the displacement is
+    // always negative.  The situation is
+    // reversed for the previous symbol.
+    STDMETHOD(GetNearNameByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByLine)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCSTR File,
+        _Out_ PULONG64 Offset
+        ) PURE;
+
+    // Enumerates the engines list of modules
+    // loaded for the current process.  This may
+    // or may not match the system module list
+    // for the process.  Reload can be used to
+    // synchronize the engines list with the system
+    // if necessary.
+    // Some sessions also track recently unloaded
+    // code modules for help in analyzing failures
+    // where an attempt is made to call unloaded code.
+    // These modules are indexed after the loaded
+    // modules.
+    STDMETHOD(GetNumberModules)(
+        THIS_
+        _Out_ PULONG Loaded,
+        _Out_ PULONG Unloaded
+        ) PURE;
+    STDMETHOD(GetModuleByIndex)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_ PULONG64 Base
+        ) PURE;
+    // The module name may not be unique.
+    // This method returns the first match.
+    STDMETHOD(GetModuleByModuleName)(
+        THIS_
+        _In_ PCSTR Name,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // Offset can be any offset within
+    // the module extent.  Extents may
+    // not be unique when including unloaded
+    // drivers.  This method returns the
+    // first match.
+    STDMETHOD(GetModuleByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    STDMETHOD(GetModuleNames)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(ImageNameBufferSize) PSTR ImageNameBuffer,
+        _In_ ULONG ImageNameBufferSize,
+        _Out_opt_ PULONG ImageNameSize,
+        _Out_writes_opt_(ModuleNameBufferSize) PSTR ModuleNameBuffer,
+        _In_ ULONG ModuleNameBufferSize,
+        _Out_opt_ PULONG ModuleNameSize,
+        _Out_writes_opt_(LoadedImageNameBufferSize) PSTR LoadedImageNameBuffer,
+        _In_ ULONG LoadedImageNameBufferSize,
+        _Out_opt_ PULONG LoadedImageNameSize
+        ) PURE;
+    STDMETHOD(GetModuleParameters)(
+        THIS_
+        _In_ ULONG Count,
+        _In_reads_opt_(Count) PULONG64 Bases,
+        _In_ ULONG Start,
+        _Out_writes_(Count) PDEBUG_MODULE_PARAMETERS Params
+        ) PURE;
+    // Looks up the module from a <Module>!<Symbol>
+    // string.
+    STDMETHOD(GetSymbolModule)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG64 Base
+        ) PURE;
+
+    // Returns the string name of a type.
+    STDMETHOD(GetTypeName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    // Returns the ID for a type name.
+    STDMETHOD(GetTypeId)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ PCSTR Name,
+        _Out_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetTypeSize)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_ PULONG Size
+        ) PURE;
+    // Given a type which can contain members
+    // this method returns the offset of a
+    // particular member within the type.
+    // TypeId should give the container type ID
+    // and Field gives the dot-separated path
+    // to the field of interest.
+    STDMETHOD(GetFieldOffset)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ PCSTR Field,
+        _Out_ PULONG Offset
+        ) PURE;
+
+    STDMETHOD(GetSymbolTypeId)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+    // As with GetOffsetByName a symbol's
+    // name may be ambiguous.  GetOffsetTypeId
+    // returns the type for the symbol closest
+    // to the given offset and can be used
+    // to avoid ambiguity.
+    STDMETHOD(GetOffsetTypeId)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+
+    // Helpers for virtual and physical data
+    // which combine creation of a location with
+    // the actual operation.
+    STDMETHOD(ReadTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataVirtual)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataVirtual)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(ReadTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesRead
+        ) PURE;
+    STDMETHOD(WriteTypedDataPhysical)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_reads_bytes_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BytesWritten
+        ) PURE;
+    STDMETHOD(OutputTypedDataPhysical)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 Offset,
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG Flags
+        ) PURE;
+
+    // Function arguments and scope block symbols
+    // can be retrieved relative to currently
+    // executing code.  A caller can provide just
+    // a code offset for scoping purposes and look
+    // up names or the caller can provide a full frame
+    // and look up actual values.  The values for
+    // scoped symbols are best-guess and may or may not
+    // be accurate depending on program optimizations,
+    // the machine architecture, the current point
+    // in the programs execution and so on.
+    // A caller can also provide a complete register
+    // context for setting a scope to a previous
+    // machine state such as a context saved for
+    // an exception.  Usually this isnt necessary
+    // and the current register context is used.
+    STDMETHOD(GetScope)(
+        THIS_
+        _Out_opt_ PULONG64 InstructionOffset,
+        _Out_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _Out_writes_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // If ScopeFrame or ScopeContext is non-NULL then
+    // InstructionOffset is ignored.
+    // If ScopeContext is NULL the current
+    // register context is used.
+    // If the scope identified by the given
+    // information is the same as before
+    // SetScope returns S_OK.  If the scope
+    // information changes, such as when the
+    // scope moves between functions or scope
+    // blocks, SetScope returns S_FALSE.
+    STDMETHOD(SetScope)(
+        THIS_
+        _In_ ULONG64 InstructionOffset,
+        _In_opt_ PDEBUG_STACK_FRAME ScopeFrame,
+        _In_reads_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+    // ResetScope clears the scope information
+    // for situations where scoped symbols
+    // mask global symbols or when resetting
+    // from explicit information to the current
+    // information.
+    STDMETHOD(ResetScope)(
+        THIS
+        ) PURE;
+    // A scope symbol is tied to its particular
+    // scope and only is meaningful within the scope.
+    // The returned group can be updated by passing it back
+    // into the method for lower-cost
+    // incremental updates when stepping.
+    STDMETHOD(GetScopeSymbolGroup)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PDEBUG_SYMBOL_GROUP Update,
+        _Out_ PDEBUG_SYMBOL_GROUP* Symbols
+        ) PURE;
+
+    // Create a new symbol group.
+    STDMETHOD(CreateSymbolGroup)(
+        THIS_
+        _Out_ PDEBUG_SYMBOL_GROUP* Group
+        ) PURE;
+
+    // StartSymbolMatch matches symbol names
+    // against the given pattern using simple
+    // regular expressions.  The search results
+    // are iterated through using GetNextSymbolMatch.
+    // When the caller is done examining results
+    // the match should be freed via EndSymbolMatch.
+    // If the match pattern contains a module name
+    // the search is restricted to a single module.
+    // Pattern matching is only done on symbol names,
+    // not module names.
+    // All active symbol match handles are invalidated
+    // when the set of loaded symbols changes.
+    STDMETHOD(StartSymbolMatch)(
+        THIS_
+        _In_ PCSTR Pattern,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // If Buffer is NULL the match does not
+    // advance.
+    STDMETHOD(GetNextSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MatchSize,
+        _Out_opt_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(EndSymbolMatch)(
+        THIS_
+        _In_ ULONG64 Handle
+        ) PURE;
+
+    STDMETHOD(Reload)(
+        THIS_
+        _In_ PCSTR Module
+        ) PURE;
+
+    STDMETHOD(GetSymbolPath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetSymbolPath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSymbolPath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Manipulate the path for executable images.
+    // Some dump files need to load executable images
+    // in order to resolve dump information.  This
+    // path controls where the engine looks for
+    // images.
+    STDMETHOD(GetImagePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetImagePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendImagePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+
+    // Path routines for source file location
+    // methods.
+    STDMETHOD(GetSourcePath)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    // Gets the nth part of the source path.
+    STDMETHOD(GetSourcePathElement)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ElementSize
+        ) PURE;
+    STDMETHOD(SetSourcePath)(
+        THIS_
+        _In_ PCSTR Path
+        ) PURE;
+    STDMETHOD(AppendSourcePath)(
+        THIS_
+        _In_ PCSTR Addition
+        ) PURE;
+    // Uses the given file path and the source path
+    // information to try and locate an existing file.
+    // The given file path is merged with elements
+    // of the source path and checked for existence.
+    // If a match is found the element used is returned.
+    // A starting element can be specified to restrict
+    // the search to a subset of the path elements;
+    // this can be useful when checking for multiple
+    // matches along the source path.
+    // The returned element can be 1, indicating
+    // the file was found directly and not on the path.
+    STDMETHOD(FindSourceFile)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+    // Retrieves all the line offset information
+    // for a particular source file.  Buffer is
+    // first intialized to DEBUG_INVALID_OFFSET for
+    // every entry.  Then for each piece of line
+    // symbol information Buffer[Line] set to
+    // Lines offset.  This produces a per-line
+    // map of the offsets for the lines of the
+    // given file.  Line numbers are decremented
+    // for the map so Buffer[0] contains the offset
+    // for line number 1.
+    // If there is no line information at all for
+    // the given file the method fails rather
+    // than returning a map of invalid offsets.
+    STDMETHOD(GetSourceFileLineOffsets)(
+        THIS_
+        _In_ PCSTR File,
+        _Out_writes_opt_(BufferLines) PULONG64 Buffer,
+        _In_ ULONG BufferLines,
+        _Out_opt_ PULONG FileLines
+        ) PURE;
+
+    // IDebugSymbols2.
+
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    // Item is specified as in VerQueryValue.
+    // Module version information is only
+    // available for loaded modules and may
+    // not be available in all debug sessions.
+    STDMETHOD(GetModuleVersionInformation)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _In_ PCSTR Item,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG VerInfoSize
+        ) PURE;
+    // Retrieves any available module name string
+    // such as module name or symbol file name.
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    // If symbols are deferred an error will
+    // be returned.
+    // E_NOINTERFACE may be returned, indicating
+    // no information exists.
+    STDMETHOD(GetModuleNameString)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Returns the string name of a constant type.
+    STDMETHOD(GetConstantName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG64 Value,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Gets name of a field in a struct
+    // FieldNumber is 0 based index of field in a struct
+    STDMETHOD(GetFieldName)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG FieldIndex,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Control options for typed values.
+    STDMETHOD(GetTypeOptions)(
+        THIS_
+        _Out_ PULONG Options
+        ) PURE;
+    STDMETHOD(AddTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(RemoveTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+    STDMETHOD(SetTypeOptions)(
+        THIS_
+        _In_ ULONG Options
+        ) PURE;
+
+    // IDebugSymbols3.
+
+    STDMETHOD(GetNameByOffsetWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByNameWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetNearNameByOffsetWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ LONG Delta,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByOffsetWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PWSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+    STDMETHOD(GetOffsetByLineWide)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCWSTR File,
+        _Out_ PULONG64 Offset
+        ) PURE;
+
+    STDMETHOD(GetModuleByModuleNameWide)(
+        THIS_
+        _In_ PCWSTR Name,
+        _In_ ULONG StartIndex,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    STDMETHOD(GetSymbolModuleWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _Out_ PULONG64 Base
+        ) PURE;
+
+    STDMETHOD(GetTypeNameWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+    // Returns the ID for a type name.
+    STDMETHOD(GetTypeIdWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ PCWSTR Name,
+        _Out_ PULONG TypeId
+        ) PURE;
+    STDMETHOD(GetFieldOffsetWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ PCWSTR Field,
+        _Out_ PULONG Offset
+        ) PURE;
+
+    STDMETHOD(GetSymbolTypeIdWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _Out_ PULONG TypeId,
+        _Out_opt_ PULONG64 Module
+        ) PURE;
+
+    STDMETHOD(GetScopeSymbolGroup2)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_opt_ PDEBUG_SYMBOL_GROUP2 Update,
+        _Out_ PDEBUG_SYMBOL_GROUP2* Symbols
+        ) PURE;
+
+    STDMETHOD(CreateSymbolGroup2)(
+        THIS_
+        _Out_ PDEBUG_SYMBOL_GROUP2* Group
+        ) PURE;
+
+    STDMETHOD(StartSymbolMatchWide)(
+        THIS_
+        _In_ PCWSTR Pattern,
+        _Out_ PULONG64 Handle
+        ) PURE;
+    STDMETHOD(GetNextSymbolMatchWide)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG MatchSize,
+        _Out_opt_ PULONG64 Offset
+        ) PURE;
+
+    STDMETHOD(ReloadWide)(
+        THIS_
+        _In_ PCWSTR Module
+        ) PURE;
+
+    STDMETHOD(GetSymbolPathWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetSymbolPathWide)(
+        THIS_
+        _In_ PCWSTR Path
+        ) PURE;
+    STDMETHOD(AppendSymbolPathWide)(
+        THIS_
+        _In_ PCWSTR Addition
+        ) PURE;
+
+    STDMETHOD(GetImagePathWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(SetImagePathWide)(
+        THIS_
+        _In_ PCWSTR Path
+        ) PURE;
+    STDMETHOD(AppendImagePathWide)(
+        THIS_
+        _In_ PCWSTR Addition
+        ) PURE;
+
+    STDMETHOD(GetSourcePathWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG PathSize
+        ) PURE;
+    STDMETHOD(GetSourcePathElementWide)(
+        THIS_
+        _In_ ULONG Index,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ElementSize
+        ) PURE;
+    STDMETHOD(SetSourcePathWide)(
+        THIS_
+        _In_ PCWSTR Path
+        ) PURE;
+    STDMETHOD(AppendSourcePathWide)(
+        THIS_
+        _In_ PCWSTR Addition
+        ) PURE;
+    STDMETHOD(FindSourceFileWide)(
+        THIS_
+        _In_ ULONG StartElement,
+        _In_ PCWSTR File,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG FoundElement,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG FoundSize
+        ) PURE;
+    STDMETHOD(GetSourceFileLineOffsetsWide)(
+        THIS_
+        _In_ PCWSTR File,
+        _Out_writes_opt_(BufferLines) PULONG64 Buffer,
+        _In_ ULONG BufferLines,
+        _Out_opt_ PULONG FileLines
+        ) PURE;
+
+    STDMETHOD(GetModuleVersionInformationWide)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _In_ PCWSTR Item,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG VerInfoSize
+        ) PURE;
+    STDMETHOD(GetModuleNameStringWide)(
+        THIS_
+        _In_ ULONG Which,
+        _In_ ULONG Index,
+        _In_ ULONG64 Base,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    STDMETHOD(GetConstantNameWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG64 Value,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    STDMETHOD(GetFieldNameWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG TypeId,
+        _In_ ULONG FieldIndex,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // Returns S_OK if the engine is using managed
+    // debugging support when retriving information
+    // for the given module.  This can be expensive
+    // to check.
+    STDMETHOD(IsManagedModule)(
+        THIS_
+        _In_ ULONG Index,
+        _In_ ULONG64 Base
+        ) PURE;
+
+    // The module name may not be unique.
+    // This method returns the first match.
+    STDMETHOD(GetModuleByModuleName2)(
+        THIS_
+        _In_ PCSTR Name,
+        _In_ ULONG StartIndex,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    STDMETHOD(GetModuleByModuleName2Wide)(
+        THIS_
+        _In_ PCWSTR Name,
+        _In_ ULONG StartIndex,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+    // Offset can be any offset within
+    // the module extent.  Extents may
+    // not be unique when including unloaded
+    // drivers.  This method returns the
+    // first match.
+    STDMETHOD(GetModuleByOffset2)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG StartIndex,
+        _In_ ULONG Flags,
+        _Out_opt_ PULONG Index,
+        _Out_opt_ PULONG64 Base
+        ) PURE;
+
+    // A caller can create artificial loaded modules in
+    // the engine's module list if desired.
+    // These modules only serve as names for
+    // a region of addresses.  They cannot have
+    // real symbols loaded for them; if that
+    // is desired Reload can be used with explicit
+    // parameters to create a true module entry.
+    // The region must not be in use by any other
+    // module.
+    // A general reload will discard any synthetic modules.
+    STDMETHOD(AddSyntheticModule)(
+        THIS_
+        _In_ ULONG64 Base,
+        _In_ ULONG Size,
+        _In_ PCSTR ImagePath,
+        _In_ PCSTR ModuleName,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(AddSyntheticModuleWide)(
+        THIS_
+        _In_ ULONG64 Base,
+        _In_ ULONG Size,
+        _In_ PCWSTR ImagePath,
+        _In_ PCWSTR ModuleName,
+        _In_ ULONG Flags
+        ) PURE;
+    STDMETHOD(RemoveSyntheticModule)(
+        THIS_
+        _In_ ULONG64 Base
+        ) PURE;
+
+    // Modify the current frame used for scoping.
+    // This is equivalent to the '.frame' command.
+    STDMETHOD(GetCurrentScopeFrameIndex)(
+        THIS_
+        _Out_ PULONG Index
+        ) PURE;
+    STDMETHOD(SetScopeFrameByIndex)(
+        THIS_
+        _In_ ULONG Index
+        ) PURE;
+
+    // Recovers JIT_DEBUG_INFO information at the given
+    // address from the debuggee and sets current
+    // debugger scope context from it.
+    // Equivalent to '.jdinfo' command.
+    STDMETHOD(SetScopeFromJitDebugInfo)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG64 InfoOffset
+        ) PURE;
+
+    // Switches the current debugger scope to
+    // the stored event information.
+    // Equivalent to the '.ecxr' command.
+    STDMETHOD(SetScopeFromStoredEvent)(
+        THIS
+        ) PURE;
+
+    // Takes the first symbol hit and outputs it.
+    // Controlled with DEBUG_OUTSYM_* flags.
+    STDMETHOD(OutputSymbolByOffset)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ ULONG64 Offset
+        ) PURE;
+
+    // Function entry information for a particular
+    // piece of code can be retrieved by this method.
+    // The actual data returned is system-dependent.
+    STDMETHOD(GetFunctionEntryByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG BufferNeeded
+        ) PURE;
+
+    // Given a type which can contain members
+    // this method returns the type ID and offset of a
+    // particular member within the type.
+    // Field gives the dot-separated path
+    // to the field of interest.
+    STDMETHOD(GetFieldTypeAndOffset)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG ContainerTypeId,
+        _In_ PCSTR Field,
+        _Out_opt_ PULONG FieldTypeId,
+        _Out_opt_ PULONG Offset
+        ) PURE;
+    STDMETHOD(GetFieldTypeAndOffsetWide)(
+        THIS_
+        _In_ ULONG64 Module,
+        _In_ ULONG ContainerTypeId,
+        _In_ PCWSTR Field,
+        _Out_opt_ PULONG FieldTypeId,
+        _Out_opt_ PULONG Offset
+        ) PURE;
+
+    // Artificial symbols can be created in any
+    // existing module as a way to name an address.
+    // The address must not already have symbol
+    // information.
+    // A reload will discard synthetic symbols
+    // for all address regions reloaded.
+    STDMETHOD(AddSyntheticSymbol)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Size,
+        _In_ PCSTR Name,
+        _In_ ULONG Flags,
+        _Out_opt_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+    STDMETHOD(AddSyntheticSymbolWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Size,
+        _In_ PCWSTR Name,
+        _In_ ULONG Flags,
+        _Out_opt_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+    STDMETHOD(RemoveSyntheticSymbol)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+
+    // The following methods can return multiple
+    // hits for symbol lookups to allow for all
+    // possible hits to be returned.
+    STDMETHOD(GetSymbolEntriesByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(IdsCount) PDEBUG_MODULE_AND_ID Ids,
+        _Out_writes_opt_(IdsCount) PULONG64 Displacements,
+        _In_ ULONG IdsCount,
+        _Out_opt_ PULONG Entries
+        ) PURE;
+    STDMETHOD(GetSymbolEntriesByName)(
+        THIS_
+        _In_ PCSTR Symbol,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(IdsCount) PDEBUG_MODULE_AND_ID Ids,
+        _In_ ULONG IdsCount,
+        _Out_opt_ PULONG Entries
+        ) PURE;
+    STDMETHOD(GetSymbolEntriesByNameWide)(
+        THIS_
+        _In_ PCWSTR Symbol,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(IdsCount) PDEBUG_MODULE_AND_ID Ids,
+        _In_ ULONG IdsCount,
+        _Out_opt_ PULONG Entries
+        ) PURE;
+    // Symbol lookup by managed metadata token.
+    STDMETHOD(GetSymbolEntryByToken)(
+        THIS_
+        _In_ ULONG64 ModuleBase,
+        _In_ ULONG Token,
+        _Out_ PDEBUG_MODULE_AND_ID Id
+        ) PURE;
+
+    // Retrieves full symbol entry information from an ID.
+    STDMETHOD(GetSymbolEntryInformation)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _Out_ PDEBUG_SYMBOL_ENTRY Info
+        ) PURE;
+    STDMETHOD(GetSymbolEntryString)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSymbolEntryStringWide)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    // Returns all known memory regions associated
+    // with the given symbol.  Simple symbols will
+    // have a single region starting from their base.
+    // More complicated regions, such as functions
+    // with multiple code areas, can have an arbitrarily
+    // large number of regions.
+    // The quality of information returned is highly
+    // dependent on the symbolic information availble.
+    STDMETHOD(GetSymbolEntryOffsetRegions)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID Id,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(RegionsCount) PDEBUG_OFFSET_REGION Regions,
+        _In_ ULONG RegionsCount,
+        _Out_opt_ PULONG RegionsAvail
+        ) PURE;
+
+    // This method allows navigating within the
+    // symbol entry hierarchy.
+    STDMETHOD(GetSymbolEntryBySymbolEntry)(
+        THIS_
+        _In_ PDEBUG_MODULE_AND_ID FromId,
+        _In_ ULONG Flags,
+        _Out_ PDEBUG_MODULE_AND_ID ToId
+        ) PURE;
+
+    // The following methods can return multiple
+    // hits for source lookups to allow for all
+    // possible hits to be returned.
+    STDMETHOD(GetSourceEntriesByOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
+        _In_ ULONG EntriesCount,
+        _Out_opt_ PULONG EntriesAvail
+        ) PURE;
+    STDMETHOD(GetSourceEntriesByLine)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCSTR File,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
+        _In_ ULONG EntriesCount,
+        _Out_opt_ PULONG EntriesAvail
+        ) PURE;
+    STDMETHOD(GetSourceEntriesByLineWide)(
+        THIS_
+        _In_ ULONG Line,
+        _In_ PCWSTR File,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(EntriesCount) PDEBUG_SYMBOL_SOURCE_ENTRY Entries,
+        _In_ ULONG EntriesCount,
+        _Out_opt_ PULONG EntriesAvail
+        ) PURE;
+
+    STDMETHOD(GetSourceEntryString)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    STDMETHOD(GetSourceEntryStringWide)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
+        _In_ ULONG Which,
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG StringSize
+        ) PURE;
+    // Returns all known memory regions associated
+    // with the given source entry.  As with
+    // GetSymbolEntryOffsetRegions the regions available
+    // are variable.
+    STDMETHOD(GetSourceEntryOffsetRegions)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY Entry,
+        _In_ ULONG Flags,
+        _Out_writes_opt_(RegionsCount) PDEBUG_OFFSET_REGION Regions,
+        _In_ ULONG RegionsCount,
+        _Out_opt_ PULONG RegionsAvail
+        ) PURE;
+
+    // This method allows navigating within the
+    // source entries.
+    STDMETHOD(GetSourceEntryBySourceEntry)(
+        THIS_
+        _In_ PDEBUG_SYMBOL_SOURCE_ENTRY FromEntry,
+        _In_ ULONG Flags,
+        _Out_ PDEBUG_SYMBOL_SOURCE_ENTRY ToEntry
+        ) PURE;
+
+    // IDebugSymbols4
+    STDMETHOD(GetScopeEx)(
+        THIS_
+        _Out_opt_ PULONG64 InstructionOffset,
+        _Out_opt_ PDEBUG_STACK_FRAME_EX ScopeFrame,
+        _Out_writes_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+
+    STDMETHOD(SetScopeEx)(
+        THIS_
+        _In_ ULONG64 InstructionOffset,
+        _In_opt_ PDEBUG_STACK_FRAME_EX ScopeFrame,
+        _In_reads_bytes_opt_(ScopeContextSize) PVOID ScopeContext,
+        _In_ ULONG ScopeContextSize
+        ) PURE;
+
+    STDMETHOD(GetNameByInlineContext)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext,
+        _Out_writes_opt_(NameBufferSize) PSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetNameByInlineContextWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext,
+        _Out_writes_opt_(NameBufferSize) PWSTR NameBuffer,
+        _In_ ULONG NameBufferSize,
+        _Out_opt_ PULONG NameSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByInlineContext)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(GetLineByInlineContextWide)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext,
+        _Out_opt_ PULONG Line,
+        _Out_writes_opt_(FileBufferSize) PWSTR FileBuffer,
+        _In_ ULONG FileBufferSize,
+        _Out_opt_ PULONG FileSize,
+        _Out_opt_ PULONG64 Displacement
+        ) PURE;
+
+    STDMETHOD(OutputSymbolByInlineContext)(
+        THIS_
+        _In_ ULONG OutputControl,
+        _In_ ULONG Flags,
+        _In_ ULONG64 Offset,
+        _In_ ULONG InlineContext
+        ) PURE;
+
+    // IDebugSymbols5
+    STDMETHOD(GetCurrentScopeFrameIndexEx)(
+        THIS_
+        _In_ ULONG Flags,
+        _Out_ PULONG Index
+        ) PURE;
+    STDMETHOD(SetScopeFrameByIndexEx)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG Index
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// IDebugSystemObjects
+//
+//----------------------------------------------------------------------------
+
+#undef INTERFACE
+#define INTERFACE IDebugSystemObjects
+DECLARE_INTERFACE_(IDebugSystemObjects, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSystemObjects.
+
+    // In user mode debugging the debugger
+    // tracks all threads and processes and
+    // enumerates them through the following
+    // methods.  When enumerating threads
+    // the threads are enumerated for the current
+    // process.
+    // Kernel mode debugging currently is
+    // limited to enumerating only the threads
+    // assigned to processors, not all of
+    // the threads in the system.  Process
+    // enumeration is limited to a single
+    // virtual process representing kernel space.
+
+    // Returns the ID of the thread on which
+    // the last event occurred.
+    STDMETHOD(GetEventThread)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetEventProcess)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+
+    // Controls implicit thread used by the
+    // debug engine.  The debuggers current
+    // thread is just a piece of data held
+    // by the debugger for calls which use
+    // thread-specific information.  In those
+    // calls the debuggers current thread is used.
+    // The debuggers current thread is not related
+    // to any system thread attribute.
+    // IDs for threads are small integer IDs
+    // maintained by the engine.  They are not
+    // related to system thread IDs.
+    STDMETHOD(GetCurrentThreadId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(SetCurrentThreadId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+    // The current process is the process
+    // that owns the current thread.
+    STDMETHOD(GetCurrentProcessId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    // Setting the current process automatically
+    // sets the current thread to the thread that
+    // was last current in that process.
+    STDMETHOD(SetCurrentProcessId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+
+    // Gets the number of threads in the current process.
+    STDMETHOD(GetNumberThreads)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // Gets thread count information for all processes
+    // and the largest number of threads in a single process.
+    STDMETHOD(GetTotalNumberThreads)(
+        THIS_
+        _Out_ PULONG Total,
+        _Out_ PULONG LargestProcess
+        ) PURE;
+    STDMETHOD(GetThreadIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _Out_writes_opt_(Count) PULONG SysIds
+        ) PURE;
+    // Gets the debugger ID for the thread
+    // currently running on the given
+    // processor.  Only works in kernel
+    // debugging.
+    STDMETHOD(GetThreadIdByProcessor)(
+        THIS_
+        _In_ ULONG Processor,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current threads
+    // system data structure.  When kernel debugging
+    // this is the offset of the KTHREAD.
+    // When user debugging it is the offset
+    // of the current TEB.
+    STDMETHOD(GetCurrentThreadDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger thread ID for the given
+    // system thread data structure.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current threads
+    // TEB.  In user mode this is equivalent to
+    // the threads data offset.
+    STDMETHOD(GetCurrentThreadTeb)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger thread ID for the given TEB.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByTeb)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the system unique ID for the current thread.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetCurrentThreadSystemId)(
+        THIS_
+        _Out_ PULONG SysId
+        ) PURE;
+    // Looks up a debugger thread ID for the given
+    // system thread ID.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdBySystemId)(
+        THIS_
+        _In_ ULONG SysId,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the handle of the current thread.
+    // In kernel mode the value returned is the
+    // index of the processor the thread is
+    // executing on plus one.
+    STDMETHOD(GetCurrentThreadHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // Looks up a debugger thread ID for the given handle.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByHandle)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ PULONG Id
+        ) PURE;
+
+    // Currently kernel mode sessions will only have
+    // a single process representing kernel space.
+    STDMETHOD(GetNumberProcesses)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetProcessIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _Out_writes_opt_(Count) PULONG SysIds
+        ) PURE;
+    // Returns the offset of the current processs
+    // system data structure.  When kernel debugging
+    // this is the offset of the KPROCESS of
+    // the process that owns the current thread.
+    // When user debugging it is the offset
+    // of the current PEB.
+    STDMETHOD(GetCurrentProcessDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger process ID for the given
+    // system process data structure.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdByDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current processs
+    // PEB.  In user mode this is equivalent to
+    // the processs data offset.
+    STDMETHOD(GetCurrentProcessPeb)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger process ID for the given PEB.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdByPeb)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the system unique ID for the current process.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetCurrentProcessSystemId)(
+        THIS_
+        _Out_ PULONG SysId
+        ) PURE;
+    // Looks up a debugger process ID for the given
+    // system process ID.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdBySystemId)(
+        THIS_
+        _In_ ULONG SysId,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the handle of the current process.
+    // In kernel mode this is the kernel processs
+    // artificial handle used for symbol operations
+    // and so can only be used with dbghelp APIs.
+    STDMETHOD(GetCurrentProcessHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // Looks up a debugger process ID for the given handle.
+    STDMETHOD(GetProcessIdByHandle)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ PULONG Id
+        ) PURE;
+    // Retrieve the name of the executable loaded
+    // in the process.  This may fail if no executable
+    // was identified.
+    STDMETHOD(GetCurrentProcessExecutableName)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExeSize
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugSystemObjects2
+DECLARE_INTERFACE_(IDebugSystemObjects2, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSystemObjects.
+
+    // In user mode debugging the debugger
+    // tracks all threads and processes and
+    // enumerates them through the following
+    // methods.  When enumerating threads
+    // the threads are enumerated for the current
+    // process.
+    // Kernel mode debugging currently is
+    // limited to enumerating only the threads
+    // assigned to processors, not all of
+    // the threads in the system.  Process
+    // enumeration is limited to a single
+    // virtual process representing kernel space.
+
+    // Returns the ID of the thread on which
+    // the last event occurred.
+    STDMETHOD(GetEventThread)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetEventProcess)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+
+    // Controls implicit thread used by the
+    // debug engine.  The debuggers current
+    // thread is just a piece of data held
+    // by the debugger for calls which use
+    // thread-specific information.  In those
+    // calls the debuggers current thread is used.
+    // The debuggers current thread is not related
+    // to any system thread attribute.
+    // IDs for threads are small integer IDs
+    // maintained by the engine.  They are not
+    // related to system thread IDs.
+    STDMETHOD(GetCurrentThreadId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(SetCurrentThreadId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+    // The current process is the process
+    // that owns the current thread.
+    STDMETHOD(GetCurrentProcessId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    // Setting the current process automatically
+    // sets the current thread to the thread that
+    // was last current in that process.
+    STDMETHOD(SetCurrentProcessId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+
+    // Gets the number of threads in the current process.
+    STDMETHOD(GetNumberThreads)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // Gets thread count information for all processes
+    // and the largest number of threads in a single process.
+    STDMETHOD(GetTotalNumberThreads)(
+        THIS_
+        _Out_ PULONG Total,
+        _Out_ PULONG LargestProcess
+        ) PURE;
+    STDMETHOD(GetThreadIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _Out_writes_opt_(Count) PULONG SysIds
+        ) PURE;
+    // Gets the debugger ID for the thread
+    // currently running on the given
+    // processor.  Only works in kernel
+    // debugging.
+    STDMETHOD(GetThreadIdByProcessor)(
+        THIS_
+        _In_ ULONG Processor,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current threads
+    // system data structure.  When kernel debugging
+    // this is the offset of the KTHREAD.
+    // When user debugging it is the offset
+    // of the current TEB.
+    STDMETHOD(GetCurrentThreadDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger thread ID for the given
+    // system thread data structure.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current threads
+    // TEB.  In user mode this is equivalent to
+    // the threads data offset.
+    STDMETHOD(GetCurrentThreadTeb)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger thread ID for the given TEB.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByTeb)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the system unique ID for the current thread.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetCurrentThreadSystemId)(
+        THIS_
+        _Out_ PULONG SysId
+        ) PURE;
+    // Looks up a debugger thread ID for the given
+    // system thread ID.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdBySystemId)(
+        THIS_
+        _In_ ULONG SysId,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the handle of the current thread.
+    // In kernel mode the value returned is the
+    // index of the processor the thread is
+    // executing on plus one.
+    STDMETHOD(GetCurrentThreadHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // Looks up a debugger thread ID for the given handle.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByHandle)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ PULONG Id
+        ) PURE;
+
+    // Currently kernel mode sessions will only have
+    // a single process representing kernel space.
+    STDMETHOD(GetNumberProcesses)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetProcessIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _Out_writes_opt_(Count) PULONG SysIds
+        ) PURE;
+    // Returns the offset of the current processs
+    // system data structure.  When kernel debugging
+    // this is the offset of the KPROCESS of
+    // the process that owns the current thread.
+    // When user debugging it is the offset
+    // of the current PEB.
+    STDMETHOD(GetCurrentProcessDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger process ID for the given
+    // system process data structure.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdByDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current processs
+    // PEB.  In user mode this is equivalent to
+    // the processs data offset.
+    STDMETHOD(GetCurrentProcessPeb)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger process ID for the given PEB.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdByPeb)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the system unique ID for the current process.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetCurrentProcessSystemId)(
+        THIS_
+        _Out_ PULONG SysId
+        ) PURE;
+    // Looks up a debugger process ID for the given
+    // system process ID.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdBySystemId)(
+        THIS_
+        _In_ ULONG SysId,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the handle of the current process.
+    // In kernel mode this is the kernel processs
+    // artificial handle used for symbol operations
+    // and so can only be used with dbghelp APIs.
+    STDMETHOD(GetCurrentProcessHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // Looks up a debugger process ID for the given handle.
+    STDMETHOD(GetProcessIdByHandle)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ PULONG Id
+        ) PURE;
+    // Retrieve the name of the executable loaded
+    // in the process.  This may fail if no executable
+    // was identified.
+    STDMETHOD(GetCurrentProcessExecutableName)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExeSize
+        ) PURE;
+
+    // IDebugSystemObjects2.
+
+    // Return the number of seconds that the current
+    // process has been running.
+    STDMETHOD(GetCurrentProcessUpTime)(
+        THIS_
+        _Out_ PULONG UpTime
+        ) PURE;
+
+    // During kernel sessions the debugger retrieves
+    // some information from the system thread and process
+    // running on the current processor.  For example,
+    // the debugger will retrieve virtual memory translation
+    // information for when the debugger needs to
+    // carry out its own virtual to physical translations.
+    // Occasionally it can be interesting to perform
+    // similar operations but on a process which isnt
+    // currently running.  The follow methods allow a caller
+    // to override the data offsets used by the debugger
+    // so that other system threads and processes can
+    // be used instead.  These values are defaulted to
+    // the thread and process running on the current
+    // processor each time the debuggee executes or
+    // the current processor changes.
+    // The thread and process settings are independent so
+    // it is possible to refer to a thread in a process
+    // other than the current process and vice versa.
+    // Setting an offset of zero will reload the
+    // default value.
+    STDMETHOD(GetImplicitThreadDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(SetImplicitThreadDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetImplicitProcessDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(SetImplicitProcessDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugSystemObjects3
+DECLARE_INTERFACE_(IDebugSystemObjects3, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSystemObjects.
+
+    // In user mode debugging the debugger
+    // tracks all threads and processes and
+    // enumerates them through the following
+    // methods.  When enumerating threads
+    // the threads are enumerated for the current
+    // process.
+    // Kernel mode debugging currently is
+    // limited to enumerating only the threads
+    // assigned to processors, not all of
+    // the threads in the system.  Process
+    // enumeration is limited to a single
+    // virtual process representing kernel space.
+
+    // Returns the ID of the thread on which
+    // the last event occurred.
+    STDMETHOD(GetEventThread)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetEventProcess)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+
+    // Controls implicit thread used by the
+    // debug engine.  The debuggers current
+    // thread is just a piece of data held
+    // by the debugger for calls which use
+    // thread-specific information.  In those
+    // calls the debuggers current thread is used.
+    // The debuggers current thread is not related
+    // to any system thread attribute.
+    // IDs for threads are small integer IDs
+    // maintained by the engine.  They are not
+    // related to system thread IDs.
+    STDMETHOD(GetCurrentThreadId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(SetCurrentThreadId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+    // The current process is the process
+    // that owns the current thread.
+    STDMETHOD(GetCurrentProcessId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    // Setting the current process automatically
+    // sets the current thread to the thread that
+    // was last current in that process.
+    STDMETHOD(SetCurrentProcessId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+
+    // Gets the number of threads in the current process.
+    STDMETHOD(GetNumberThreads)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // Gets thread count information for all processes
+    // and the largest number of threads in a single process.
+    STDMETHOD(GetTotalNumberThreads)(
+        THIS_
+        _Out_ PULONG Total,
+        _Out_ PULONG LargestProcess
+        ) PURE;
+    STDMETHOD(GetThreadIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _Out_writes_opt_(Count) PULONG SysIds
+        ) PURE;
+    // Gets the debugger ID for the thread
+    // currently running on the given
+    // processor.  Only works in kernel
+    // debugging.
+    STDMETHOD(GetThreadIdByProcessor)(
+        THIS_
+        _In_ ULONG Processor,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current threads
+    // system data structure.  When kernel debugging
+    // this is the offset of the KTHREAD.
+    // When user debugging it is the offset
+    // of the current TEB.
+    STDMETHOD(GetCurrentThreadDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger thread ID for the given
+    // system thread data structure.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current threads
+    // TEB.  In user mode this is equivalent to
+    // the threads data offset.
+    STDMETHOD(GetCurrentThreadTeb)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger thread ID for the given TEB.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByTeb)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the system unique ID for the current thread.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetCurrentThreadSystemId)(
+        THIS_
+        _Out_ PULONG SysId
+        ) PURE;
+    // Looks up a debugger thread ID for the given
+    // system thread ID.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdBySystemId)(
+        THIS_
+        _In_ ULONG SysId,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the handle of the current thread.
+    // In kernel mode the value returned is the
+    // index of the processor the thread is
+    // executing on plus one.
+    STDMETHOD(GetCurrentThreadHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // Looks up a debugger thread ID for the given handle.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByHandle)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ PULONG Id
+        ) PURE;
+
+    // Currently kernel mode sessions will only have
+    // a single process representing kernel space.
+    STDMETHOD(GetNumberProcesses)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetProcessIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _Out_writes_opt_(Count) PULONG SysIds
+        ) PURE;
+    // Returns the offset of the current processs
+    // system data structure.  When kernel debugging
+    // this is the offset of the KPROCESS of
+    // the process that owns the current thread.
+    // When user debugging it is the offset
+    // of the current PEB.
+    STDMETHOD(GetCurrentProcessDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger process ID for the given
+    // system process data structure.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdByDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current processs
+    // PEB.  In user mode this is equivalent to
+    // the processs data offset.
+    STDMETHOD(GetCurrentProcessPeb)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger process ID for the given PEB.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdByPeb)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the system unique ID for the current process.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetCurrentProcessSystemId)(
+        THIS_
+        _Out_ PULONG SysId
+        ) PURE;
+    // Looks up a debugger process ID for the given
+    // system process ID.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdBySystemId)(
+        THIS_
+        _In_ ULONG SysId,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the handle of the current process.
+    // In kernel mode this is the kernel processs
+    // artificial handle used for symbol operations
+    // and so can only be used with dbghelp APIs.
+    STDMETHOD(GetCurrentProcessHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // Looks up a debugger process ID for the given handle.
+    STDMETHOD(GetProcessIdByHandle)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ PULONG Id
+        ) PURE;
+    // Retrieve the name of the executable loaded
+    // in the process.  This may fail if no executable
+    // was identified.
+    STDMETHOD(GetCurrentProcessExecutableName)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExeSize
+        ) PURE;
+
+    // IDebugSystemObjects2.
+
+    // Return the number of seconds that the current
+    // process has been running.
+    STDMETHOD(GetCurrentProcessUpTime)(
+        THIS_
+        _Out_ PULONG UpTime
+        ) PURE;
+
+    // During kernel sessions the debugger retrieves
+    // some information from the system thread and process
+    // running on the current processor.  For example,
+    // the debugger will retrieve virtual memory translation
+    // information for when the debugger needs to
+    // carry out its own virtual to physical translations.
+    // Occasionally it can be interesting to perform
+    // similar operations but on a process which isnt
+    // currently running.  The follow methods allow a caller
+    // to override the data offsets used by the debugger
+    // so that other system threads and processes can
+    // be used instead.  These values are defaulted to
+    // the thread and process running on the current
+    // processor each time the debuggee executes or
+    // the current processor changes.
+    // The thread and process settings are independent so
+    // it is possible to refer to a thread in a process
+    // other than the current process and vice versa.
+    // Setting an offset of zero will reload the
+    // default value.
+    STDMETHOD(GetImplicitThreadDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(SetImplicitThreadDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetImplicitProcessDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(SetImplicitProcessDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset
+        ) PURE;
+
+    // IDebugSystemObjects3.
+
+    STDMETHOD(GetEventSystem)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+
+    STDMETHOD(GetCurrentSystemId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(SetCurrentSystemId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+
+    STDMETHOD(GetNumberSystems)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetSystemIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Ids
+        ) PURE;
+    STDMETHOD(GetTotalNumberThreadsAndProcesses)(
+        THIS_
+        _Out_ PULONG TotalThreads,
+        _Out_ PULONG TotalProcesses,
+        _Out_ PULONG LargestProcessThreads,
+        _Out_ PULONG LargestSystemThreads,
+        _Out_ PULONG LargestSystemProcesses
+        ) PURE;
+    STDMETHOD(GetCurrentSystemServer)(
+        THIS_
+        _Out_ PULONG64 Server
+        ) PURE;
+    STDMETHOD(GetSystemByServer)(
+        THIS_
+        _In_ ULONG64 Server,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetCurrentSystemServerName)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+};
+
+#undef INTERFACE
+#define INTERFACE IDebugSystemObjects4
+DECLARE_INTERFACE_(IDebugSystemObjects4, IUnknown)
+{
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        ) PURE;
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        ) PURE;
+
+    // IDebugSystemObjects.
+
+    // In user mode debugging the debugger
+    // tracks all threads and processes and
+    // enumerates them through the following
+    // methods.  When enumerating threads
+    // the threads are enumerated for the current
+    // process.
+    // Kernel mode debugging currently is
+    // limited to enumerating only the threads
+    // assigned to processors, not all of
+    // the threads in the system.  Process
+    // enumeration is limited to a single
+    // virtual process representing kernel space.
+
+    // Returns the ID of the thread on which
+    // the last event occurred.
+    STDMETHOD(GetEventThread)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetEventProcess)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+
+    // Controls implicit thread used by the
+    // debug engine.  The debuggers current
+    // thread is just a piece of data held
+    // by the debugger for calls which use
+    // thread-specific information.  In those
+    // calls the debuggers current thread is used.
+    // The debuggers current thread is not related
+    // to any system thread attribute.
+    // IDs for threads are small integer IDs
+    // maintained by the engine.  They are not
+    // related to system thread IDs.
+    STDMETHOD(GetCurrentThreadId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(SetCurrentThreadId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+    // The current process is the process
+    // that owns the current thread.
+    STDMETHOD(GetCurrentProcessId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    // Setting the current process automatically
+    // sets the current thread to the thread that
+    // was last current in that process.
+    STDMETHOD(SetCurrentProcessId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+
+    // Gets the number of threads in the current process.
+    STDMETHOD(GetNumberThreads)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    // Gets thread count information for all processes
+    // and the largest number of threads in a single process.
+    STDMETHOD(GetTotalNumberThreads)(
+        THIS_
+        _Out_ PULONG Total,
+        _Out_ PULONG LargestProcess
+        ) PURE;
+    STDMETHOD(GetThreadIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _Out_writes_opt_(Count) PULONG SysIds
+        ) PURE;
+    // Gets the debugger ID for the thread
+    // currently running on the given
+    // processor.  Only works in kernel
+    // debugging.
+    STDMETHOD(GetThreadIdByProcessor)(
+        THIS_
+        _In_ ULONG Processor,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current threads
+    // system data structure.  When kernel debugging
+    // this is the offset of the KTHREAD.
+    // When user debugging it is the offset
+    // of the current TEB.
+    STDMETHOD(GetCurrentThreadDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger thread ID for the given
+    // system thread data structure.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current threads
+    // TEB.  In user mode this is equivalent to
+    // the threads data offset.
+    STDMETHOD(GetCurrentThreadTeb)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger thread ID for the given TEB.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByTeb)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the system unique ID for the current thread.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetCurrentThreadSystemId)(
+        THIS_
+        _Out_ PULONG SysId
+        ) PURE;
+    // Looks up a debugger thread ID for the given
+    // system thread ID.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdBySystemId)(
+        THIS_
+        _In_ ULONG SysId,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the handle of the current thread.
+    // In kernel mode the value returned is the
+    // index of the processor the thread is
+    // executing on plus one.
+    STDMETHOD(GetCurrentThreadHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // Looks up a debugger thread ID for the given handle.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    STDMETHOD(GetThreadIdByHandle)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ PULONG Id
+        ) PURE;
+
+    // Currently kernel mode sessions will only have
+    // a single process representing kernel space.
+    STDMETHOD(GetNumberProcesses)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetProcessIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_opt_(Count) PULONG Ids,
+        _Out_writes_opt_(Count) PULONG SysIds
+        ) PURE;
+    // Returns the offset of the current processs
+    // system data structure.  When kernel debugging
+    // this is the offset of the KPROCESS of
+    // the process that owns the current thread.
+    // When user debugging it is the offset
+    // of the current PEB.
+    STDMETHOD(GetCurrentProcessDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger process ID for the given
+    // system process data structure.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdByDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the offset of the current processs
+    // PEB.  In user mode this is equivalent to
+    // the processs data offset.
+    STDMETHOD(GetCurrentProcessPeb)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    // Looks up a debugger process ID for the given PEB.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdByPeb)(
+        THIS_
+        _In_ ULONG64 Offset,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the system unique ID for the current process.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetCurrentProcessSystemId)(
+        THIS_
+        _Out_ PULONG SysId
+        ) PURE;
+    // Looks up a debugger process ID for the given
+    // system process ID.
+    // Not currently supported when kernel debugging.
+    STDMETHOD(GetProcessIdBySystemId)(
+        THIS_
+        _In_ ULONG SysId,
+        _Out_ PULONG Id
+        ) PURE;
+    // Returns the handle of the current process.
+    // In kernel mode this is the kernel processs
+    // artificial handle used for symbol operations
+    // and so can only be used with dbghelp APIs.
+    STDMETHOD(GetCurrentProcessHandle)(
+        THIS_
+        _Out_ PULONG64 Handle
+        ) PURE;
+    // Looks up a debugger process ID for the given handle.
+    STDMETHOD(GetProcessIdByHandle)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _Out_ PULONG Id
+        ) PURE;
+    // Retrieve the name of the executable loaded
+    // in the process.  This may fail if no executable
+    // was identified.
+    STDMETHOD(GetCurrentProcessExecutableName)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExeSize
+        ) PURE;
+
+    // IDebugSystemObjects2.
+
+    // Return the number of seconds that the current
+    // process has been running.
+    STDMETHOD(GetCurrentProcessUpTime)(
+        THIS_
+        _Out_ PULONG UpTime
+        ) PURE;
+
+    // During kernel sessions the debugger retrieves
+    // some information from the system thread and process
+    // running on the current processor.  For example,
+    // the debugger will retrieve virtual memory translation
+    // information for when the debugger needs to
+    // carry out its own virtual to physical translations.
+    // Occasionally it can be interesting to perform
+    // similar operations but on a process which isnt
+    // currently running.  The follow methods allow a caller
+    // to override the data offsets used by the debugger
+    // so that other system threads and processes can
+    // be used instead.  These values are defaulted to
+    // the thread and process running on the current
+    // processor each time the debuggee executes or
+    // the current processor changes.
+    // The thread and process settings are independent so
+    // it is possible to refer to a thread in a process
+    // other than the current process and vice versa.
+    // Setting an offset of zero will reload the
+    // default value.
+    STDMETHOD(GetImplicitThreadDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(SetImplicitThreadDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset
+        ) PURE;
+    STDMETHOD(GetImplicitProcessDataOffset)(
+        THIS_
+        _Out_ PULONG64 Offset
+        ) PURE;
+    STDMETHOD(SetImplicitProcessDataOffset)(
+        THIS_
+        _In_ ULONG64 Offset
+        ) PURE;
+
+    // IDebugSystemObjects3.
+
+    STDMETHOD(GetEventSystem)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+
+    STDMETHOD(GetCurrentSystemId)(
+        THIS_
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(SetCurrentSystemId)(
+        THIS_
+        _In_ ULONG Id
+        ) PURE;
+
+    STDMETHOD(GetNumberSystems)(
+        THIS_
+        _Out_ PULONG Number
+        ) PURE;
+    STDMETHOD(GetSystemIdsByIndex)(
+        THIS_
+        _In_ ULONG Start,
+        _In_ ULONG Count,
+        _Out_writes_(Count) PULONG Ids
+        ) PURE;
+    STDMETHOD(GetTotalNumberThreadsAndProcesses)(
+        THIS_
+        _Out_ PULONG TotalThreads,
+        _Out_ PULONG TotalProcesses,
+        _Out_ PULONG LargestProcessThreads,
+        _Out_ PULONG LargestSystemThreads,
+        _Out_ PULONG LargestSystemProcesses
+        ) PURE;
+    STDMETHOD(GetCurrentSystemServer)(
+        THIS_
+        _Out_ PULONG64 Server
+        ) PURE;
+    STDMETHOD(GetSystemByServer)(
+        THIS_
+        _In_ ULONG64 Server,
+        _Out_ PULONG Id
+        ) PURE;
+    STDMETHOD(GetCurrentSystemServerName)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+
+    // IDebugSystemObjects4.
+
+    STDMETHOD(GetCurrentProcessExecutableNameWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG ExeSize
+        ) PURE;
+
+    STDMETHOD(GetCurrentSystemServerNameWide)(
+        THIS_
+        _Out_writes_opt_(BufferSize) PWSTR Buffer,
+        _In_ ULONG BufferSize,
+        _Out_opt_ PULONG NameSize
+        ) PURE;
+};
+
+//----------------------------------------------------------------------------
+//
+// Debugger/debuggee communication.
+//
+// A distinguished exception, DBG_COMMAND_EXCEPTION (0x40010009),
+// can be used by a debuggee to communicate with the debugger.
+// The arguments of the exception must be:
+// 1. Exception ID.
+// 2. Command code.
+// 3. Size of argument.
+// 4. Pointer to argument.
+//
+// The arguments depend on the command code.
+//
+//----------------------------------------------------------------------------
+
+#define DEBUG_COMMAND_EXCEPTION_ID 0xdbe00dbe
+
+// Invalid command code.
+#define DEBUG_CMDEX_INVALID             0x00000000
+
+//
+// The debugger can collect strings for display at the
+// next event.  A debuggee can use this to register information
+// about a program situation before places where an event
+// may occur, such as a risky operation or assertion.
+// The strings are automatically flushed on the next
+// event continuation.  Strings are kept on a per-thread basis.
+//
+// When adding, the argument is the string to add.
+// Reset has no arguments and clears all strings.
+//
+#define DEBUG_CMDEX_ADD_EVENT_STRING    0x00000001
+#define DEBUG_CMDEX_RESET_EVENT_STRINGS 0x00000002
+
+#ifndef DEBUG_NO_IMPLEMENTATION
+
+FORCEINLINE void
+DebugCommandException(ULONG Command, ULONG ArgSize, PVOID Arg)
+{
+    ULONG_PTR ExArgs[4];
+
+    ExArgs[0] = DEBUG_COMMAND_EXCEPTION_ID;
+    ExArgs[1] = Command;
+    ExArgs[2] = ArgSize;
+    ExArgs[3] = (ULONG_PTR)Arg;
+    RaiseException(DBG_COMMAND_EXCEPTION, 0, 4, ExArgs);
+}
+
+#endif // #ifndef DEBUG_NO_IMPLEMENTATION
+
+//----------------------------------------------------------------------------
+//
+// Extension callbacks.
+//
+//----------------------------------------------------------------------------
+
+// Returns a version with the major version in
+// the high word and the minor version in the low word.
+#define DEBUG_EXTENSION_VERSION(Major, Minor) \
+    ((((Major) & 0xffff) << 16) | ((Minor) & 0xffff))
+
+//
+// Descriptive flags returned from extension initialization.
+//
+
+// Extension has a !help command which can give
+// per-command help.
+#define DEBUG_EXTINIT_HAS_COMMAND_HELP 0x00000001
+
+// Initialization routine.  Called once when the extension DLL
+// is loaded.  Returns a version and returns flags detailing
+// overall qualities of the extension DLL.
+// A session may or may not be active at the time the DLL
+// is loaded so initialization routines should not expect
+// to be able to query session information.
+typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_INITIALIZE)
+    (_Out_ PULONG Version, _Out_ PULONG Flags);
+// Exit routine.  Called once just before attempting to unload
+// the extension DLL.  If DebugExtensionCanUnload is present,
+// it will be called between the return of this callback and
+// an actual unload of the DLL.  If not, the extension DLL 
+// will be unloaded upon return of this method.  As with 
+// initialization, a session may or may not be active at the 
+// time of the call.
+typedef void (CALLBACK* PDEBUG_EXTENSION_UNINITIALIZE)
+    (void);
+// Routine to check if a debug extension can unload after
+// the uninitialization call.  If present, this is called
+// between the uninitialize callback and actual unload of
+// the DLL.  The extension should return either S_OK (if no
+// objects are present which would prevent unload of the
+// extension) or S_FALSE (if there are still outstanding 
+// references to model objects in the debugger extension)
+// 
+// This is the debugger's equivalent of DllCanUnloadNow
+// for extensions which manipulate the debugger's object
+// model.
+typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_CANUNLOAD)
+    (void);
+// Unload routine.  If and only if DebugExtensionCanUnload
+// is presnt in the debugger extension, this will be called
+// after a successful CanUnload call immediately before the 
+// debugger actually unloads the extension DLL.
+typedef void (CALLBACK* PDEBUG_EXTENSION_UNLOAD)
+    (void);
+
+// A debuggee has been discovered for the session.  It
+// is not necessarily halted.
+#define DEBUG_NOTIFY_SESSION_ACTIVE       0x00000000
+// The session no longer has a debuggee.
+#define DEBUG_NOTIFY_SESSION_INACTIVE     0x00000001
+// The debuggee is halted and accessible.
+#define DEBUG_NOTIFY_SESSION_ACCESSIBLE   0x00000002
+// The debuggee is running or inaccessible.
+#define DEBUG_NOTIFY_SESSION_INACCESSIBLE 0x00000003
+
+typedef void (CALLBACK* PDEBUG_EXTENSION_NOTIFY)
+    (_In_ ULONG Notify, _In_ ULONG64 Argument);
+
+// A PDEBUG_EXTENSION_CALL function can return this code
+// to indicate that it was unable to handle the request
+// and that the search for an extension function should
+// continue down the extension DLL chain.
+// Taken from STATUS_VALIDATE_CONTINUE.
+#define DEBUG_EXTENSION_CONTINUE_SEARCH \
+    HRESULT_FROM_NT(0xC0000271L)
+
+// A PDEBUG_EXTENSION_CALL function can return this code
+// to indicate that the engine should unload and reload
+// the extension binary.  This allows extensions to implement
+// auto-update functionality.
+#define DEBUG_EXTENSION_RELOAD_EXTENSION \
+    HRESULT_FROM_NT(0xC00000EEL)
+
+// Every routine in an extension DLL has the following prototype.
+// The extension may be called from multiple clients so it
+// should not cache the client value between calls.
+typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_CALL)
+    (_In_ PDEBUG_CLIENT Client, _In_opt_ PCSTR Args);
+
+//
+// KnownStructOutput[Ex] flags
+//
+
+// Return names of supported structs.
+#define DEBUG_KNOWN_STRUCT_GET_NAMES              1
+// Return value output for type.
+#define DEBUG_KNOWN_STRUCT_GET_SINGLE_LINE_OUTPUT 2
+// Return S_OK if suppressing type name.
+#define DEBUG_KNOWN_STRUCT_SUPPRESS_TYPE_NAME     3
+
+// Extensions may export this callback in order to dump structs that
+// are well known to them.  The engine calls this to inject extension
+// output into dt's struct dump.
+typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_KNOWN_STRUCT)
+    (_In_ ULONG Flags,
+     _In_ ULONG64 Offset,
+     _In_opt_ PSTR TypeName,
+     _Out_writes_opt_(*BufferChars) PSTR Buffer,
+     _Inout_opt_ PULONG BufferChars);
+typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_KNOWN_STRUCT_EX)
+    (_In_ PDEBUG_CLIENT Client,
+     _In_ ULONG Flags,
+     _In_ ULONG64 Offset,
+     _In_opt_ PCSTR TypeName,
+     _Out_writes_opt_(*BufferChars) PSTR Buffer,
+     _Inout_opt_ PULONG BufferChars);
+
+// Backwards compatibility with old, incorrect name.
+typedef PDEBUG_EXTENSION_KNOWN_STRUCT PDEBUG_ENTENSION_KNOWNSTRUCT;
+
+//
+// Extensions can provide pseudo-register values that
+// operate similiarly to the debugger's built-in $teb, etc.
+//
+
+#define DEBUG_EXT_QVALUE_DEFAULT 0x00000000
+
+typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_QUERY_VALUE_NAMES)
+    (_In_ PDEBUG_CLIENT Client,
+     _In_ ULONG Flags,
+     _Out_writes_(BufferChars) PWSTR Buffer,
+     _In_ ULONG BufferChars,
+     _Out_ PULONG BufferNeeded);
+
+#define DEBUG_EXT_PVALUE_DEFAULT 0x00000000
+
+#define DEBUG_EXT_PVTYPE_IS_VALUE   0x00000000
+#define DEBUG_EXT_PVTYPE_IS_POINTER 0x00000001
+
+typedef HRESULT (CALLBACK* PDEBUG_EXTENSION_PROVIDE_VALUE)
+    (_In_ PDEBUG_CLIENT Client,
+     _In_ ULONG Flags,
+     _In_ PCWSTR Name,
+     _Out_ PULONG64 Value,
+     _Out_ PULONG64 TypeModBase,
+     _Out_ PULONG TypeId,
+     _Out_ PULONG TypeFlags);
+
+//----------------------------------------------------------------------------
+//
+// Extension functions.
+//
+// Extension functions differ from extension callbacks in that
+// they are arbitrary functions exported from an extension DLL
+// for other code callers instead of for human invocation from
+// debugger commands.  Extension function pointers are retrieved
+// for an extension DLL with IDebugControl::GetExtensionFunction.
+//
+// Extension function names must begin with _EFN_.  Other than that
+// they can have any name and prototype.  Extension functions
+// must be public exports of their extension DLL.  They should
+// have a typedef for their function pointer prototype in an
+// extension header so that callers have a header file to include
+// with a type that allows a correctly-formed invocation of the
+// extension function.
+//
+// The engine does not perform any validation of calls to
+// extension functions.  Once the extension function pointer
+// is retrieved with GetExtensionFunction all calls go
+// directly between the caller and the extension function and
+// are not mediated by the engine.
+//
+//----------------------------------------------------------------------------
+
+#ifdef __cplusplus
+};
+
+//----------------------------------------------------------------------------
+//
+// Dump stack provider callbacks
+//
+//----------------------------------------------------------------------------
+
+// If a specific dump stream type is present,
+// dbgeng will pass the stream to dump stack
+// provider prior to thread enumeration.
+// Implemented by dump stack provider
+// BeginThreadStackReconstruction
+typedef HRESULT (CALLBACK* PDEBUG_STACK_PROVIDER_BEGINTHREADSTACKRECONSTRUCTION)
+    (
+    _In_ ULONG StreamType,
+    _In_reads_(BufferSize) PVOID MiniDumpStreamBuffer,
+    _In_ ULONG BufferSize); 
+
+// Queries dump stream provider per-thread
+// Stack frames and symbolic data are returned
+// New inline frames may be provided
+// stackdmpprovider must be enabled
+// ReconstructStack
+typedef HRESULT (CALLBACK* PDEBUG_STACK_PROVIDER_RECONSTRUCTSTACK)
+    (
+    _In_ ULONG SystemThreadId,
+    _In_reads_(CountNativeFrames) PDEBUG_STACK_FRAME_EX NativeFrames,
+    _In_ ULONG CountNativeFrames,
+    _Outptr_result_buffer_(*StackSymFramesFilled) PSTACK_SYM_FRAME_INFO *StackSymFrames,
+    _Out_ PULONG StackSymFramesFilled); 
+
+//After ReconstructStack is called and used dbgeng will call the stack provider to free memory
+// FreeStackSymFrames
+typedef HRESULT (CALLBACK* PDEBUG_STACK_PROVIDER_FREESTACKSYMFRAMES)
+    (
+    _In_opt_ PSTACK_SYM_FRAME_INFO StackSymFrames); 
+
+// Dbgeng is done with thread stack reconstruction
+// Dump stack provider may clean up state
+// EndThreadStackReconstruction
+typedef HRESULT (CALLBACK* PDEBUG_STACK_PROVIDER_ENDTHREADSTACKRECONSTRUCTION)
+    (void); 
+
+
+//----------------------------------------------------------------------------
+//
+// C++ implementation helper classes.
+//
+//----------------------------------------------------------------------------
+
+#if !defined(DEBUG_NO_IMPLEMENTATION) && !defined(_M_CEE_PURE)
+
+//
+// DebugBaseEventCallbacks provides a do-nothing base implementation
+// of IDebugEventCallbacks.  A program can derive their own
+// event callbacks class from DebugBaseEventCallbacks and implement
+// only the methods they are interested in.  Programs must be
+// careful to implement GetInterestMask appropriately.
+//
+class DebugBaseEventCallbacks : public IDebugEventCallbacks
+{
+public:
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        )
+    {
+        *Interface = NULL;
+
+#if _MSC_VER >= 1100
+        if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
+            IsEqualIID(InterfaceId, __uuidof(IDebugEventCallbacks)))
+#else
+        if (IsEqualIID(InterfaceId, IID_IUnknown) ||
+            IsEqualIID(InterfaceId, IID_IDebugEventCallbacks))
+#endif
+        {
+            *Interface = (IDebugEventCallbacks *)this;
+            AddRef();
+            return S_OK;
+        }
+        else
+        {
+            return E_NOINTERFACE;
+        }
+    }
+
+    // IDebugEventCallbacks.
+
+    STDMETHOD(Breakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT Bp
+        )
+    {
+        UNREFERENCED_PARAMETER(Bp);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(Exception)(
+        THIS_
+        _In_ PEXCEPTION_RECORD64 Exception,
+        _In_ ULONG FirstChance
+        )
+    {
+        UNREFERENCED_PARAMETER(Exception);
+        UNREFERENCED_PARAMETER(FirstChance);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(CreateThread)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 DataOffset,
+        _In_ ULONG64 StartOffset
+        )
+    {
+        UNREFERENCED_PARAMETER(Handle);
+        UNREFERENCED_PARAMETER(DataOffset);
+        UNREFERENCED_PARAMETER(StartOffset);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(ExitThread)(
+        THIS_
+        _In_ ULONG ExitCode
+        )
+    {
+        UNREFERENCED_PARAMETER(ExitCode);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_ PCSTR ModuleName,
+        _In_ PCSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp,
+        _In_ ULONG64 InitialThreadHandle,
+        _In_ ULONG64 ThreadDataOffset,
+        _In_ ULONG64 StartOffset
+        )
+    {
+        UNREFERENCED_PARAMETER(ImageFileHandle);
+        UNREFERENCED_PARAMETER(Handle);
+        UNREFERENCED_PARAMETER(BaseOffset);
+        UNREFERENCED_PARAMETER(ModuleSize);
+        UNREFERENCED_PARAMETER(ModuleName);
+        UNREFERENCED_PARAMETER(ImageName);
+        UNREFERENCED_PARAMETER(CheckSum);
+        UNREFERENCED_PARAMETER(TimeDateStamp);
+        UNREFERENCED_PARAMETER(InitialThreadHandle);
+        UNREFERENCED_PARAMETER(ThreadDataOffset);
+        UNREFERENCED_PARAMETER(StartOffset);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(ExitProcess)(
+        THIS_
+        _In_ ULONG ExitCode
+        )
+    {
+        UNREFERENCED_PARAMETER(ExitCode);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(LoadModule)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_ PCSTR ModuleName,
+        _In_ PCSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp
+        )
+    {
+        UNREFERENCED_PARAMETER(ImageFileHandle);
+        UNREFERENCED_PARAMETER(BaseOffset);
+        UNREFERENCED_PARAMETER(ModuleSize);
+        UNREFERENCED_PARAMETER(ModuleName);
+        UNREFERENCED_PARAMETER(ImageName);
+        UNREFERENCED_PARAMETER(CheckSum);
+        UNREFERENCED_PARAMETER(TimeDateStamp);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(UnloadModule)(
+        THIS_
+        _In_ PCSTR ImageBaseName,
+        _In_ ULONG64 BaseOffset
+        )
+    {
+        UNREFERENCED_PARAMETER(ImageBaseName);
+        UNREFERENCED_PARAMETER(BaseOffset);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(SystemError)(
+        THIS_
+        _In_ ULONG Error,
+        _In_ ULONG Level
+        )
+    {
+        UNREFERENCED_PARAMETER(Error);
+        UNREFERENCED_PARAMETER(Level);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(SessionStatus)(
+        THIS_
+        _In_ ULONG Status
+        )
+    {
+        UNREFERENCED_PARAMETER(Status);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(ChangeDebuggeeState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        )
+    {
+        UNREFERENCED_PARAMETER(Flags);
+        UNREFERENCED_PARAMETER(Argument);
+        return S_OK;
+    }
+    STDMETHOD(ChangeEngineState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        )
+    {
+        UNREFERENCED_PARAMETER(Flags);
+        UNREFERENCED_PARAMETER(Argument);
+        return S_OK;
+    }
+    STDMETHOD(ChangeSymbolState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        )
+    {
+        UNREFERENCED_PARAMETER(Flags);
+        UNREFERENCED_PARAMETER(Argument);
+        return S_OK;
+    }
+};
+
+class DebugBaseEventCallbacksWide : public IDebugEventCallbacksWide
+{
+public:
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        _In_ REFIID InterfaceId,
+        _Out_ PVOID* Interface
+        )
+    {
+        *Interface = NULL;
+
+#if _MSC_VER >= 1100
+        if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
+            IsEqualIID(InterfaceId, __uuidof(IDebugEventCallbacksWide)))
+#else
+        if (IsEqualIID(InterfaceId, IID_IUnknown) ||
+            IsEqualIID(InterfaceId, IID_IDebugEventCallbacksWide))
+#endif
+        {
+            *Interface = (IDebugEventCallbacksWide *)this;
+            AddRef();
+            return S_OK;
+        }
+        else
+        {
+            return E_NOINTERFACE;
+        }
+    }
+
+    // IDebugEventCallbacksWide.
+
+    STDMETHOD(Breakpoint)(
+        THIS_
+        _In_ PDEBUG_BREAKPOINT2 Bp
+        )
+    {
+        UNREFERENCED_PARAMETER(Bp);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(Exception)(
+        THIS_
+        _In_ PEXCEPTION_RECORD64 Exception,
+        _In_ ULONG FirstChance
+        )
+    {
+        UNREFERENCED_PARAMETER(Exception);
+        UNREFERENCED_PARAMETER(FirstChance);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(CreateThread)(
+        THIS_
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 DataOffset,
+        _In_ ULONG64 StartOffset
+        )
+    {
+        UNREFERENCED_PARAMETER(Handle);
+        UNREFERENCED_PARAMETER(DataOffset);
+        UNREFERENCED_PARAMETER(StartOffset);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(ExitThread)(
+        THIS_
+        _In_ ULONG ExitCode
+        )
+    {
+        UNREFERENCED_PARAMETER(ExitCode);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(CreateProcess)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 Handle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_ PCWSTR ModuleName,
+        _In_ PCWSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp,
+        _In_ ULONG64 InitialThreadHandle,
+        _In_ ULONG64 ThreadDataOffset,
+        _In_ ULONG64 StartOffset
+        )
+    {
+        UNREFERENCED_PARAMETER(ImageFileHandle);
+        UNREFERENCED_PARAMETER(Handle);
+        UNREFERENCED_PARAMETER(BaseOffset);
+        UNREFERENCED_PARAMETER(ModuleSize);
+        UNREFERENCED_PARAMETER(ModuleName);
+        UNREFERENCED_PARAMETER(ImageName);
+        UNREFERENCED_PARAMETER(CheckSum);
+        UNREFERENCED_PARAMETER(TimeDateStamp);
+        UNREFERENCED_PARAMETER(InitialThreadHandle);
+        UNREFERENCED_PARAMETER(ThreadDataOffset);
+        UNREFERENCED_PARAMETER(StartOffset);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(ExitProcess)(
+        THIS_
+        _In_ ULONG ExitCode
+        )
+    {
+        UNREFERENCED_PARAMETER(ExitCode);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(LoadModule)(
+        THIS_
+        _In_ ULONG64 ImageFileHandle,
+        _In_ ULONG64 BaseOffset,
+        _In_ ULONG ModuleSize,
+        _In_ PCWSTR ModuleName,
+        _In_ PCWSTR ImageName,
+        _In_ ULONG CheckSum,
+        _In_ ULONG TimeDateStamp
+        )
+    {
+        UNREFERENCED_PARAMETER(ImageFileHandle);
+        UNREFERENCED_PARAMETER(BaseOffset);
+        UNREFERENCED_PARAMETER(ModuleSize);
+        UNREFERENCED_PARAMETER(ModuleName);
+        UNREFERENCED_PARAMETER(ImageName);
+        UNREFERENCED_PARAMETER(CheckSum);
+        UNREFERENCED_PARAMETER(TimeDateStamp);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(UnloadModule)(
+        THIS_
+        _In_ PCWSTR ImageBaseName,
+        _In_ ULONG64 BaseOffset
+        )
+    {
+        UNREFERENCED_PARAMETER(ImageBaseName);
+        UNREFERENCED_PARAMETER(BaseOffset);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(SystemError)(
+        THIS_
+        _In_ ULONG Error,
+        _In_ ULONG Level
+        )
+    {
+        UNREFERENCED_PARAMETER(Error);
+        UNREFERENCED_PARAMETER(Level);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(SessionStatus)(
+        THIS_
+        _In_ ULONG Status
+        )
+    {
+        UNREFERENCED_PARAMETER(Status);
+        return DEBUG_STATUS_NO_CHANGE;
+    }
+    STDMETHOD(ChangeDebuggeeState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        )
+    {
+        UNREFERENCED_PARAMETER(Flags);
+        UNREFERENCED_PARAMETER(Argument);
+        return S_OK;
+    }
+    STDMETHOD(ChangeEngineState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        )
+    {
+        UNREFERENCED_PARAMETER(Flags);
+        UNREFERENCED_PARAMETER(Argument);
+        return S_OK;
+    }
+    STDMETHOD(ChangeSymbolState)(
+        THIS_
+        _In_ ULONG Flags,
+        _In_ ULONG64 Argument
+        )
+    {
+        UNREFERENCED_PARAMETER(Flags);
+        UNREFERENCED_PARAMETER(Argument);
+        return S_OK;
+    }
+};
+
+#endif // #ifndef DEBUG_NO_IMPLEMENTATION
+
+#ifdef DEBUG_UNICODE_MACROS
+
+#ifdef UNICODE
+
+#define IDebugEventCallbacksT IDebugEventCallbacksWide
+#define IID_IDebugEventCallbacksT IID_IDebugEventCallbacksWide
+#define IDebugOutputCallbacksT IDebugOutputCallbacksWide
+#define IID_IDebugOutputCallbacksT IID_IDebugOutputCallbacksWide
+#define DebugBaseEventCallbacksT DebugBaseEventCallbacksWide
+
+#define DebugConnectT DebugConnectWide
+#define GetSourceFileInformationT GetSourceFileInformationWide
+#define FindSourceFileAndTokenT FindSourceFileAndTokenWide
+#define GetSymbolInformationT GetSymbolInformationWide
+#define GetSymbolInformationExT GetSymbolInformationWideEx
+#define GetCommandT GetCommandWide
+#define SetCommandT SetCommandWide
+#define GetOffsetExpressionT GetOffsetExpressionWide
+#define SetOffsetExpressionT SetOffsetExpressionWide
+#define GetRunningProcessSystemIdByExecutableNameT GetRunningProcessSystemIdByExecutableNameWide
+#define GetRunningProcessDescriptionT GetRunningProcessDescriptionWide
+#define CreateProcessT CreateProcessWide
+#define CreateProcessAndAttachT CreateProcessAndAttachWide
+#define AddDumpInformationFileT AddDumpInformationFileWide
+#define GetDumpFileT GetDumpFileWide
+#define AttachKernelT AttachKernelWide
+#define GetKernelConnectionOptionsT GetKernelConnectionOptionsWide
+#define SetKernelConnectionOptionsT SetKernelConnectionOptionsWide
+#define StartProcessServerT StartProcessServerWide
+#define ConnectProcessServerT ConnectProcessServerWide
+#define StartServerT StartServerWide
+#define OutputServersT OutputServersWide
+#define GetOutputCallbacksT GetOutputCallbacksWide
+#define SetOutputCallbacksT SetOutputCallbacksWide
+#define GetOutputLinePrefixT GetOutputLinePrefixWide
+#define SetOutputLinePrefixT SetOutputLinePrefixWide
+#define GetIdentityT GetIdentityWide
+#define OutputIdentityT OutputIdentityWide
+#define GetEventCallbacksT GetEventCallbacksWide
+#define SetEventCallbacksT SetEventCallbacksWide
+#define CreateProcess2T CreateProcess2Wide
+#define CreateProcessAndAttach2T CreateProcessAndAttach2Wide
+#define PushOutputLinePrefixT PushOutputLinePrefixWide
+#define GetQuitLockStringT GetQuitLockStringWide
+#define SetQuitLockStringT SetQuitLockStringWide
+#define GetLogFileT GetLogFileWide
+#define OpenLogFileT OpenLogFileWide
+#define InputT InputWide
+#define ReturnInputT ReturnInputWide
+#define OutputT OutputWide
+#define OutputVaListT OutputVaListWide
+#define ControlledOutputT ControlledOutputWide
+#define ControlledOutputVaListT ControlledOutputVaListWide
+#define OutputPromptT OutputPromptWide
+#define OutputPromptVaListT OutputPromptVaListWide
+#define GetPromptTextT GetPromptTextWide
+#define AssembleT AssembleWide
+#define DisassembleT DisassembleWide
+#define GetProcessorTypeNamesT GetProcessorTypeNamesWide
+#define GetTextMacroT GetTextMacroWide
+#define SetTextMacroT SetTextMacroWide
+#define EvaluateT EvaluateWide
+#define ExecuteT ExecuteWide
+#define ExecuteCommandFileT ExecuteCommandFileWide
+#define AddExtensionT AddExtensionWide
+#define GetExtensionByPathT GetExtensionByPathWide
+#define CallExtensionT CallExtensionWide
+#define GetExtensionFunctionT GetExtensionFunctionWide
+#define GetEventFilterTextT GetEventFilterTextWide
+#define GetEventFilterCommandT GetEventFilterCommandWide
+#define SetEventFilterCommandT SetEventFilterCommandWide
+#define GetSpecificFilterArgumentT GetSpecificFilterArgumentWide
+#define SetSpecificFilterArgumentT SetSpecificFilterArgumentWide
+#define GetExceptionFilterSecondCommandT GetExceptionFilterSecondCommandWide
+#define SetExceptionFilterSecondCommandT SetExceptionFilterSecondCommandWide
+#define GetLastEventInformationT GetLastEventInformationWide
+#define GetTextReplacementT GetTextReplacementWide
+#define SetTextReplacementT SetTextReplacementWide
+#define SetExpressionSyntaxByNameT SetExpressionSyntaxByNameWide
+#define GetExpressionSyntaxNamesT GetExpressionSyntaxNamesWide
+#define GetEventIndexDescriptionT GetEventIndexDescriptionWide
+#define GetLogFile2T GetLogFile2Wide
+#define OpenLogFile2T OpenLogFile2Wide
+#define GetSystemVersionStringT GetSystemVersionStringWide
+#define ReadMultiByteStringVirtualT ReadMultiByteStringVirtualWide
+#define ReadUnicodeStringVirtualT ReadUnicodeStringVirtualWide
+#define GetDescriptionT GetDescriptionWide
+#define GetIndexByNameT GetIndexByNameWide
+#define GetPseudoDescriptionT GetPseudoDescriptionWide
+#define GetPseudoIndexByNameT GetPseudoIndexByNameWide
+#define AddSymbolT AddSymbolWide
+#define RemoveSymbolByNameT RemoveSymbolByNameWide
+#define GetSymbolNameT GetSymbolNameWide
+#define WriteSymbolT WriteSymbolWide
+#define OutputAsTypeT OutputAsTypeWide
+#define GetSymbolTypeNameT GetSymbolTypeNameWide
+#define GetSymbolValueTextT GetSymbolValueTextWide
+#define GetNameByOffsetT GetNameByOffsetWide
+#define GetNameByInlineContextT GetNameByInlineContextWide
+#define GetOffsetByNameT GetOffsetByNameWide
+#define GetNearNameByOffsetT GetNearNameByOffsetWide
+#define GetLineByOffsetT GetLineByOffsetWide
+#define GetLineByInlineContextT GetLineByInlineContextWide
+#define GetOffsetByLineT GetOffsetByLineWide
+#define GetModuleByModuleNameT GetModuleByModuleNameWide
+#define GetModuleByModuleName2T GetModuleByModuleName2Wide
+#define GetSymbolModuleT GetSymbolModuleWide
+#define GetTypeNameT GetTypeNameWide
+#define GetTypeIdT GetTypeIdWide
+#define GetFieldOffsetT GetFieldOffsetWide
+#define GetSymbolTypeIdT GetSymbolTypeIdWide
+#define StartSymbolMatchT StartSymbolMatchWide
+#define GetNextSymbolMatchT GetNextSymbolMatchWide
+#define ReloadT ReloadWide
+#define GetSymbolPathT GetSymbolPathWide
+#define SetSymbolPathT SetSymbolPathWide
+#define AppendSymbolPathT AppendSymbolPathWide
+#define GetImagePathT GetImagePathWide
+#define SetImagePathT SetImagePathWide
+#define AppendImagePathT AppendImagePathWide
+#define GetSourcePathT GetSourcePathWide
+#define GetSourcePathElementT GetSourcePathElementWide
+#define SetSourcePathT SetSourcePathWide
+#define AppendSourcePathT AppendSourcePathWide
+#define FindSourceFileT FindSourceFileWide
+#define GetSourceFileLineOffsetsT GetSourceFileLineOffsetsWide
+#define GetModuleVersionInformationT GetModuleVersionInformationWide
+#define GetModuleNameStringT GetModuleNameStringWide
+#define GetConstantNameT GetConstantNameWide
+#define GetFieldNameT GetFieldNameWide
+#define GetFieldTypeAndOffsetT GetFieldTypeAndOffsetWide
+#define GetSymbolEntriesByNameT GetSymbolEntriesByNameWide
+#define GetSymbolEntryStringT GetSymbolEntryStringWide
+#define GetSourceEntriesByLineT GetSourceEntriesByLineWide
+#define GetSourceEntryStringT GetSourceEntryStringWide
+#define GetCurrentProcessExecutableNameT GetCurrentProcessExecutableNameWide
+#define GetCurrentSystemServerNameT GetCurrentSystemServerNameWide
+
+#else // #ifdef UNICODE
+
+#define IDebugEventCallbacksT IDebugEventCallbacks
+#define IID_IDebugEventCallbacksT IID_IDebugEventCallbacks
+#define IDebugOutputCallbacksT IDebugOutputCallbacks
+#define IID_IDebugOutputCallbacksT IID_IDebugOutputCallbacks
+#define DebugBaseEventCallbacksT DebugBaseEventCallbacks
+
+#define DebugConnectT DebugConnect
+#define GetSourceFileInformationT GetSourceFileInformation
+#define FindSourceFileAndTokenT FindSourceFileAndToken
+#define GetSymbolInformationT GetSymbolInformation
+#define GetCommandT GetCommand
+#define SetCommandT SetCommand
+#define GetOffsetExpressionT GetOffsetExpression
+#define SetOffsetExpressionT SetOffsetExpression
+#define GetRunningProcessSystemIdByExecutableNameT GetRunningProcessSystemIdByExecutableName
+#define GetRunningProcessDescriptionT GetRunningProcessDescription
+#define CreateProcessT CreateProcess
+#define CreateProcessAndAttachT CreateProcessAndAttach
+#define AddDumpInformationFileT AddDumpInformationFile
+#define GetDumpFileT GetDumpFile
+#define AttachKernelT AttachKernel
+#define GetKernelConnectionOptionsT GetKernelConnectionOptions
+#define SetKernelConnectionOptionsT SetKernelConnectionOptions
+#define StartProcessServerT StartProcessServer
+#define ConnectProcessServerT ConnectProcessServer
+#define StartServerT StartServer
+#define OutputServersT OutputServers
+#define GetOutputCallbacksT GetOutputCallbacks
+#define SetOutputCallbacksT SetOutputCallbacks
+#define GetOutputLinePrefixT GetOutputLinePrefix
+#define SetOutputLinePrefixT SetOutputLinePrefix
+#define GetIdentityT GetIdentity
+#define OutputIdentityT OutputIdentity
+#define GetEventCallbacksT GetEventCallbacks
+#define SetEventCallbacksT SetEventCallbacks
+#define CreateProcess2T CreateProcess2
+#define CreateProcessAndAttach2T CreateProcessAndAttach2
+#define PushOutputLinePrefixT PushOutputLinePrefix
+#define GetQuitLockStringT GetQuitLockString
+#define SetQuitLockStringT SetQuitLockString
+#define GetLogFileT GetLogFile
+#define OpenLogFileT OpenLogFile
+#define InputT Input
+#define ReturnInputT ReturnInput
+#define OutputT Output
+#define OutputVaListT OutputVaList
+#define ControlledOutputT ControlledOutput
+#define ControlledOutputVaListT ControlledOutputVaList
+#define OutputPromptT OutputPrompt
+#define OutputPromptVaListT OutputPromptVaList
+#define GetPromptTextT GetPromptText
+#define AssembleT Assemble
+#define DisassembleT Disassemble
+#define GetProcessorTypeNamesT GetProcessorTypeNames
+#define GetTextMacroT GetTextMacro
+#define SetTextMacroT SetTextMacro
+#define EvaluateT Evaluate
+#define ExecuteT Execute
+#define ExecuteCommandFileT ExecuteCommandFile
+#define AddExtensionT AddExtension
+#define GetExtensionByPathT GetExtensionByPath
+#define CallExtensionT CallExtension
+#define GetExtensionFunctionT GetExtensionFunction
+#define GetEventFilterTextT GetEventFilterText
+#define GetEventFilterCommandT GetEventFilterCommand
+#define SetEventFilterCommandT SetEventFilterCommand
+#define GetSpecificFilterArgumentT GetSpecificFilterArgument
+#define SetSpecificFilterArgumentT SetSpecificFilterArgument
+#define GetExceptionFilterSecondCommandT GetExceptionFilterSecondCommand
+#define SetExceptionFilterSecondCommandT SetExceptionFilterSecondCommand
+#define GetLastEventInformationT GetLastEventInformation
+#define GetTextReplacementT GetTextReplacement
+#define SetTextReplacementT SetTextReplacement
+#define SetExpressionSyntaxByNameT SetExpressionSyntaxByName
+#define GetExpressionSyntaxNamesT GetExpressionSyntaxNames
+#define GetEventIndexDescriptionT GetEventIndexDescription
+#define GetLogFile2T GetLogFile2
+#define OpenLogFile2T OpenLogFile2
+#define GetSystemVersionStringT GetSystemVersionString
+#define ReadMultiByteStringVirtualT ReadMultiByteStringVirtual
+#define ReadUnicodeStringVirtualT ReadUnicodeStringVirtual
+#define GetDescriptionT GetDescription
+#define GetIndexByNameT GetIndexByName
+#define GetPseudoDescriptionT GetPseudoDescription
+#define GetPseudoIndexByNameT GetPseudoIndexByName
+#define AddSymbolT AddSymbol
+#define RemoveSymbolByNameT RemoveSymbolByName
+#define GetSymbolNameT GetSymbolName
+#define WriteSymbolT WriteSymbol
+#define OutputAsTypeT OutputAsType
+#define GetSymbolTypeNameT GetSymbolTypeName
+#define GetSymbolValueTextT GetSymbolValueText
+#define GetNameByOffsetT GetNameByOffset
+#define GetNameByInlineContextT GetNameByInlineContext
+#define GetOffsetByNameT GetOffsetByName
+#define GetNearNameByOffsetT GetNearNameByOffset
+#define GetLineByOffsetT GetLineByOffset
+#define GetLineByInlineContextT GetLineByInlineContext
+#define GetOffsetByLineT GetOffsetByLine
+#define GetModuleByModuleNameT GetModuleByModuleName
+#define GetModuleByModuleName2T GetModuleByModuleName2
+#define GetSymbolModuleT GetSymbolModule
+#define GetTypeNameT GetTypeName
+#define GetTypeIdT GetTypeId
+#define GetFieldOffsetT GetFieldOffset
+#define GetSymbolTypeIdT GetSymbolTypeId
+#define StartSymbolMatchT StartSymbolMatch
+#define GetNextSymbolMatchT GetNextSymbolMatch
+#define ReloadT Reload
+#define GetSymbolPathT GetSymbolPath
+#define SetSymbolPathT SetSymbolPath
+#define AppendSymbolPathT AppendSymbolPath
+#define GetImagePathT GetImagePath
+#define SetImagePathT SetImagePath
+#define AppendImagePathT AppendImagePath
+#define GetSourcePathT GetSourcePath
+#define GetSourcePathElementT GetSourcePathElement
+#define SetSourcePathT SetSourcePath
+#define AppendSourcePathT AppendSourcePath
+#define FindSourceFileT FindSourceFile
+#define GetSourceFileLineOffsetsT GetSourceFileLineOffsets
+#define GetModuleVersionInformationT GetModuleVersionInformation
+#define GetModuleNameStringT GetModuleNameString
+#define GetConstantNameT GetConstantName
+#define GetFieldNameT GetFieldName
+#define GetFieldTypeAndOffsetT GetFieldTypeAndOffset
+#define GetSymbolEntriesByNameT GetSymbolEntriesByName
+#define GetSymbolEntryStringT GetSymbolEntryString
+#define GetSourceEntriesByLineT GetSourceEntriesByLine
+#define GetSourceEntryStringT GetSourceEntryString
+#define GetCurrentProcessExecutableNameT GetCurrentProcessExecutableName
+#define GetCurrentSystemServerNameT GetCurrentSystemServerName
+
+#endif // #ifdef UNICODE
+
+#endif // #ifdef DEBUG_UNICODE_MACROS
+
+#endif // #ifdef __cplusplus
+
+#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PKG_WER) */
+#pragma endregion
+
+#endif // #ifndef __DBGENG_H__
+
diff --git a/src/SOS/inc/dbgeng/dbghelp.h b/src/SOS/inc/dbgeng/dbghelp.h
new file mode 100644 (file)
index 0000000..1334dca
--- /dev/null
@@ -0,0 +1,4185 @@
+/*++ BUILD Version: 0000     Increment this if a change has global effects
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+    dbghelp.h
+
+Abstract:
+
+    This module defines the prototypes and constants required for the image
+    help routines.
+
+    Contains debugging support routines that are redistributable.
+
+Revision History:
+
+--*/
+
+#ifndef _DBGHELP_
+#define _DBGHELP_
+
+#if _MSC_VER > 1020
+#pragma once
+#endif
+
+#include <winapifamily.h>
+
+#define NONGAMESPARTITIONS WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PKG_WER
+
+#pragma region Desktop Family or WER Package
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+
+// As a general principal always call the 64 bit version
+// of every API, if a choice exists.  The 64 bit version
+// works great on 32 bit platforms, and is forward
+// compatible to 64 bit platforms.
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+#ifdef _WIN64
+#ifndef _IMAGEHLP64
+#define _IMAGEHLP64
+#endif
+#endif
+
+#include <pshpack8.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _IMAGEHLP_SOURCE_
+ #define IMAGEAPI __stdcall
+ #define DBHLP_DEPRECIATED
+#else
+ #define IMAGEAPI DECLSPEC_IMPORT __stdcall
+ #if (_MSC_VER >= 1300) && !defined(MIDL_PASS)
+  #define DBHLP_DEPRECIATED   __declspec(deprecated)
+ #else
+  #define DBHLP_DEPRECIATED
+ #endif
+#endif
+
+#define DBHLPAPI IMAGEAPI
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+#define IMAGE_SEPARATION (64*1024)
+
+// Observant readers may notice that 2 new fields,
+// 'fReadOnly' and 'Version' have been added to
+// the LOADED_IMAGE structure after 'fDOSImage'.
+// This does not change the size of the structure
+// from previous headers.  That is because while
+// 'fDOSImage' is a byte, it is padded by the
+// compiler to 4 bytes.  So the 2 new fields are
+// slipped into the extra space.
+
+typedef struct _LOADED_IMAGE {
+    PSTR                  ModuleName;
+    HANDLE                hFile;
+    PUCHAR                MappedAddress;
+#ifdef _IMAGEHLP64
+    PIMAGE_NT_HEADERS64   FileHeader;
+#else
+    PIMAGE_NT_HEADERS32   FileHeader;
+#endif
+    PIMAGE_SECTION_HEADER LastRvaSection;
+    ULONG                 NumberOfSections;
+    PIMAGE_SECTION_HEADER Sections;
+    ULONG                 Characteristics;
+    BOOLEAN               fSystemImage;
+    BOOLEAN               fDOSImage;
+    BOOLEAN               fReadOnly;
+    UCHAR                 Version;
+    LIST_ENTRY            Links;
+    ULONG                 SizeOfImage;
+} LOADED_IMAGE, *PLOADED_IMAGE;
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+#define MAX_SYM_NAME            2000
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+
+// Error codes set by dbghelp functions.  Call GetLastError
+// to see them.
+// Dbghelp also sets error codes found in winerror.h
+
+#define ERROR_IMAGE_NOT_STRIPPED    0x8800  // the image is not stripped.  No dbg file available.
+#define ERROR_NO_DBG_POINTER        0x8801  // image is stripped but there is no pointer to a dbg file
+#define ERROR_NO_PDB_POINTER        0x8802  // image does not point to a pdb file
+
+typedef BOOL
+(CALLBACK *PFIND_DEBUG_FILE_CALLBACK)(
+    _In_ HANDLE FileHandle,
+    _In_ PCSTR FileName,
+    _In_ PVOID CallerData
+    );
+
+HANDLE
+IMAGEAPI
+SymFindDebugInfoFile(
+    _In_ HANDLE hProcess,
+    _In_ PCSTR FileName,
+    _Out_writes_(MAX_PATH + 1) PSTR DebugFilePath,
+    _In_opt_ PFIND_DEBUG_FILE_CALLBACK Callback,
+    _In_opt_ PVOID CallerData
+    );
+
+typedef BOOL
+(CALLBACK *PFIND_DEBUG_FILE_CALLBACKW)(
+    _In_ HANDLE FileHandle,
+    _In_ PCWSTR FileName,
+    _In_ PVOID  CallerData
+    );
+
+HANDLE
+IMAGEAPI
+SymFindDebugInfoFileW(
+    _In_ HANDLE hProcess,
+    _In_ PCWSTR FileName,
+    _Out_writes_(MAX_PATH + 1) PWSTR DebugFilePath,
+    _In_opt_ PFIND_DEBUG_FILE_CALLBACKW Callback,
+    _In_opt_ PVOID CallerData
+    );
+
+HANDLE
+IMAGEAPI
+FindDebugInfoFile (
+    _In_ PCSTR FileName,
+    _In_ PCSTR SymbolPath,
+    _Out_writes_(MAX_PATH + 1) PSTR DebugFilePath
+    );
+
+HANDLE
+IMAGEAPI
+FindDebugInfoFileEx (
+    _In_ PCSTR FileName,
+    _In_ PCSTR SymbolPath,
+    _Out_writes_(MAX_PATH + 1) PSTR  DebugFilePath,
+    _In_opt_ PFIND_DEBUG_FILE_CALLBACK Callback,
+    _In_opt_ PVOID CallerData
+    );
+
+HANDLE
+IMAGEAPI
+FindDebugInfoFileExW (
+    _In_ PCWSTR FileName,
+    _In_ PCWSTR SymbolPath,
+    _Out_writes_(MAX_PATH + 1) PWSTR DebugFilePath,
+    _In_opt_ PFIND_DEBUG_FILE_CALLBACKW Callback,
+    _In_opt_ PVOID CallerData
+    );
+
+typedef BOOL
+(CALLBACK *PFINDFILEINPATHCALLBACK)(
+    _In_ PCSTR filename,
+    _In_ PVOID context
+    );
+
+BOOL
+IMAGEAPI
+SymFindFileInPath(
+    _In_ HANDLE hprocess,
+    _In_opt_ PCSTR SearchPath,
+    _In_ PCSTR FileName,
+    _In_opt_ PVOID id,
+    _In_ DWORD two,
+    _In_ DWORD three,
+    _In_ DWORD flags,
+    _Out_writes_(MAX_PATH + 1) PSTR FoundFile,
+    _In_opt_ PFINDFILEINPATHCALLBACK callback,
+    _In_opt_ PVOID context
+    );
+
+typedef BOOL
+(CALLBACK *PFINDFILEINPATHCALLBACKW)(
+    _In_ PCWSTR filename,
+    _In_ PVOID context
+    );
+
+BOOL
+IMAGEAPI
+SymFindFileInPathW(
+    _In_ HANDLE hprocess,
+    _In_opt_ PCWSTR SearchPath,
+    _In_ PCWSTR FileName,
+    _In_opt_ PVOID id,
+    _In_ DWORD two,
+    _In_ DWORD three,
+    _In_ DWORD flags,
+    _Out_writes_(MAX_PATH + 1) PWSTR FoundFile,
+    _In_opt_ PFINDFILEINPATHCALLBACKW callback,
+    _In_opt_ PVOID context
+    );
+
+typedef BOOL
+(CALLBACK *PFIND_EXE_FILE_CALLBACK)(
+    _In_ HANDLE FileHandle,
+    _In_ PCSTR FileName,
+    _In_opt_ PVOID CallerData
+    );
+
+HANDLE
+IMAGEAPI
+SymFindExecutableImage(
+    _In_ HANDLE hProcess,
+    _In_ PCSTR FileName,
+    _Out_writes_(MAX_PATH + 1) PSTR ImageFilePath,
+    _In_ PFIND_EXE_FILE_CALLBACK Callback,
+    _In_ PVOID CallerData
+    );
+
+typedef BOOL
+(CALLBACK *PFIND_EXE_FILE_CALLBACKW)(
+    _In_ HANDLE FileHandle,
+    _In_ PCWSTR FileName,
+    _In_opt_ PVOID CallerData
+    );
+
+HANDLE
+IMAGEAPI
+SymFindExecutableImageW(
+    _In_ HANDLE hProcess,
+    _In_ PCWSTR FileName,
+    _Out_writes_(MAX_PATH + 1) PWSTR ImageFilePath,
+    _In_ PFIND_EXE_FILE_CALLBACKW Callback,
+    _In_ PVOID CallerData
+    );
+
+HANDLE
+IMAGEAPI
+FindExecutableImage(
+    _In_ PCSTR FileName,
+    _In_ PCSTR SymbolPath,
+    _Out_writes_(MAX_PATH + 1) PSTR ImageFilePath
+    );
+
+HANDLE
+IMAGEAPI
+FindExecutableImageEx(
+    _In_ PCSTR FileName,
+    _In_ PCSTR SymbolPath,
+    _Out_writes_(MAX_PATH + 1) PSTR ImageFilePath,
+    _In_opt_ PFIND_EXE_FILE_CALLBACK Callback,
+    _In_opt_ PVOID CallerData
+    );
+
+HANDLE
+IMAGEAPI
+FindExecutableImageExW(
+    _In_ PCWSTR FileName,
+    _In_ PCWSTR SymbolPath,
+    _Out_writes_(MAX_PATH + 1) PWSTR ImageFilePath,
+    _In_opt_ PFIND_EXE_FILE_CALLBACKW Callback,
+    _In_ PVOID CallerData
+    );
+
+PIMAGE_NT_HEADERS
+IMAGEAPI
+ImageNtHeader (
+    _In_ PVOID Base
+    );
+
+PVOID
+IMAGEAPI
+ImageDirectoryEntryToDataEx (
+    _In_ PVOID Base,
+    _In_ BOOLEAN MappedAsImage,
+    _In_ USHORT DirectoryEntry,
+    _Out_ PULONG Size,
+    _Out_opt_ PIMAGE_SECTION_HEADER *FoundHeader
+    );
+
+PVOID
+IMAGEAPI
+ImageDirectoryEntryToData (
+    _In_ PVOID Base,
+    _In_ BOOLEAN MappedAsImage,
+    _In_ USHORT DirectoryEntry,
+    _Out_ PULONG Size
+    );
+
+PIMAGE_SECTION_HEADER
+IMAGEAPI
+ImageRvaToSection(
+    _In_ PIMAGE_NT_HEADERS NtHeaders,
+    _In_ PVOID Base,
+    _In_ ULONG Rva
+    );
+
+PVOID
+IMAGEAPI
+ImageRvaToVa(
+    _In_ PIMAGE_NT_HEADERS NtHeaders,
+    _In_ PVOID Base,
+    _In_ ULONG Rva,
+    _In_opt_ OUT PIMAGE_SECTION_HEADER *LastRvaSection
+    );
+
+#ifndef _WIN64
+// This api won't be ported to Win64 - Fix your code.
+
+typedef struct _IMAGE_DEBUG_INFORMATION {
+    LIST_ENTRY List;
+    DWORD ReservedSize;
+    PVOID ReservedMappedBase;
+    USHORT ReservedMachine;
+    USHORT ReservedCharacteristics;
+    DWORD ReservedCheckSum;
+    DWORD ImageBase;
+    DWORD SizeOfImage;
+
+    DWORD ReservedNumberOfSections;
+    PIMAGE_SECTION_HEADER ReservedSections;
+
+    DWORD ReservedExportedNamesSize;
+    PSTR ReservedExportedNames;
+
+    DWORD ReservedNumberOfFunctionTableEntries;
+    PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries;
+    DWORD ReservedLowestFunctionStartingAddress;
+    DWORD ReservedHighestFunctionEndingAddress;
+
+    DWORD ReservedNumberOfFpoTableEntries;
+    PFPO_DATA ReservedFpoTableEntries;
+
+    DWORD SizeOfCoffSymbols;
+    PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols;
+
+    DWORD ReservedSizeOfCodeViewSymbols;
+    PVOID ReservedCodeViewSymbols;
+
+    PSTR ImageFilePath;
+    PSTR ImageFileName;
+    PSTR ReservedDebugFilePath;
+
+    DWORD ReservedTimeDateStamp;
+
+    BOOL  ReservedRomImage;
+    PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory;
+    DWORD ReservedNumberOfDebugDirectories;
+
+    DWORD ReservedOriginalFunctionTableBaseAddress;
+
+    DWORD Reserved[ 2 ];
+
+} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION;
+
+
+PIMAGE_DEBUG_INFORMATION
+IMAGEAPI
+MapDebugInformation(
+    _In_opt_ HANDLE FileHandle,
+    _In_ PCSTR FileName,
+    _In_opt_ PCSTR SymbolPath,
+    _In_ ULONG ImageBase
+    );
+
+BOOL
+IMAGEAPI
+UnmapDebugInformation(
+    _Out_writes_(_Inexpressible_(unknown)) PIMAGE_DEBUG_INFORMATION DebugInfo
+    );
+
+#endif
+
+BOOL
+IMAGEAPI
+SearchTreeForFile(
+    _In_ PCSTR RootPath,
+    _In_ PCSTR InputPathName,
+    _Out_writes_(MAX_PATH + 1) PSTR OutputPathBuffer
+    );
+
+BOOL
+IMAGEAPI
+SearchTreeForFileW(
+    _In_ PCWSTR RootPath,
+    _In_ PCWSTR InputPathName,
+    _Out_writes_(MAX_PATH + 1) PWSTR OutputPathBuffer
+    );
+
+typedef BOOL
+(CALLBACK *PENUMDIRTREE_CALLBACK)(
+    _In_ PCSTR FilePath,
+    _In_opt_ PVOID CallerData
+    );
+
+BOOL
+IMAGEAPI
+EnumDirTree(
+    _In_opt_ HANDLE hProcess,
+    _In_ PCSTR RootPath,
+    _In_ PCSTR InputPathName,
+    _Out_writes_opt_(MAX_PATH + 1) PSTR OutputPathBuffer,
+    _In_opt_ PENUMDIRTREE_CALLBACK cb,
+    _In_opt_ PVOID data
+    );
+
+typedef BOOL
+(CALLBACK *PENUMDIRTREE_CALLBACKW)(
+    _In_ PCWSTR FilePath,
+    _In_opt_ PVOID CallerData
+    );
+
+BOOL
+IMAGEAPI
+EnumDirTreeW(
+    _In_opt_ HANDLE hProcess,
+    _In_ PCWSTR RootPath,
+    _In_ PCWSTR InputPathName,
+    _Out_writes_opt_(MAX_PATH + 1) PWSTR OutputPathBuffer,
+    _In_opt_ PENUMDIRTREE_CALLBACKW cb,
+    _In_opt_ PVOID data
+    );
+
+BOOL
+IMAGEAPI
+MakeSureDirectoryPathExists(
+    _In_ PCSTR DirPath
+    );
+
+//
+// UnDecorateSymbolName Flags
+//
+
+#define UNDNAME_COMPLETE                 (0x0000)  // Enable full undecoration
+#define UNDNAME_NO_LEADING_UNDERSCORES   (0x0001)  // Remove leading underscores from MS extended keywords
+#define UNDNAME_NO_MS_KEYWORDS           (0x0002)  // Disable expansion of MS extended keywords
+#define UNDNAME_NO_FUNCTION_RETURNS      (0x0004)  // Disable expansion of return type for primary declaration
+#define UNDNAME_NO_ALLOCATION_MODEL      (0x0008)  // Disable expansion of the declaration model
+#define UNDNAME_NO_ALLOCATION_LANGUAGE   (0x0010)  // Disable expansion of the declaration language specifier
+#define UNDNAME_NO_MS_THISTYPE           (0x0020)  // NYI Disable expansion of MS keywords on the 'this' type for primary declaration
+#define UNDNAME_NO_CV_THISTYPE           (0x0040)  // NYI Disable expansion of CV modifiers on the 'this' type for primary declaration
+#define UNDNAME_NO_THISTYPE              (0x0060)  // Disable all modifiers on the 'this' type
+#define UNDNAME_NO_ACCESS_SPECIFIERS     (0x0080)  // Disable expansion of access specifiers for members
+#define UNDNAME_NO_THROW_SIGNATURES      (0x0100)  // Disable expansion of 'throw-signatures' for functions and pointers to functions
+#define UNDNAME_NO_MEMBER_TYPE           (0x0200)  // Disable expansion of 'static' or 'virtual'ness of members
+#define UNDNAME_NO_RETURN_UDT_MODEL      (0x0400)  // Disable expansion of MS model for UDT returns
+#define UNDNAME_32_BIT_DECODE            (0x0800)  // Undecorate 32-bit decorated names
+#define UNDNAME_NAME_ONLY                (0x1000)  // Crack only the name for primary declaration;
+                                                                                                   //  return just [scope::]name.  Does expand template params
+#define UNDNAME_NO_ARGUMENTS             (0x2000)  // Don't undecorate arguments to function
+#define UNDNAME_NO_SPECIAL_SYMS          (0x4000)  // Don't undecorate special names (v-table, vcall, vector xxx, metatype, etc)
+
+DWORD
+IMAGEAPI
+WINAPI
+UnDecorateSymbolName(
+    _In_ PCSTR name,
+    _Out_writes_(maxStringLength) PSTR outputString,
+    _In_ DWORD maxStringLength,
+    _In_ DWORD flags
+    );
+
+DWORD
+IMAGEAPI
+WINAPI
+UnDecorateSymbolNameW(
+    _In_ PCWSTR name,
+    _Out_writes_(maxStringLength) PWSTR outputString,
+    _In_ DWORD maxStringLength,
+    _In_ DWORD flags
+    );
+
+//
+// these values are used for synthesized file types
+// that can be passed in as image headers instead of
+// the standard ones from ntimage.h
+//
+
+#define DBHHEADER_DEBUGDIRS     0x1
+#define DBHHEADER_CVMISC        0x2
+#define DBHHEADER_PDBGUID       0x3
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+typedef struct _MODLOAD_DATA {
+    DWORD   ssize;                  // size of this struct
+    DWORD   ssig;                   // signature identifying the passed data
+    PVOID   data;                   // pointer to passed data
+    DWORD   size;                   // size of passed data
+    DWORD   flags;                  // options
+} MODLOAD_DATA, *PMODLOAD_DATA;
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+typedef struct _MODLOAD_CVMISC {
+    DWORD   oCV;                    // ofset to the codeview record
+    size_t  cCV;                    // size of the codeview record
+    DWORD   oMisc;                  // offset to the misc record
+    size_t  cMisc;                  // size of the misc record
+    DWORD   dtImage;                // datetime stamp of the image
+    DWORD   cImage;                 // size of the image
+} MODLOAD_CVMISC, *PMODLOAD_CVMISC;
+
+typedef struct _MODLOAD_PDBGUID_PDBAGE {
+    GUID    PdbGuid;                // Pdb Guid
+    DWORD   PdbAge;                 // Pdb Age
+} MODLOAD_PDBGUID_PDBAGE, *PMODLOAD_PDBGUID_PDBAGE;
+
+//
+// StackWalking API
+//
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+typedef enum {
+    AddrMode1616,
+    AddrMode1632,
+    AddrModeReal,
+    AddrModeFlat
+} ADDRESS_MODE;
+
+typedef struct _tagADDRESS64 {
+    DWORD64       Offset;
+    WORD          Segment;
+    ADDRESS_MODE  Mode;
+} ADDRESS64, *LPADDRESS64;
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define ADDRESS ADDRESS64
+#define LPADDRESS LPADDRESS64
+#else
+typedef struct _tagADDRESS {
+    DWORD         Offset;
+    WORD          Segment;
+    ADDRESS_MODE  Mode;
+} ADDRESS, *LPADDRESS;
+
+__inline
+void
+Address32To64(
+    _In_ LPADDRESS a32,
+    _Out_ LPADDRESS64 a64
+    )
+{
+    a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset;
+    a64->Segment = a32->Segment;
+    a64->Mode = a32->Mode;
+}
+
+__inline
+void
+Address64To32(
+    _In_ LPADDRESS64 a64,
+    _Out_ LPADDRESS a32
+    )
+{
+    a32->Offset = (ULONG)a64->Offset;
+    a32->Segment = a64->Segment;
+    a32->Mode = a64->Mode;
+}
+#endif
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+//
+// This structure is included in the STACKFRAME structure,
+// and is used to trace through usermode callbacks in a thread's
+// kernel stack.  The values must be copied by the kernel debugger
+// from the DBGKD_GET_VERSION and WAIT_STATE_CHANGE packets.
+//
+
+//
+// New KDHELP structure for 64 bit system support.
+// This structure is preferred in new code.
+//
+typedef struct _KDHELP64 {
+
+    //
+    // address of kernel thread object, as provided in the
+    // WAIT_STATE_CHANGE packet.
+    //
+    DWORD64   Thread;
+
+    //
+    // offset in thread object to pointer to the current callback frame
+    // in kernel stack.
+    //
+    DWORD   ThCallbackStack;
+
+    //
+    // offset in thread object to pointer to the current callback backing
+    // store frame in kernel stack.
+    //
+    DWORD   ThCallbackBStore;
+
+    //
+    // offsets to values in frame:
+    //
+    // address of next callback frame
+    DWORD   NextCallback;
+
+    // address of saved frame pointer (if applicable)
+    DWORD   FramePointer;
+
+
+    //
+    // Address of the kernel function that calls out to user mode
+    //
+    DWORD64   KiCallUserMode;
+
+    //
+    // Address of the user mode dispatcher function
+    //
+    DWORD64   KeUserCallbackDispatcher;
+
+    //
+    // Lowest kernel mode address
+    //
+    DWORD64   SystemRangeStart;
+
+    //
+    // Address of the user mode exception dispatcher function.
+    // Added in API version 10.
+    //
+    DWORD64   KiUserExceptionDispatcher;
+
+    //
+    // Stack bounds, added in API version 11.
+    //
+    DWORD64   StackBase;
+    DWORD64   StackLimit;
+
+    //
+    // Target OS build number. Added in API version 12.
+    //
+    DWORD     BuildVersion;
+    DWORD     RetpolineStubFunctionTableSize;
+    DWORD64   RetpolineStubFunctionTable;
+    DWORD     RetpolineStubOffset;
+    DWORD     RetpolineStubSize;
+    DWORD64   Reserved0[2];
+
+} KDHELP64, *PKDHELP64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define KDHELP KDHELP64
+#define PKDHELP PKDHELP64
+#else
+typedef struct _KDHELP {
+
+    //
+    // address of kernel thread object, as provided in the
+    // WAIT_STATE_CHANGE packet.
+    //
+    DWORD   Thread;
+
+    //
+    // offset in thread object to pointer to the current callback frame
+    // in kernel stack.
+    //
+    DWORD   ThCallbackStack;
+
+    //
+    // offsets to values in frame:
+    //
+    // address of next callback frame
+    DWORD   NextCallback;
+
+    // address of saved frame pointer (if applicable)
+    DWORD   FramePointer;
+
+    //
+    // Address of the kernel function that calls out to user mode
+    //
+    DWORD   KiCallUserMode;
+
+    //
+    // Address of the user mode dispatcher function
+    //
+    DWORD   KeUserCallbackDispatcher;
+
+    //
+    // Lowest kernel mode address
+    //
+    DWORD   SystemRangeStart;
+
+    //
+    // offset in thread object to pointer to the current callback backing
+    // store frame in kernel stack.
+    //
+    DWORD   ThCallbackBStore;
+
+    //
+    // Address of the user mode exception dispatcher function.
+    // Added in API version 10.
+    //
+    DWORD   KiUserExceptionDispatcher;
+
+    //
+    // Stack bounds, added in API version 11.
+    //
+    DWORD   StackBase;
+    DWORD   StackLimit;
+
+    DWORD   Reserved[5];
+
+} KDHELP, *PKDHELP;
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+__inline
+void
+KdHelp32To64(
+    _In_ PKDHELP p32,
+    _Out_ PKDHELP64 p64
+    )
+{
+    p64->Thread = p32->Thread;
+    p64->ThCallbackStack = p32->ThCallbackStack;
+    p64->NextCallback = p32->NextCallback;
+    p64->FramePointer = p32->FramePointer;
+    p64->KiCallUserMode = p32->KiCallUserMode;
+    p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher;
+    p64->SystemRangeStart = p32->SystemRangeStart;
+    p64->KiUserExceptionDispatcher = p32->KiUserExceptionDispatcher;
+    p64->StackBase = p32->StackBase;
+    p64->StackLimit = p32->StackLimit;
+}
+#endif
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+typedef struct _tagSTACKFRAME64 {
+    ADDRESS64   AddrPC;               // program counter
+    ADDRESS64   AddrReturn;           // return address
+    ADDRESS64   AddrFrame;            // frame pointer
+    ADDRESS64   AddrStack;            // stack pointer
+    ADDRESS64   AddrBStore;           // backing store pointer
+    PVOID       FuncTableEntry;       // pointer to pdata/fpo or NULL
+    DWORD64     Params[4];            // possible arguments to the function
+    BOOL        Far;                  // WOW far call
+    BOOL        Virtual;              // is this a virtual frame?
+    DWORD64     Reserved[3];
+    KDHELP64    KdHelp;
+} STACKFRAME64, *LPSTACKFRAME64;
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+#define INLINE_FRAME_CONTEXT_INIT   0
+#define INLINE_FRAME_CONTEXT_IGNORE 0xFFFFFFFF
+
+typedef struct _tagSTACKFRAME_EX {
+    // First, STACKFRAME64 structure
+    ADDRESS64   AddrPC;            // program counter
+    ADDRESS64   AddrReturn;        // return address
+    ADDRESS64   AddrFrame;         // frame pointer
+    ADDRESS64   AddrStack;         // stack pointer
+    ADDRESS64   AddrBStore;        // backing store pointer
+    PVOID       FuncTableEntry;    // pointer to pdata/fpo or NULL
+    DWORD64     Params[4];         // possible arguments to the function
+    BOOL        Far;               // WOW far call
+    BOOL        Virtual;           // is this a virtual frame?
+    DWORD64     Reserved[3];
+    KDHELP64    KdHelp;
+
+    // Extended STACKFRAME fields
+    DWORD       StackFrameSize;
+    DWORD       InlineFrameContext;
+} STACKFRAME_EX, *LPSTACKFRAME_EX;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define STACKFRAME STACKFRAME64
+#define LPSTACKFRAME LPSTACKFRAME64
+#else
+typedef struct _tagSTACKFRAME {
+    ADDRESS     AddrPC;               // program counter
+    ADDRESS     AddrReturn;           // return address
+    ADDRESS     AddrFrame;            // frame pointer
+    ADDRESS     AddrStack;            // stack pointer
+    PVOID       FuncTableEntry;       // pointer to pdata/fpo or NULL
+    DWORD       Params[4];            // possible arguments to the function
+    BOOL        Far;                  // WOW far call
+    BOOL        Virtual;              // is this a virtual frame?
+    DWORD       Reserved[3];
+    KDHELP      KdHelp;
+    ADDRESS     AddrBStore;           // backing store pointer
+} STACKFRAME, *LPSTACKFRAME;
+#endif
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+typedef
+BOOL
+(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 qwBaseAddress,
+    _Out_writes_bytes_(nSize) PVOID lpBuffer,
+    _In_ DWORD nSize,
+    _Out_ LPDWORD lpNumberOfBytesRead
+    );
+
+typedef
+PVOID
+(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)(
+    _In_ HANDLE ahProcess,
+    _In_ DWORD64 AddrBase
+    );
+
+typedef
+DWORD64
+(__stdcall *PGET_MODULE_BASE_ROUTINE64)(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address
+    );
+
+typedef
+DWORD64
+(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(
+    _In_ HANDLE hProcess,
+    _In_ HANDLE hThread,
+    _In_ LPADDRESS64 lpaddr
+    );
+
+BOOL
+IMAGEAPI
+StackWalk64(
+    _In_ DWORD MachineType,
+    _In_ HANDLE hProcess,
+    _In_ HANDLE hThread,
+    _Inout_ LPSTACKFRAME64 StackFrame,
+    _Inout_ PVOID ContextRecord,
+    _In_opt_ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
+    _In_opt_ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
+    _In_opt_ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
+    _In_opt_ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+#define SYM_STKWALK_DEFAULT        0x00000000
+#define SYM_STKWALK_FORCE_FRAMEPTR 0x00000001
+BOOL
+IMAGEAPI
+StackWalkEx(
+    _In_ DWORD MachineType,
+    _In_ HANDLE hProcess,
+    _In_ HANDLE hThread,
+    _Inout_ LPSTACKFRAME_EX StackFrame,
+    _Inout_ PVOID ContextRecord,
+    _In_opt_ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
+    _In_opt_ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
+    _In_opt_ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
+    _In_opt_ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress,
+    _In_ DWORD Flags
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+
+#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64
+#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64
+#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64
+#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64
+
+#define StackWalk StackWalk64
+
+#else
+
+typedef
+BOOL
+(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE)(
+    _In_ HANDLE hProcess,
+    _In_ DWORD lpBaseAddress,
+    _Out_writes_bytes_(nSize) PVOID lpBuffer,
+    _In_ DWORD nSize,
+    _Out_ PDWORD lpNumberOfBytesRead
+    );
+
+typedef
+PVOID
+(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE)(
+    _In_ HANDLE hProcess,
+    _In_ DWORD AddrBase
+    );
+
+typedef
+DWORD
+(__stdcall *PGET_MODULE_BASE_ROUTINE)(
+    _In_ HANDLE hProcess,
+    _In_ DWORD Address
+    );
+
+typedef
+DWORD
+(__stdcall *PTRANSLATE_ADDRESS_ROUTINE)(
+    _In_ HANDLE hProcess,
+    _In_ HANDLE hThread,
+    _Out_ LPADDRESS lpaddr
+    );
+
+BOOL
+IMAGEAPI
+StackWalk(
+    DWORD MachineType,
+    _In_ HANDLE hProcess,
+    _In_ HANDLE hThread,
+    _Inout_ LPSTACKFRAME StackFrame,
+    _Inout_ PVOID ContextRecord,
+    _In_opt_ PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
+    _In_opt_ PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
+    _In_opt_ PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
+    _In_opt_ PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
+    );
+
+#endif
+
+
+#define API_VERSION_NUMBER 12
+
+typedef struct API_VERSION {
+    USHORT  MajorVersion;
+    USHORT  MinorVersion;
+    USHORT  Revision;
+    USHORT  Reserved;
+} API_VERSION, *LPAPI_VERSION;
+
+LPAPI_VERSION
+IMAGEAPI
+ImagehlpApiVersion(
+    VOID
+    );
+
+LPAPI_VERSION
+IMAGEAPI
+ImagehlpApiVersionEx(
+    _In_ LPAPI_VERSION AppVersion
+    );
+
+DWORD
+IMAGEAPI
+GetTimestampForLoadedLibrary(
+    _In_ HMODULE Module
+    );
+
+//
+// typedefs for function pointers
+//
+typedef BOOL
+(CALLBACK *PSYM_ENUMMODULES_CALLBACK64)(
+    _In_ PCSTR ModuleName,
+    _In_ DWORD64 BaseOfDll,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMMODULES_CALLBACKW64)(
+    _In_ PCWSTR ModuleName,
+    _In_ DWORD64 BaseOfDll,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PENUMLOADED_MODULES_CALLBACK64)(
+    _In_ PCSTR ModuleName,
+    _In_ DWORD64 ModuleBase,
+    _In_ ULONG ModuleSize,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PENUMLOADED_MODULES_CALLBACKW64)(
+    _In_ PCWSTR ModuleName,
+    _In_ DWORD64 ModuleBase,
+    _In_ ULONG ModuleSize,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64)(
+    _In_ PCSTR SymbolName,
+    _In_ DWORD64 SymbolAddress,
+    _In_ ULONG SymbolSize,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64W)(
+    _In_ PCWSTR SymbolName,
+    _In_ DWORD64 SymbolAddress,
+    _In_ ULONG SymbolSize,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PSYMBOL_REGISTERED_CALLBACK64)(
+    _In_ HANDLE hProcess,
+    _In_ ULONG ActionCode,
+    _In_opt_ ULONG64 CallbackData,
+    _In_opt_ ULONG64 UserContext
+    );
+
+typedef
+PVOID
+(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)(
+    _In_ HANDLE hProcess,
+    _In_ DWORD AddrBase,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef
+PVOID
+(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 AddrBase,
+    _In_ ULONG64 UserContext
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+
+#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64
+#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64
+#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W
+#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64
+#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64
+#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64
+
+#else
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMMODULES_CALLBACK)(
+    _In_ PCSTR ModuleName,
+    _In_ ULONG BaseOfDll,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK)(
+    _In_ PCSTR SymbolName,
+    _In_ ULONG SymbolAddress,
+    _In_ ULONG SymbolSize,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACKW)(
+    _In_ PCWSTR SymbolName,
+    _In_ ULONG SymbolAddress,
+    _In_ ULONG SymbolSize,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PENUMLOADED_MODULES_CALLBACK)(
+    _In_ PCSTR ModuleName,
+    _In_ ULONG ModuleBase,
+    _In_ ULONG ModuleSize,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PSYMBOL_REGISTERED_CALLBACK)(
+    _In_ HANDLE hProcess,
+    _In_ ULONG ActionCode,
+    _In_opt_ PVOID CallbackData,
+    _In_opt_ PVOID UserContext
+    );
+
+#endif
+
+
+// values found in SYMBOL_INFO.Tag
+//
+// This was taken from cvconst.h and should
+// not override any values found there.
+//
+// #define _NO_CVCONST_H_ if you don't
+// have access to that file...
+
+#ifdef _NO_CVCONST_H
+
+// DIA enums
+
+enum SymTagEnum
+{
+    SymTagNull,
+    SymTagExe,
+    SymTagCompiland,
+    SymTagCompilandDetails,
+    SymTagCompilandEnv,
+    SymTagFunction,
+    SymTagBlock,
+    SymTagData,
+    SymTagAnnotation,
+    SymTagLabel,
+    SymTagPublicSymbol,
+    SymTagUDT,
+    SymTagEnum,
+    SymTagFunctionType,
+    SymTagPointerType,
+    SymTagArrayType,
+    SymTagBaseType,
+    SymTagTypedef,
+    SymTagBaseClass,
+    SymTagFriend,
+    SymTagFunctionArgType,
+    SymTagFuncDebugStart,
+    SymTagFuncDebugEnd,
+    SymTagUsingNamespace,
+    SymTagVTableShape,
+    SymTagVTable,
+    SymTagCustom,
+    SymTagThunk,
+    SymTagCustomType,
+    SymTagManagedType,
+    SymTagDimension,
+    SymTagCallSite,
+    SymTagInlineSite,
+    SymTagBaseInterface,
+    SymTagVectorType,
+    SymTagMatrixType,
+    SymTagHLSLType,
+    SymTagCaller,
+    SymTagCallee,
+    SymTagExport,
+    SymTagHeapAllocationSite,
+    SymTagCoffGroup,
+    SymTagMax
+};
+
+#endif
+
+//
+// flags found in SYMBOL_INFO.Flags
+//
+
+#define SYMFLAG_VALUEPRESENT        0x00000001
+#define SYMFLAG_REGISTER            0x00000008
+#define SYMFLAG_REGREL              0x00000010
+#define SYMFLAG_FRAMEREL            0x00000020
+#define SYMFLAG_PARAMETER           0x00000040
+#define SYMFLAG_LOCAL               0x00000080
+#define SYMFLAG_CONSTANT            0x00000100
+#define SYMFLAG_EXPORT              0x00000200
+#define SYMFLAG_FORWARDER           0x00000400
+#define SYMFLAG_FUNCTION            0x00000800
+#define SYMFLAG_VIRTUAL             0x00001000
+#define SYMFLAG_THUNK               0x00002000
+#define SYMFLAG_TLSREL              0x00004000
+#define SYMFLAG_SLOT                0x00008000
+#define SYMFLAG_ILREL               0x00010000
+#define SYMFLAG_METADATA            0x00020000
+#define SYMFLAG_CLR_TOKEN           0x00040000
+#define SYMFLAG_NULL                0x00080000
+#define SYMFLAG_FUNC_NO_RETURN      0x00100000
+#define SYMFLAG_SYNTHETIC_ZEROBASE  0x00200000
+#define SYMFLAG_PUBLIC_CODE         0x00400000
+#define SYMFLAG_REGREL_ALIASINDIR   0x00800000
+
+// this resets SymNext/Prev to the beginning
+// of the module passed in the address field
+
+#define SYMFLAG_RESET            0x80000000
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+//
+// symbol type enumeration
+//
+typedef enum {
+    SymNone = 0,
+    SymCoff,
+    SymCv,
+    SymPdb,
+    SymExport,
+    SymDeferred,
+    SymSym,       // .sym file
+    SymDia,
+    SymVirtual,
+    NumSymTypes
+} SYM_TYPE;
+
+//
+// symbol data structure
+//
+
+typedef struct _IMAGEHLP_SYMBOL64 {
+    DWORD   SizeOfStruct;           // set to sizeof(IMAGEHLP_SYMBOL64)
+    DWORD64 Address;                // virtual address including dll base address
+    DWORD   Size;                   // estimated size of symbol, can be zero
+    DWORD   Flags;                  // info about the symbols, see the SYMF defines
+    DWORD   MaxNameLength;          // maximum size of symbol name in 'Name'
+    CHAR    Name[1];                // symbol name (null terminated string)
+} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
+
+typedef struct _IMAGEHLP_SYMBOL64_PACKAGE {
+    IMAGEHLP_SYMBOL64 sym;
+    CHAR              name[MAX_SYM_NAME + 1];
+} IMAGEHLP_SYMBOL64_PACKAGE, *PIMAGEHLP_SYMBOL64_PACKAGE;
+
+typedef struct _IMAGEHLP_SYMBOLW64 {
+    DWORD   SizeOfStruct;           // set to sizeof(IMAGEHLP_SYMBOLW64)
+    DWORD64 Address;                // virtual address including dll base address
+    DWORD   Size;                   // estimated size of symbol, can be zero
+    DWORD   Flags;                  // info about the symbols, see the SYMF defines
+    DWORD   MaxNameLength;          // maximum size of symbol name in 'Name'
+    WCHAR   Name[1];                // symbol name (null terminated string)
+} IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64;
+
+typedef struct _IMAGEHLP_SYMBOLW64_PACKAGE {
+    IMAGEHLP_SYMBOLW64 sym;
+    WCHAR              name[MAX_SYM_NAME + 1];
+} IMAGEHLP_SYMBOLW64_PACKAGE, *PIMAGEHLP_SYMBOLW64_PACKAGE;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+
+ #define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64
+ #define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64
+ #define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE
+ #define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE
+ #define IMAGEHLP_SYMBOLW IMAGEHLP_SYMBOLW64
+ #define PIMAGEHLP_SYMBOLW PIMAGEHLP_SYMBOLW64
+ #define IMAGEHLP_SYMBOLW_PACKAGE IMAGEHLP_SYMBOLW64_PACKAGE
+ #define PIMAGEHLP_SYMBOLW_PACKAGE PIMAGEHLP_SYMBOLW64_PACKAGE
+
+#else
+
+ typedef struct _IMAGEHLP_SYMBOL {
+     DWORD SizeOfStruct;           // set to sizeof(IMAGEHLP_SYMBOL)
+     DWORD Address;                // virtual address including dll base address
+     DWORD Size;                   // estimated size of symbol, can be zero
+     DWORD Flags;                  // info about the symbols, see the SYMF defines
+     DWORD                       MaxNameLength;          // maximum size of symbol name in 'Name'
+     CHAR                        Name[1];                // symbol name (null terminated string)
+ } IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL;
+
+ typedef struct _IMAGEHLP_SYMBOL_PACKAGE {
+     IMAGEHLP_SYMBOL sym;
+     CHAR            name[MAX_SYM_NAME + 1];
+ } IMAGEHLP_SYMBOL_PACKAGE, *PIMAGEHLP_SYMBOL_PACKAGE;
+
+ typedef struct _IMAGEHLP_SYMBOLW {
+     DWORD SizeOfStruct;           // set to sizeof(IMAGEHLP_SYMBOLW)
+     DWORD Address;                // virtual address including dll base address
+     DWORD Size;                   // estimated size of symbol, can be zero
+     DWORD Flags;                  // info about the symbols, see the SYMF defines
+     DWORD                       MaxNameLength;          // maximum size of symbol name in 'Name'
+     WCHAR                       Name[1];                // symbol name (null terminated string)
+ } IMAGEHLP_SYMBOLW, *PIMAGEHLP_SYMBOLW;
+
+ typedef struct _IMAGEHLP_SYMBOLW_PACKAGE {
+     IMAGEHLP_SYMBOLW sym;
+     WCHAR            name[MAX_SYM_NAME + 1];
+ } IMAGEHLP_SYMBOLW_PACKAGE, *PIMAGEHLP_SYMBOLW_PACKAGE;
+
+#endif
+
+//
+// module data structure
+//
+
+typedef struct _IMAGEHLP_MODULE64 {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_MODULE64)
+    DWORD64  BaseOfImage;            // base load address of module
+    DWORD    ImageSize;              // virtual size of the loaded module
+    DWORD    TimeDateStamp;          // date/time stamp from pe header
+    DWORD    CheckSum;               // checksum from the pe header
+    DWORD    NumSyms;                // number of symbols in the symbol table
+    SYM_TYPE SymType;                // type of symbols loaded
+    CHAR     ModuleName[32];         // module name
+    CHAR     ImageName[256];         // image name
+    CHAR     LoadedImageName[256];   // symbol file name
+    // new elements: 07-Jun-2002
+    CHAR     LoadedPdbName[256];     // pdb file name
+    DWORD    CVSig;                  // Signature of the CV record in the debug directories
+    CHAR     CVData[MAX_PATH * 3];   // Contents of the CV record
+    DWORD    PdbSig;                 // Signature of PDB
+    GUID     PdbSig70;               // Signature of PDB (VC 7 and up)
+    DWORD    PdbAge;                 // DBI age of pdb
+    BOOL     PdbUnmatched;           // loaded an unmatched pdb
+    BOOL     DbgUnmatched;           // loaded an unmatched dbg
+    BOOL     LineNumbers;            // we have line number information
+    BOOL     GlobalSymbols;          // we have internal symbol information
+    BOOL     TypeInfo;               // we have type information
+    // new elements: 17-Dec-2003
+    BOOL     SourceIndexed;          // pdb supports source server
+    BOOL     Publics;                // contains public symbols
+    // new element: 15-Jul-2009
+    DWORD    MachineType;            // IMAGE_FILE_MACHINE_XXX from ntimage.h and winnt.h
+    DWORD    Reserved;               // Padding - don't remove.
+} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64;
+
+typedef struct _IMAGEHLP_MODULEW64 {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_MODULE64)
+    DWORD64  BaseOfImage;            // base load address of module
+    DWORD    ImageSize;              // virtual size of the loaded module
+    DWORD    TimeDateStamp;          // date/time stamp from pe header
+    DWORD    CheckSum;               // checksum from the pe header
+    DWORD    NumSyms;                // number of symbols in the symbol table
+    SYM_TYPE SymType;                // type of symbols loaded
+    WCHAR    ModuleName[32];         // module name
+    WCHAR    ImageName[256];         // image name
+    // new elements: 07-Jun-2002
+    WCHAR    LoadedImageName[256];   // symbol file name
+    WCHAR    LoadedPdbName[256];     // pdb file name
+    DWORD    CVSig;                  // Signature of the CV record in the debug directories
+    WCHAR        CVData[MAX_PATH * 3];   // Contents of the CV record
+    DWORD    PdbSig;                 // Signature of PDB
+    GUID     PdbSig70;               // Signature of PDB (VC 7 and up)
+    DWORD    PdbAge;                 // DBI age of pdb
+    BOOL     PdbUnmatched;           // loaded an unmatched pdb
+    BOOL     DbgUnmatched;           // loaded an unmatched dbg
+    BOOL     LineNumbers;            // we have line number information
+    BOOL     GlobalSymbols;          // we have internal symbol information
+    BOOL     TypeInfo;               // we have type information
+    // new elements: 17-Dec-2003
+    BOOL     SourceIndexed;          // pdb supports source server
+    BOOL     Publics;                // contains public symbols
+    // new element: 15-Jul-2009
+    DWORD    MachineType;            // IMAGE_FILE_MACHINE_XXX from ntimage.h and winnt.h
+    DWORD    Reserved;               // Padding - don't remove.
+} IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define IMAGEHLP_MODULE IMAGEHLP_MODULE64
+#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64
+#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64
+#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64
+#else
+typedef struct _IMAGEHLP_MODULE {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_MODULE)
+    DWORD    BaseOfImage;            // base load address of module
+    DWORD    ImageSize;              // virtual size of the loaded module
+    DWORD    TimeDateStamp;          // date/time stamp from pe header
+    DWORD    CheckSum;               // checksum from the pe header
+    DWORD    NumSyms;                // number of symbols in the symbol table
+    SYM_TYPE SymType;                // type of symbols loaded
+    CHAR     ModuleName[32];         // module name
+    CHAR     ImageName[256];         // image name
+    CHAR     LoadedImageName[256];   // symbol file name
+} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE;
+
+typedef struct _IMAGEHLP_MODULEW {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_MODULE)
+    DWORD    BaseOfImage;            // base load address of module
+    DWORD    ImageSize;              // virtual size of the loaded module
+    DWORD    TimeDateStamp;          // date/time stamp from pe header
+    DWORD    CheckSum;               // checksum from the pe header
+    DWORD    NumSyms;                // number of symbols in the symbol table
+    SYM_TYPE SymType;                // type of symbols loaded
+    WCHAR    ModuleName[32];         // module name
+    WCHAR    ImageName[256];         // image name
+    WCHAR    LoadedImageName[256];   // symbol file name
+} IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW;
+#endif
+
+//
+// source file line data structure
+//
+
+typedef struct _IMAGEHLP_LINE64 {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_LINE64)
+    PVOID    Key;                    // internal
+    DWORD    LineNumber;             // line number in file
+    PCHAR    FileName;               // full filename
+    DWORD64  Address;                // first instruction of line
+} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
+
+typedef struct _IMAGEHLP_LINEW64 {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_LINE64)
+    PVOID    Key;                    // internal
+    DWORD    LineNumber;             // line number in file
+    PWSTR    FileName;               // full filename
+    DWORD64  Address;                // first instruction of line
+} IMAGEHLP_LINEW64, *PIMAGEHLP_LINEW64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define IMAGEHLP_LINE IMAGEHLP_LINE64
+#define PIMAGEHLP_LINE PIMAGEHLP_LINE64
+#else
+typedef struct _IMAGEHLP_LINE {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_LINE)
+    PVOID    Key;                    // internal
+    DWORD    LineNumber;             // line number in file
+    PCHAR    FileName;               // full filename
+    DWORD    Address;                // first instruction of line
+} IMAGEHLP_LINE, *PIMAGEHLP_LINE;
+
+typedef struct _IMAGEHLP_LINEW {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_LINE64)
+    PVOID    Key;                    // internal
+    DWORD    LineNumber;             // line number in file
+    PCHAR    FileName;               // full filename
+    DWORD64  Address;                // first instruction of line
+} IMAGEHLP_LINEW, *PIMAGEHLP_LINEW;
+#endif
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+//
+// source file structure
+//
+
+typedef struct _SOURCEFILE {
+    DWORD64  ModBase;                // base address of loaded module
+    PCHAR    FileName;               // full filename of source
+} SOURCEFILE, *PSOURCEFILE;
+
+typedef struct _SOURCEFILEW {
+    DWORD64  ModBase;                // base address of loaded module
+    PWSTR    FileName;               // full filename of source
+} SOURCEFILEW, *PSOURCEFILEW;
+
+//
+// data structures used for registered symbol callbacks
+//
+
+#define CBA_DEFERRED_SYMBOL_LOAD_START          0x00000001
+#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE       0x00000002
+#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE        0x00000003
+#define CBA_SYMBOLS_UNLOADED                    0x00000004
+#define CBA_DUPLICATE_SYMBOL                    0x00000005
+#define CBA_READ_MEMORY                         0x00000006
+#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL         0x00000007
+#define CBA_SET_OPTIONS                         0x00000008
+#define CBA_EVENT                               0x00000010
+#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL        0x00000020
+#define CBA_DEBUG_INFO                          0x10000000
+#define CBA_SRCSRV_INFO                         0x20000000
+#define CBA_SRCSRV_EVENT                        0x40000000
+#define CBA_UPDATE_STATUS_BAR                   0x50000000
+#define CBA_ENGINE_PRESENT                      0x60000000
+#define CBA_CHECK_ENGOPT_DISALLOW_NETWORK_PATHS 0x70000000
+#define CBA_CHECK_ARM_MACHINE_THUMB_TYPE_OVERRIDE 0x80000000
+#define CBA_XML_LOG                             0x90000000
+
+
+typedef struct _IMAGEHLP_CBA_READ_MEMORY {
+    DWORD64   addr;                                     // address to read from
+    PVOID     buf;                                      // buffer to read to
+    DWORD     bytes;                                    // amount of bytes to read
+    DWORD    *bytesread;                                // pointer to store amount of bytes read
+} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY;
+
+enum {
+    sevInfo = 0,
+    sevProblem,
+    sevAttn,
+    sevFatal,
+    sevMax  // unused
+};
+
+#define EVENT_SRCSPEW_START 100
+#define EVENT_SRCSPEW       100
+#define EVENT_SRCSPEW_END   199
+
+typedef struct _IMAGEHLP_CBA_EVENT {
+    DWORD severity;                                     // values from sevInfo to sevFatal
+    DWORD code;                                         // numerical code IDs the error
+    PCHAR desc;                                         // may contain a text description of the error
+    PVOID object;                                       // value dependant upon the error code
+} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT;
+
+typedef struct _IMAGEHLP_CBA_EVENTW {
+    DWORD  severity;                                     // values from sevInfo to sevFatal
+    DWORD  code;                                         // numerical code IDs the error
+    PCWSTR desc;                                         // may contain a text description of the error
+    PVOID  object;                                       // value dependant upon the error code
+} IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW;
+
+typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
+    DWORD64  BaseOfImage;            // base load address of module
+    DWORD    CheckSum;               // checksum from the pe header
+    DWORD    TimeDateStamp;          // date/time stamp from pe header
+    CHAR     FileName[MAX_PATH];     // symbols file or image name
+    BOOLEAN  Reparse;                // load failure reparse
+    HANDLE   hFile;                  // file handle, if passed
+    DWORD    Flags;                     //
+} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64;
+
+typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOADW64)
+    DWORD64  BaseOfImage;            // base load address of module
+    DWORD    CheckSum;               // checksum from the pe header
+    DWORD    TimeDateStamp;          // date/time stamp from pe header
+    WCHAR    FileName[MAX_PATH + 1]; // symbols file or image name
+    BOOLEAN  Reparse;                // load failure reparse
+    HANDLE   hFile;                  // file handle, if passed
+    DWORD    Flags;         //
+} IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64;
+
+#define DSLFLAG_MISMATCHED_PDB              0x1
+#define DSLFLAG_MISMATCHED_DBG              0x2
+#define FLAG_ENGINE_PRESENT                 0x4
+#define FLAG_ENGOPT_DISALLOW_NETWORK_PATHS  0x8
+#define FLAG_OVERRIDE_ARM_MACHINE_TYPE      0x10
+
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64
+#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64
+#else
+typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD {
+    DWORD    SizeOfStruct;           // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD)
+    DWORD    BaseOfImage;            // base load address of module
+    DWORD    CheckSum;               // checksum from the pe header
+    DWORD    TimeDateStamp;          // date/time stamp from pe header
+    CHAR     FileName[MAX_PATH];     // symbols file or image name
+    BOOLEAN  Reparse;                // load failure reparse
+    HANDLE   hFile;                  // file handle, if passed
+} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD;
+#endif
+
+typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 {
+    DWORD              SizeOfStruct;           // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64)
+    DWORD              NumberOfDups;           // number of duplicates in the Symbol array
+    PIMAGEHLP_SYMBOL64 Symbol;                 // array of duplicate symbols
+    DWORD              SelectedSymbol;         // symbol selected (-1 to start)
+} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64
+#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64
+#else
+typedef struct _IMAGEHLP_DUPLICATE_SYMBOL {
+    DWORD            SizeOfStruct;           // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL)
+    DWORD            NumberOfDups;           // number of duplicates in the Symbol array
+    PIMAGEHLP_SYMBOL Symbol;                 // array of duplicate symbols
+    DWORD            SelectedSymbol;         // symbol selected (-1 to start)
+} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL;
+#endif
+
+// If dbghelp ever needs to display graphical UI, it will use this as the parent window.
+
+BOOL
+IMAGEAPI
+SymSetParentWindow(
+    _In_ HWND hwnd
+    );
+
+PCHAR
+IMAGEAPI
+SymSetHomeDirectory(
+    _In_opt_ HANDLE hProcess,
+    _In_opt_ PCSTR dir
+    );
+
+PWSTR
+IMAGEAPI
+SymSetHomeDirectoryW(
+    _In_opt_ HANDLE hProcess,
+    _In_opt_ PCWSTR dir
+    );
+
+PCHAR
+IMAGEAPI
+SymGetHomeDirectory(
+    _In_ DWORD type,
+    _Out_writes_(size) PSTR dir,
+    _In_ size_t size
+    );
+
+PWSTR
+IMAGEAPI
+SymGetHomeDirectoryW(
+    _In_ DWORD type,
+    _Out_writes_(size) PWSTR dir,
+    _In_ size_t size
+    );
+
+typedef enum {
+    hdBase = 0, // root directory for dbghelp
+    hdSym,      // where symbols are stored
+    hdSrc,      // where source is stored
+    hdMax       // end marker
+} IMAGEHLP_HD_TYPE;
+
+typedef struct _OMAP {
+    ULONG  rva;
+    ULONG  rvaTo;
+} OMAP, *POMAP;
+
+BOOL
+IMAGEAPI
+SymGetOmaps(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 BaseOfDll,
+    _Out_ POMAP *OmapTo,
+    _Out_ PDWORD64 cOmapTo,
+    _Out_ POMAP *OmapFrom,
+    _Out_ PDWORD64 cOmapFrom
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Application Family or OneCore Family or Games Family
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
+
+//
+// options that are set/returned by SymSetOptions() & SymGetOptions()
+// these are used as a mask
+//
+
+ #define SYMOPT_CASE_INSENSITIVE          0x00000001
+ #define SYMOPT_UNDNAME                   0x00000002
+ #define SYMOPT_DEFERRED_LOADS            0x00000004
+ #define SYMOPT_NO_CPP                    0x00000008
+ #define SYMOPT_LOAD_LINES                0x00000010
+ #define SYMOPT_OMAP_FIND_NEAREST         0x00000020
+ #define SYMOPT_LOAD_ANYTHING             0x00000040
+ #define SYMOPT_IGNORE_CVREC              0x00000080
+ #define SYMOPT_NO_UNQUALIFIED_LOADS      0x00000100
+ #define SYMOPT_FAIL_CRITICAL_ERRORS      0x00000200
+ #define SYMOPT_EXACT_SYMBOLS             0x00000400
+ #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS    0x00000800
+ #define SYMOPT_IGNORE_NT_SYMPATH         0x00001000
+ #define SYMOPT_INCLUDE_32BIT_MODULES     0x00002000
+ #define SYMOPT_PUBLICS_ONLY              0x00004000
+ #define SYMOPT_NO_PUBLICS                0x00008000
+ #define SYMOPT_AUTO_PUBLICS              0x00010000
+ #define SYMOPT_NO_IMAGE_SEARCH           0x00020000
+ #define SYMOPT_SECURE                    0x00040000
+ #define SYMOPT_NO_PROMPTS                0x00080000
+ #define SYMOPT_OVERWRITE                 0x00100000
+ #define SYMOPT_IGNORE_IMAGEDIR           0x00200000
+ #define SYMOPT_FLAT_DIRECTORY            0x00400000
+ #define SYMOPT_FAVOR_COMPRESSED          0x00800000
+ #define SYMOPT_ALLOW_ZERO_ADDRESS        0x01000000
+ #define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000
+ #define SYMOPT_READONLY_CACHE            0x04000000
+ #define SYMOPT_SYMPATH_LAST              0x08000000
+ #define SYMOPT_DISABLE_FAST_SYMBOLS      0x10000000
+ #define SYMOPT_DISABLE_SYMSRV_TIMEOUT    0x20000000
+ #define SYMOPT_DISABLE_SRVSTAR_ON_STARTUP 0x40000000
+ #define SYMOPT_DEBUG                     0x80000000
+
+#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */ 
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+typedef enum {
+    SYMOPT_EX_DISABLEACCESSTIMEUPDATE, // Disable File Last Access Time on Symbols
+    SYMOPT_EX_LASTVALIDDEBUGDIRECTORY, // For entries with multiple debug directories: prefer the last to the first
+    SYMOPT_EX_MAX                      // Unused
+} IMAGEHLP_EXTENDED_OPTIONS;
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+DWORD
+IMAGEAPI
+SymSetOptions(
+    _In_ DWORD   SymOptions
+    );
+
+DWORD
+IMAGEAPI
+SymGetOptions(
+    VOID
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+BOOL
+IMAGEAPI
+SymCleanup(
+    _In_ HANDLE hProcess
+    );
+
+// Returns the value of the extended option
+BOOL
+IMAGEAPI
+SymGetExtendedOption(_In_ IMAGEHLP_EXTENDED_OPTIONS option);
+
+// Returns the previous value of the option
+BOOL
+IMAGEAPI
+SymSetExtendedOption(_In_ IMAGEHLP_EXTENDED_OPTIONS option, _In_ BOOL value);
+
+BOOL
+IMAGEAPI
+SymMatchString(
+    _In_ PCSTR string,
+    _In_ PCSTR expression,
+    _In_ BOOL fCase
+    );
+
+BOOL
+IMAGEAPI
+SymMatchStringA(
+    _In_ PCSTR string,
+    _In_ PCSTR expression,
+    _In_ BOOL fCase
+    );
+
+BOOL
+IMAGEAPI
+SymMatchStringW(
+    _In_ PCWSTR string,
+    _In_ PCWSTR expression,
+    _In_ BOOL fCase
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACK)(
+    _In_ PSOURCEFILE pSourceFile,
+    _In_opt_ PVOID UserContext
+    );
+
+// for backwards compatibility - don't use this
+#define PSYM_ENUMSOURCFILES_CALLBACK PSYM_ENUMSOURCEFILES_CALLBACK
+
+BOOL
+IMAGEAPI
+SymEnumSourceFiles(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 ModBase,
+    _In_opt_ PCSTR Mask,
+    _In_ PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACKW)(
+    _In_ PSOURCEFILEW pSourceFile,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumSourceFilesW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 ModBase,
+    _In_opt_ PCWSTR Mask,
+    _In_ PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumerateModules64(
+    _In_ HANDLE hProcess,
+    _In_ PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumerateModulesW64(
+    _In_ HANDLE hProcess,
+    _In_ PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymEnumerateModules SymEnumerateModules64
+#else
+BOOL
+IMAGEAPI
+SymEnumerateModules(
+    _In_ HANDLE hProcess,
+    _In_ PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
+    _In_opt_ PVOID UserContext
+    );
+#endif
+
+BOOL
+IMAGEAPI
+EnumerateLoadedModulesEx(
+    _In_ HANDLE hProcess,
+    _In_ PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+EnumerateLoadedModulesExW(
+    _In_ HANDLE hProcess,
+    _In_ PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+EnumerateLoadedModules64(
+    _In_ HANDLE hProcess,
+    _In_ PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+EnumerateLoadedModulesW64(
+    _In_ HANDLE hProcess,
+    _In_ PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define EnumerateLoadedModules EnumerateLoadedModules64
+#else
+BOOL
+IMAGEAPI
+EnumerateLoadedModules(
+    _In_ HANDLE hProcess,
+    _In_ PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
+    _In_opt_ PVOID UserContext
+    );
+#endif
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+PVOID
+IMAGEAPI
+SymFunctionTableAccess64(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 AddrBase
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+PVOID
+IMAGEAPI
+SymFunctionTableAccess64AccessRoutines(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 AddrBase,
+    _In_opt_ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
+    _In_opt_ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymFunctionTableAccess SymFunctionTableAccess64
+#else
+PVOID
+IMAGEAPI
+SymFunctionTableAccess(
+    _In_ HANDLE hProcess,
+    _In_ DWORD AddrBase
+    );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetUnwindInfo(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address,
+    _Out_writes_bytes_opt_(*Size) PVOID Buffer,
+    _Inout_ PULONG Size
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+BOOL
+IMAGEAPI
+SymGetModuleInfo64(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 qwAddr,
+    _Out_ PIMAGEHLP_MODULE64 ModuleInfo
+    );
+
+BOOL
+IMAGEAPI
+SymGetModuleInfoW64(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 qwAddr,
+    _Out_ PIMAGEHLP_MODULEW64 ModuleInfo
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetModuleInfo   SymGetModuleInfo64
+#define SymGetModuleInfoW  SymGetModuleInfoW64
+#else
+BOOL
+IMAGEAPI
+SymGetModuleInfo(
+    _In_ HANDLE hProcess,
+    _In_ DWORD dwAddr,
+    _Out_ PIMAGEHLP_MODULE ModuleInfo
+    );
+
+BOOL
+IMAGEAPI
+SymGetModuleInfoW(
+    _In_ HANDLE hProcess,
+    _In_ DWORD dwAddr,
+    _Out_ PIMAGEHLP_MODULEW ModuleInfo
+    );
+#endif
+
+DWORD64
+IMAGEAPI
+SymGetModuleBase64(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 qwAddr
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetModuleBase SymGetModuleBase64
+#else
+DWORD
+IMAGEAPI
+SymGetModuleBase(
+    _In_ HANDLE hProcess,
+    _In_ DWORD dwAddr
+    );
+#endif
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+typedef struct _SRCCODEINFO {
+    DWORD   SizeOfStruct;           // set to sizeof(SRCCODEINFO)
+    PVOID   Key;                    // not used
+    DWORD64 ModBase;                // base address of module this applies to
+    CHAR    Obj[MAX_PATH + 1];      // the object file within the module
+    CHAR    FileName[MAX_PATH + 1]; // full filename
+    DWORD   LineNumber;             // line number in file
+    DWORD64 Address;                // first instruction of line
+} SRCCODEINFO, *PSRCCODEINFO;
+
+typedef struct _SRCCODEINFOW {
+    DWORD   SizeOfStruct;           // set to sizeof(SRCCODEINFO)
+    PVOID   Key;                    // not used
+    DWORD64 ModBase;                // base address of module this applies to
+    WCHAR   Obj[MAX_PATH + 1];      // the object file within the module
+    WCHAR   FileName[MAX_PATH + 1]; // full filename
+    DWORD   LineNumber;             // line number in file
+    DWORD64 Address;                // first instruction of line
+} SRCCODEINFOW, *PSRCCODEINFOW;
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMLINES_CALLBACK)(
+    _In_ PSRCCODEINFO LineInfo,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumLines(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_opt_ PCSTR Obj,
+    _In_opt_ PCSTR File,
+    _In_ PSYM_ENUMLINES_CALLBACK EnumLinesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMLINES_CALLBACKW)(
+    _In_ PSRCCODEINFOW LineInfo,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumLinesW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_opt_ PCWSTR Obj,
+    _In_opt_ PCWSTR File,
+    _In_ PSYM_ENUMLINES_CALLBACKW EnumLinesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+BOOL
+IMAGEAPI
+SymGetLineFromAddr64(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 qwAddr,
+    _Out_ PDWORD pdwDisplacement,
+    _Out_ PIMAGEHLP_LINE64 Line64
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+BOOL
+IMAGEAPI
+SymGetLineFromAddrW64(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 dwAddr,
+    _Out_ PDWORD pdwDisplacement,
+    _Out_ PIMAGEHLP_LINEW64 Line
+    );
+
+BOOL
+IMAGEAPI
+SymGetLineFromInlineContext(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 qwAddr,
+    _In_ ULONG InlineContext,
+    _In_opt_ DWORD64 qwModuleBaseAddress,
+    _Out_ PDWORD pdwDisplacement,
+    _Out_ PIMAGEHLP_LINE64 Line64
+    );
+
+BOOL
+IMAGEAPI
+SymGetLineFromInlineContextW(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 dwAddr,
+    _In_ ULONG InlineContext,
+    _In_opt_ DWORD64 qwModuleBaseAddress,
+    _Out_ PDWORD pdwDisplacement,
+    _Out_ PIMAGEHLP_LINEW64 Line
+    );
+
+BOOL
+IMAGEAPI
+SymEnumSourceLines(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_opt_ PCSTR Obj,
+    _In_opt_ PCSTR File,
+    _In_opt_ DWORD Line,
+    _In_ DWORD Flags,
+    _In_ PSYM_ENUMLINES_CALLBACK EnumLinesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumSourceLinesW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_opt_ PCWSTR Obj,
+    _In_opt_ PCWSTR File,
+    _In_opt_ DWORD Line,
+    _In_ DWORD Flags,
+    _In_ PSYM_ENUMLINES_CALLBACKW EnumLinesCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+// Check whether input Address includes "inline stack".
+DWORD
+IMAGEAPI
+SymAddrIncludeInlineTrace(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address
+    );
+
+#define SYM_INLINE_COMP_ERROR     0
+#define SYM_INLINE_COMP_IDENTICAL 1
+#define SYM_INLINE_COMP_STEPIN    2
+#define SYM_INLINE_COMP_STEPOUT   3
+#define SYM_INLINE_COMP_STEPOVER  4
+#define SYM_INLINE_COMP_DIFFERENT 5
+
+// Compare the "inline stack" from the 2 input addresses and determine whether the difference is possibly from
+// what execution control operation. The return value would be onr of the literals defined above.
+DWORD
+IMAGEAPI
+SymCompareInlineTrace(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address1,
+    _In_ DWORD   InlineContext1,
+    _In_ DWORD64 RetAddress1,
+    _In_ DWORD64 Address2,
+    _In_ DWORD64 RetAddress2
+    );
+
+BOOL
+IMAGEAPI
+SymQueryInlineTrace(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 StartAddress,
+    _In_ DWORD StartContext,
+    _In_ DWORD64 StartRetAddress,
+    _In_ DWORD64 CurAddress,
+    _Out_ LPDWORD CurContext,
+    _Out_ LPDWORD CurFrameIndex
+    );
+
+// flags for SymEnumSourceLines
+
+#define ESLFLAG_FULLPATH        0x00000001
+#define ESLFLAG_NEAREST         0x00000002
+#define ESLFLAG_PREV            0x00000004
+#define ESLFLAG_NEXT            0x00000008
+#define ESLFLAG_INLINE_SITE     0x00000010
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetLineFromAddr SymGetLineFromAddr64
+#define SymGetLineFromAddrW SymGetLineFromAddrW64
+#else
+BOOL
+IMAGEAPI
+SymGetLineFromAddr(
+    _In_ HANDLE hProcess,
+    _In_ DWORD dwAddr,
+    _Out_ PDWORD pdwDisplacement,
+    _Out_ PIMAGEHLP_LINE Line
+    );
+
+BOOL
+IMAGEAPI
+SymGetLineFromAddrW(
+    _In_ HANDLE hProcess,
+    _In_ DWORD dwAddr,
+    _Out_ PDWORD pdwDisplacement,
+    _Out_ PIMAGEHLP_LINEW Line
+    );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetLineFromName64(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR ModuleName,
+    _In_opt_ PCSTR FileName,
+    _In_ DWORD dwLineNumber,
+    _Out_ PLONG plDisplacement,
+    _Inout_ PIMAGEHLP_LINE64 Line
+    );
+
+BOOL
+IMAGEAPI
+SymGetLineFromNameW64(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCWSTR ModuleName,
+    _In_opt_ PCWSTR FileName,
+    _In_ DWORD dwLineNumber,
+    _Out_ PLONG plDisplacement,
+    _Inout_ PIMAGEHLP_LINEW64 Line
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetLineFromName SymGetLineFromName64
+#else
+BOOL
+IMAGEAPI
+SymGetLineFromName(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR ModuleName,
+    _In_opt_ PCSTR FileName,
+    _In_ DWORD dwLineNumber,
+    _Out_ PLONG plDisplacement,
+    _Inout_ PIMAGEHLP_LINE Line
+    );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetLineNext64(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_LINE64 Line
+    );
+
+BOOL
+IMAGEAPI
+SymGetLineNextW64(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_LINEW64 Line
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetLineNext SymGetLineNext64
+#else
+BOOL
+IMAGEAPI
+SymGetLineNext(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_LINE Line
+    );
+
+BOOL
+IMAGEAPI
+SymGetLineNextW(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_LINEW Line
+    );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetLinePrev64(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_LINE64 Line
+    );
+
+BOOL
+IMAGEAPI
+SymGetLinePrevW64(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_LINEW64 Line
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetLinePrev SymGetLinePrev64
+#else
+BOOL
+IMAGEAPI
+SymGetLinePrev(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_LINE Line
+    );
+
+BOOL
+IMAGEAPI
+SymGetLinePrevW(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_LINEW Line
+    );
+#endif
+
+ULONG
+IMAGEAPI
+SymGetFileLineOffsets64(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR ModuleName,
+    _In_ PCSTR FileName,
+    _Out_writes_(BufferLines) PDWORD64 Buffer,
+    _In_ ULONG BufferLines
+    );
+
+BOOL
+IMAGEAPI
+SymMatchFileName(
+    _In_ PCSTR FileName,
+    _In_ PCSTR Match,
+    _Outptr_opt_ PSTR *FileNameStop,
+    _Outptr_opt_ PSTR *MatchStop
+    );
+
+BOOL
+IMAGEAPI
+SymMatchFileNameW(
+    _In_ PCWSTR FileName,
+    _In_ PCWSTR Match,
+    _Outptr_opt_ PWSTR *FileNameStop,
+    _Outptr_opt_ PWSTR *MatchStop
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceFile(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_opt_ PCSTR Params,
+    _In_ PCSTR FileSpec,
+    _Out_writes_(Size) PSTR FilePath,
+    _In_ DWORD Size
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_opt_ PCWSTR Params,
+    _In_ PCWSTR FileSpec,
+    _Out_writes_(Size) PWSTR FilePath,
+    _In_ DWORD Size
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileToken(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_ PCSTR FileSpec,
+    _Outptr_ PVOID *Token,
+    _Out_ DWORD *Size
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileChecksumW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_ PCWSTR FileSpec,
+    _Out_ DWORD *pCheckSumType,
+    _Out_writes_(checksumSize) BYTE *pChecksum,
+    _In_ DWORD checksumSize,
+    _Out_ DWORD *pActualBytesWritten
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileChecksum(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_ PCSTR FileSpec,
+    _Out_ DWORD *pCheckSumType,
+    _Out_writes_(checksumSize) BYTE *pChecksum,
+    _In_ DWORD checksumSize,
+    _Out_ DWORD *pActualBytesWritten
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileTokenW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_ PCWSTR FileSpec,
+    _Outptr_ PVOID *Token,
+    _Out_ DWORD *Size
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileFromToken(
+    _In_ HANDLE hProcess,
+    _In_ PVOID Token,
+    _In_opt_ PCSTR Params,
+    _Out_writes_(Size) PSTR FilePath,
+    _In_ DWORD Size
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileFromTokenW(
+    _In_ HANDLE hProcess,
+    _In_ PVOID Token,
+    _In_opt_ PCWSTR Params,
+    _Out_writes_(Size) PWSTR FilePath,
+    _In_ DWORD Size
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceVarFromToken(
+    _In_ HANDLE hProcess,
+    _In_ PVOID Token,
+    _In_opt_ PCSTR Params,
+    _In_ PCSTR VarName,
+    _Out_writes_(Size) PSTR Value,
+    _In_ DWORD Size
+    );
+
+BOOL
+IMAGEAPI
+SymGetSourceVarFromTokenW(
+    _In_ HANDLE hProcess,
+    _In_ PVOID Token,
+    _In_opt_ PCWSTR Params,
+    _In_ PCWSTR VarName,
+    _Out_writes_(Size) PWSTR Value,
+    _In_ DWORD Size
+    );
+
+typedef BOOL (CALLBACK *PENUMSOURCEFILETOKENSCALLBACK)(_In_ PVOID token,  _In_ size_t size);
+
+BOOL
+IMAGEAPI
+SymEnumSourceFileTokens(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_ PENUMSOURCEFILETOKENSCALLBACK Callback
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+BOOL
+IMAGEAPI
+SymInitialize(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR UserSearchPath,
+    _In_ BOOL fInvadeProcess
+    );
+
+BOOL
+IMAGEAPI
+SymInitializeW(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCWSTR UserSearchPath,
+    _In_ BOOL fInvadeProcess
+    );
+    
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+BOOL
+IMAGEAPI
+SymGetSearchPath(
+    _In_ HANDLE hProcess,
+    _Out_writes_(SearchPathLength) PSTR SearchPath,
+    _In_ DWORD SearchPathLength
+    );
+
+BOOL
+IMAGEAPI
+SymGetSearchPathW(
+    _In_ HANDLE hProcess,
+    _Out_writes_(SearchPathLength) PWSTR SearchPath,
+    _In_ DWORD SearchPathLength
+    );
+
+BOOL
+IMAGEAPI
+SymSetSearchPath(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR SearchPath
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+BOOL
+IMAGEAPI
+SymSetSearchPathW(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCWSTR SearchPath
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+#define SLMFLAG_VIRTUAL     0x1
+#define SLMFLAG_ALT_INDEX   0x2
+#define SLMFLAG_NO_SYMBOLS  0x4
+
+DWORD64
+IMAGEAPI
+SymLoadModuleEx(
+    _In_ HANDLE hProcess,
+    _In_opt_ HANDLE hFile,
+    _In_opt_ PCSTR ImageName,
+    _In_opt_ PCSTR ModuleName,
+    _In_ DWORD64 BaseOfDll,
+    _In_ DWORD DllSize,
+    _In_opt_ PMODLOAD_DATA Data,
+    _In_opt_ DWORD Flags
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+DWORD64
+IMAGEAPI
+SymLoadModuleExW(
+    _In_ HANDLE hProcess,
+    _In_opt_ HANDLE hFile,
+    _In_opt_ PCWSTR ImageName,
+    _In_opt_ PCWSTR ModuleName,
+    _In_ DWORD64 BaseOfDll,
+    _In_ DWORD DllSize,
+    _In_opt_ PMODLOAD_DATA Data,
+    _In_opt_ DWORD Flags
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+BOOL
+IMAGEAPI
+SymUnloadModule64(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 BaseOfDll
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymUnloadModule SymUnloadModule64
+#else
+BOOL
+IMAGEAPI
+SymUnloadModule(
+    _In_ HANDLE hProcess,
+    _In_ DWORD BaseOfDll
+    );
+#endif
+
+BOOL
+IMAGEAPI
+SymUnDName64(
+    _In_ PIMAGEHLP_SYMBOL64 sym,            // Symbol to undecorate
+    _Out_writes_(UnDecNameLength) PSTR UnDecName,   // Buffer to store undecorated name in
+    _In_ DWORD UnDecNameLength              // Size of the buffer
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymUnDName SymUnDName64
+#else
+BOOL
+IMAGEAPI
+SymUnDName(
+    _In_ PIMAGEHLP_SYMBOL sym,              // Symbol to undecorate
+    _Out_writes_(UnDecNameLength) PSTR UnDecName,   // Buffer to store undecorated name in
+    _In_ DWORD UnDecNameLength              // Size of the buffer
+    );
+#endif
+
+BOOL
+IMAGEAPI
+SymRegisterCallback64(
+    _In_ HANDLE hProcess,
+    _In_ PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
+    _In_ ULONG64 UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymRegisterCallbackW64(
+    _In_ HANDLE hProcess,
+    _In_ PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
+    _In_ ULONG64 UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymRegisterFunctionEntryCallback64(
+    _In_ HANDLE hProcess,
+    _In_ PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction,
+    _In_ ULONG64 UserContext
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymRegisterCallback SymRegisterCallback64
+#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64
+#else
+BOOL
+IMAGEAPI
+SymRegisterCallback(
+    _In_ HANDLE hProcess,
+    _In_ PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymRegisterFunctionEntryCallback(
+    _In_ HANDLE hProcess,
+    _In_ PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction,
+    _In_opt_ PVOID UserContext
+    );
+#endif
+
+
+typedef struct _IMAGEHLP_SYMBOL_SRC {
+    DWORD sizeofstruct;
+    DWORD type;
+    char  file[MAX_PATH];
+} IMAGEHLP_SYMBOL_SRC, *PIMAGEHLP_SYMBOL_SRC;
+
+typedef struct _MODULE_TYPE_INFO { // AKA TYPTYP
+    USHORT      dataLength;
+    USHORT      leaf;
+    BYTE        data[1];
+} MODULE_TYPE_INFO, *PMODULE_TYPE_INFO;
+
+typedef struct _SYMBOL_INFO {
+    ULONG       SizeOfStruct;
+    ULONG       TypeIndex;        // Type Index of symbol
+    ULONG64     Reserved[2];
+    ULONG       Index;
+    ULONG       Size;
+    ULONG64     ModBase;          // Base Address of module comtaining this symbol
+    ULONG       Flags;
+    ULONG64     Value;            // Value of symbol, ValuePresent should be 1
+    ULONG64     Address;          // Address of symbol including base address of module
+    ULONG       Register;         // register holding value or pointer to value
+    ULONG       Scope;            // scope of the symbol
+    ULONG       Tag;              // pdb classification
+    ULONG       NameLen;          // Actual length of name
+    ULONG       MaxNameLen;
+    CHAR        Name[1];          // Name of symbol
+} SYMBOL_INFO, *PSYMBOL_INFO;
+
+typedef struct _SYMBOL_INFO_PACKAGE {
+    SYMBOL_INFO si;
+    CHAR        name[MAX_SYM_NAME + 1];
+} SYMBOL_INFO_PACKAGE, *PSYMBOL_INFO_PACKAGE;
+
+typedef struct _SYMBOL_INFOW {
+    ULONG       SizeOfStruct;
+    ULONG       TypeIndex;        // Type Index of symbol
+    ULONG64     Reserved[2];
+    ULONG       Index;
+    ULONG       Size;
+    ULONG64     ModBase;          // Base Address of module comtaining this symbol
+    ULONG       Flags;
+    ULONG64     Value;            // Value of symbol, ValuePresent should be 1
+    ULONG64     Address;          // Address of symbol including base address of module
+    ULONG       Register;         // register holding value or pointer to value
+    ULONG       Scope;            // scope of the symbol
+    ULONG       Tag;              // pdb classification
+    ULONG       NameLen;          // Actual length of name
+    ULONG       MaxNameLen;
+    WCHAR       Name[1];          // Name of symbol
+} SYMBOL_INFOW, *PSYMBOL_INFOW;
+
+typedef struct _SYMBOL_INFO_PACKAGEW {
+    SYMBOL_INFOW si;
+    WCHAR        name[MAX_SYM_NAME + 1];
+} SYMBOL_INFO_PACKAGEW, *PSYMBOL_INFO_PACKAGEW;
+
+typedef struct _IMAGEHLP_STACK_FRAME
+{
+    ULONG64 InstructionOffset;
+    ULONG64 ReturnOffset;
+    ULONG64 FrameOffset;
+    ULONG64 StackOffset;
+    ULONG64 BackingStoreOffset;
+    ULONG64 FuncTableEntry;
+    ULONG64 Params[4];
+    ULONG64 Reserved[5];
+    BOOL    Virtual;
+    ULONG   Reserved2;
+} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME;
+
+typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT;
+
+
+BOOL
+IMAGEAPI
+SymSetContext(
+    _In_ HANDLE hProcess,
+    _In_ PIMAGEHLP_STACK_FRAME StackFrame,
+    _In_opt_ PIMAGEHLP_CONTEXT Context
+    );
+
+BOOL
+IMAGEAPI
+SymSetScopeFromAddr(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Address
+    );
+
+BOOL
+IMAGEAPI
+SymSetScopeFromInlineContext(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Address,
+    _In_ ULONG InlineContext
+    );
+
+BOOL
+IMAGEAPI
+SymSetScopeFromIndex(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ DWORD Index
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMPROCESSES_CALLBACK)(
+    _In_ HANDLE hProcess,
+    _In_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumProcesses(
+    _In_ PSYM_ENUMPROCESSES_CALLBACK EnumProcessesCallback,
+    _In_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymFromAddr(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address,
+    _Out_opt_ PDWORD64 Displacement,
+    _Inout_ PSYMBOL_INFO Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymFromAddrW(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address,
+    _Out_opt_ PDWORD64 Displacement,
+    _Inout_ PSYMBOL_INFOW Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymFromInlineContext(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address,
+    _In_ ULONG InlineContext,
+    _Out_opt_ PDWORD64 Displacement,
+    _Inout_ PSYMBOL_INFO Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymFromInlineContextW(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address,
+    _In_ ULONG InlineContext,
+    _Out_opt_ PDWORD64 Displacement,
+    _Inout_ PSYMBOL_INFOW Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymFromToken(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Base,
+    _In_ DWORD Token,
+    _Inout_ PSYMBOL_INFO Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymFromTokenW(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Base,
+    _In_ DWORD Token,
+    _Inout_ PSYMBOL_INFOW Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymNext(
+    _In_ HANDLE hProcess,
+    _Inout_ PSYMBOL_INFO si
+    );
+
+BOOL
+IMAGEAPI
+SymNextW(
+    _In_ HANDLE hProcess,
+    _Inout_ PSYMBOL_INFOW siw
+    );
+
+BOOL
+IMAGEAPI
+SymPrev(
+    _In_ HANDLE hProcess,
+    _Inout_ PSYMBOL_INFO si
+    );
+
+BOOL
+IMAGEAPI
+SymPrevW(
+    _In_ HANDLE hProcess,
+    _Inout_ PSYMBOL_INFOW siw
+    );
+
+// While SymFromName will provide a symbol from a name,
+// SymEnumSymbols can provide the same matching information
+// for ALL symbols with a matching name, even regular
+// expressions.  That way you can search across modules
+// and differentiate between identically named symbols.
+
+BOOL
+IMAGEAPI
+SymFromName(
+    _In_ HANDLE hProcess,
+    _In_ PCSTR Name,
+    _Inout_ PSYMBOL_INFO Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymFromNameW(
+    _In_ HANDLE hProcess,
+    _In_ PCWSTR Name,
+    _Inout_ PSYMBOL_INFOW Symbol
+    );
+
+#define SYMENUM_OPTIONS_DEFAULT 0x00000001
+#define SYMENUM_OPTIONS_INLINE  0x00000002
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)(
+    _In_ PSYMBOL_INFO pSymInfo,
+    _In_ ULONG SymbolSize,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumSymbols(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ PCSTR Mask,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumSymbolsEx(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ PCSTR Mask,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext,
+    _In_ DWORD Options
+    );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACKW)(
+    _In_ PSYMBOL_INFOW pSymInfo,
+    _In_ ULONG SymbolSize,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumSymbolsW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ PCWSTR Mask,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumSymbolsExW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ PCWSTR Mask,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext,
+    _In_ DWORD Options
+    );
+
+BOOL
+IMAGEAPI
+SymEnumSymbolsForAddr(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumSymbolsForAddrW(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 Address,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+#define SYMSEARCH_MASKOBJS      0x01    // used internally to implement other APIs
+#define SYMSEARCH_RECURSE       0X02    // recurse scopes
+#define SYMSEARCH_GLOBALSONLY   0X04    // search only for global symbols
+#define SYMSEARCH_ALLITEMS      0X08    // search for everything in the pdb, not just normal scoped symbols
+
+BOOL
+IMAGEAPI
+SymSearch(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ DWORD Index,
+    _In_opt_ DWORD SymTag,
+    _In_opt_ PCSTR Mask,
+    _In_opt_ DWORD64 Address,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext,
+    _In_ DWORD Options
+    );
+
+BOOL
+IMAGEAPI
+SymSearchW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ DWORD Index,
+    _In_opt_ DWORD SymTag,
+    _In_opt_ PCWSTR Mask,
+    _In_opt_ DWORD64 Address,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext,
+    _In_ DWORD Options
+    );
+
+BOOL
+IMAGEAPI
+SymGetScope(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ DWORD Index,
+    _Inout_ PSYMBOL_INFO Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymGetScopeW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ DWORD Index,
+    _Inout_ PSYMBOL_INFOW Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymFromIndex(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ DWORD Index,
+    _Inout_ PSYMBOL_INFO Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymFromIndexW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ DWORD Index,
+    _Inout_ PSYMBOL_INFOW Symbol
+    );
+
+typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO {
+    TI_GET_SYMTAG,
+    TI_GET_SYMNAME,
+    TI_GET_LENGTH,
+    TI_GET_TYPE,
+    TI_GET_TYPEID,
+    TI_GET_BASETYPE,
+    TI_GET_ARRAYINDEXTYPEID,
+    TI_FINDCHILDREN,
+    TI_GET_DATAKIND,
+    TI_GET_ADDRESSOFFSET,
+    TI_GET_OFFSET,
+    TI_GET_VALUE,
+    TI_GET_COUNT,
+    TI_GET_CHILDRENCOUNT,
+    TI_GET_BITPOSITION,
+    TI_GET_VIRTUALBASECLASS,
+    TI_GET_VIRTUALTABLESHAPEID,
+    TI_GET_VIRTUALBASEPOINTEROFFSET,
+    TI_GET_CLASSPARENTID,
+    TI_GET_NESTED,
+    TI_GET_SYMINDEX,
+    TI_GET_LEXICALPARENT,
+    TI_GET_ADDRESS,
+    TI_GET_THISADJUST,
+    TI_GET_UDTKIND,
+    TI_IS_EQUIV_TO,
+    TI_GET_CALLING_CONVENTION,
+    TI_IS_CLOSE_EQUIV_TO,
+    TI_GTIEX_REQS_VALID,
+    TI_GET_VIRTUALBASEOFFSET,
+    TI_GET_VIRTUALBASEDISPINDEX,
+    TI_GET_IS_REFERENCE,
+    TI_GET_INDIRECTVIRTUALBASECLASS,
+    TI_GET_VIRTUALBASETABLETYPE,
+    IMAGEHLP_SYMBOL_TYPE_INFO_MAX,
+} IMAGEHLP_SYMBOL_TYPE_INFO;
+
+typedef struct _TI_FINDCHILDREN_PARAMS {
+    ULONG Count;
+    ULONG Start;
+    ULONG ChildId[1];
+} TI_FINDCHILDREN_PARAMS;
+
+BOOL
+IMAGEAPI
+SymGetTypeInfo(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 ModBase,
+    _In_ ULONG TypeId,
+    _In_ IMAGEHLP_SYMBOL_TYPE_INFO GetType,
+    _Out_ PVOID pInfo
+    );
+
+#define IMAGEHLP_GET_TYPE_INFO_UNCACHED 0x00000001
+#define IMAGEHLP_GET_TYPE_INFO_CHILDREN 0x00000002
+
+typedef struct _IMAGEHLP_GET_TYPE_INFO_PARAMS {
+    IN  ULONG    SizeOfStruct;
+    IN  ULONG    Flags;
+    IN  ULONG    NumIds;
+    IN  PULONG   TypeIds;
+    IN  ULONG64  TagFilter;
+    IN  ULONG    NumReqs;
+    IN  IMAGEHLP_SYMBOL_TYPE_INFO* ReqKinds;
+    IN  PULONG_PTR ReqOffsets;
+    IN  PULONG   ReqSizes;
+    IN  ULONG_PTR ReqStride;
+    IN  ULONG_PTR BufferSize;
+    OUT PVOID    Buffer;
+    OUT ULONG    EntriesMatched;
+    OUT ULONG    EntriesFilled;
+    OUT ULONG64  TagsFound;
+    OUT ULONG64  AllReqsValid;
+    IN  ULONG    NumReqsValid;
+    OUT PULONG64 ReqsValid OPTIONAL;
+} IMAGEHLP_GET_TYPE_INFO_PARAMS, *PIMAGEHLP_GET_TYPE_INFO_PARAMS;
+
+BOOL
+IMAGEAPI
+SymGetTypeInfoEx(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 ModBase,
+    _Inout_ PIMAGEHLP_GET_TYPE_INFO_PARAMS Params
+    );
+
+BOOL
+IMAGEAPI
+SymEnumTypes(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumTypesW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumTypesByName(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ PCSTR mask,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymEnumTypesByNameW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ PCWSTR mask,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+BOOL
+IMAGEAPI
+SymGetTypeFromName(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ PCSTR Name,
+    _Inout_ PSYMBOL_INFO Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymGetTypeFromNameW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ PCWSTR Name,
+    _Inout_ PSYMBOL_INFOW Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymAddSymbol(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ PCSTR Name,
+    _In_ DWORD64 Address,
+    _In_ DWORD Size,
+    _In_ DWORD Flags
+    );
+
+BOOL
+IMAGEAPI
+SymAddSymbolW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ PCWSTR Name,
+    _In_ DWORD64 Address,
+    _In_ DWORD Size,
+    _In_ DWORD Flags
+    );
+
+BOOL
+IMAGEAPI
+SymDeleteSymbol(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ PCSTR Name,
+    _In_ DWORD64 Address,
+    _In_ DWORD Flags
+    );
+
+BOOL
+IMAGEAPI
+SymDeleteSymbolW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_opt_ PCWSTR Name,
+    _In_ DWORD64 Address,
+    _In_ DWORD Flags
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+BOOL
+IMAGEAPI
+SymRefreshModuleList(
+    _In_ HANDLE hProcess
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+BOOL
+IMAGEAPI
+SymAddSourceStream(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_opt_ PCSTR StreamFile,
+    _In_reads_bytes_opt_(Size) PBYTE Buffer,
+    _In_ size_t Size
+    );
+
+typedef BOOL (WINAPI *SYMADDSOURCESTREAM)(HANDLE, ULONG64, PCSTR, PBYTE, size_t);
+
+BOOL
+IMAGEAPI
+SymAddSourceStreamA(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_opt_ PCSTR StreamFile,
+    _In_reads_bytes_opt_(Size) PBYTE Buffer,
+    _In_ size_t Size
+    );
+
+typedef BOOL (WINAPI *SYMADDSOURCESTREAMA)(HANDLE, ULONG64, PCSTR, PBYTE, size_t);
+
+BOOL
+IMAGEAPI
+SymAddSourceStreamW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 Base,
+    _In_opt_ PCWSTR FileSpec,
+    _In_reads_bytes_opt_(Size) PBYTE Buffer,
+    _In_ size_t Size
+    );
+
+BOOL
+IMAGEAPI
+SymSrvIsStoreW(
+    _In_opt_ HANDLE hProcess,
+    _In_ PCWSTR path
+    );
+
+BOOL
+IMAGEAPI
+SymSrvIsStore(
+    _In_opt_ HANDLE hProcess,
+    _In_ PCSTR path
+    );
+
+PCSTR
+IMAGEAPI
+SymSrvDeltaName(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR SymPath,
+    _In_ PCSTR Type,
+    _In_ PCSTR File1,
+    _In_ PCSTR File2
+    );
+
+PCWSTR
+IMAGEAPI
+SymSrvDeltaNameW(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCWSTR SymPath,
+    _In_ PCWSTR Type,
+    _In_ PCWSTR File1,
+    _In_ PCWSTR File2
+    );
+
+PCSTR
+IMAGEAPI
+SymSrvGetSupplement(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR SymPath,
+    _In_ PCSTR Node,
+    _In_ PCSTR File
+    );
+
+PCWSTR
+IMAGEAPI
+SymSrvGetSupplementW(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCWSTR SymPath,
+    _In_ PCWSTR Node,
+    _In_ PCWSTR File
+    );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexes(
+    _In_ PCSTR File,
+    _Out_ GUID *Id,
+    _Out_ PDWORD Val1,
+    _Out_opt_ PDWORD Val2,
+    _In_ DWORD Flags
+    );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexesW(
+    _In_ PCWSTR File,
+    _Out_ GUID *Id,
+    _Out_ PDWORD Val1,
+    _Out_opt_ PDWORD Val2,
+    _In_ DWORD Flags
+    );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexStringW(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCWSTR SrvPath,
+    _In_ PCWSTR File,
+    _Out_writes_(Size) PWSTR Index,
+    _In_ size_t Size,
+    _In_ DWORD Flags
+    );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexString(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR SrvPath,
+    _In_ PCSTR File,
+    _Out_writes_(Size) PSTR Index,
+    _In_ size_t Size,
+    _In_ DWORD Flags
+    );
+
+typedef struct {
+    DWORD sizeofstruct;
+    char file[MAX_PATH +1];
+    BOOL  stripped;
+    DWORD timestamp;
+    DWORD size;
+    char dbgfile[MAX_PATH +1];
+    char pdbfile[MAX_PATH + 1];
+    GUID  guid;
+    DWORD sig;
+    DWORD age;
+} SYMSRV_INDEX_INFO, *PSYMSRV_INDEX_INFO;
+
+typedef struct {
+    DWORD sizeofstruct;
+    WCHAR file[MAX_PATH +1];
+    BOOL  stripped;
+    DWORD timestamp;
+    DWORD size;
+    WCHAR dbgfile[MAX_PATH +1];
+    WCHAR pdbfile[MAX_PATH + 1];
+    GUID  guid;
+    DWORD sig;
+    DWORD age;
+} SYMSRV_INDEX_INFOW, *PSYMSRV_INDEX_INFOW;
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexInfo(
+    _In_ PCSTR File,
+    _Out_ PSYMSRV_INDEX_INFO Info,
+    _In_ DWORD Flags
+    );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexInfoW(
+    _In_ PCWSTR File,
+    _Out_ PSYMSRV_INDEX_INFOW Info,
+    _In_ DWORD Flags
+    );
+
+PCSTR
+IMAGEAPI
+SymSrvStoreSupplement(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR SrvPath,
+    _In_ PCSTR Node,
+    _In_ PCSTR File,
+    _In_ DWORD Flags
+    );
+
+PCWSTR
+IMAGEAPI
+SymSrvStoreSupplementW(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCWSTR SymPath,
+    _In_ PCWSTR Node,
+    _In_ PCWSTR File,
+    _In_ DWORD Flags
+    );
+
+PCSTR
+IMAGEAPI
+SymSrvStoreFile(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCSTR SrvPath,
+    _In_ PCSTR File,
+    _In_ DWORD Flags
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+PCWSTR
+IMAGEAPI
+SymSrvStoreFileW(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCWSTR SrvPath,
+    _In_ PCWSTR File,
+    _In_ DWORD Flags
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+// used by SymGetSymbolFile's "Type" parameter
+
+typedef enum {
+    sfImage = 0,
+    sfDbg,
+    sfPdb,
+    sfMpd,
+    sfMax
+} IMAGEHLP_SF_TYPE;
+
+BOOL
+IMAGEAPI
+SymGetSymbolFile(
+    _In_opt_ HANDLE hProcess,
+    _In_opt_ PCSTR SymPath,
+    _In_ PCSTR ImageFile,
+    _In_ DWORD Type,
+    _Out_writes_(cSymbolFile) PSTR SymbolFile,
+    _In_ size_t cSymbolFile,
+    _Out_writes_(cDbgFile) PSTR DbgFile,
+    _In_ size_t cDbgFile
+    );
+
+BOOL
+IMAGEAPI
+SymGetSymbolFileW(
+    _In_opt_ HANDLE hProcess,
+    _In_opt_ PCWSTR SymPath,
+    _In_ PCWSTR ImageFile,
+    _In_ DWORD Type,
+    _Out_writes_(cSymbolFile) PWSTR SymbolFile,
+    _In_ size_t cSymbolFile,
+    _Out_writes_(cDbgFile) PWSTR DbgFile,
+    _In_ size_t cDbgFile
+    );
+
+//
+// Full user-mode dump creation.
+//
+
+typedef BOOL (WINAPI *PDBGHELP_CREATE_USER_DUMP_CALLBACK)(
+    _In_ DWORD DataType,
+    _In_ PVOID* Data,
+    _Out_ LPDWORD DataLength,
+    _In_opt_ PVOID UserData
+    );
+
+BOOL
+WINAPI
+DbgHelpCreateUserDump(
+    _In_opt_ LPCSTR FileName,
+    _In_ PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,
+    _In_opt_ PVOID UserData
+    );
+
+BOOL
+WINAPI
+DbgHelpCreateUserDumpW(
+    _In_opt_ LPCWSTR FileName,
+    _In_ PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,
+    _In_opt_ PVOID UserData
+    );
+
+// -----------------------------------------------------------------
+// The following 4 legacy APIs are fully supported, but newer
+// ones are recommended.  SymFromName and SymFromAddr provide
+// much more detailed info on the returned symbol.
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family or Games Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+BOOL
+IMAGEAPI
+SymGetSymFromAddr64(
+    _In_ HANDLE hProcess,
+    _In_ DWORD64 qwAddr,
+    _Out_opt_ PDWORD64 pdwDisplacement,
+    _Inout_ PIMAGEHLP_SYMBOL64  Symbol
+    );
+
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetSymFromAddr SymGetSymFromAddr64
+#else
+BOOL
+IMAGEAPI
+SymGetSymFromAddr(
+    _In_ HANDLE hProcess,
+    _In_ DWORD dwAddr,
+    _Out_opt_ PDWORD pdwDisplacement,
+    _Inout_ PIMAGEHLP_SYMBOL Symbol
+    );
+#endif
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+// While following two APIs will provide a symbol from a name,
+// SymEnumSymbols can provide the same matching information
+// for ALL symbols with a matching name, even regular
+// expressions.  That way you can search across modules
+// and differentiate between identically named symbols.
+
+BOOL
+IMAGEAPI
+SymGetSymFromName64(
+    _In_ HANDLE hProcess,
+    _In_ PCSTR Name,
+    _Inout_ PIMAGEHLP_SYMBOL64 Symbol
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetSymFromName SymGetSymFromName64
+#else
+BOOL
+IMAGEAPI
+SymGetSymFromName(
+    _In_ HANDLE hProcess,
+    _In_ PCSTR Name,
+    _Inout_ PIMAGEHLP_SYMBOL Symbol
+    );
+#endif
+
+
+// Symbol server exports
+
+//  This is the version of the SYMSRV_EXTENDED_OUTPUT_DATA structure.
+#define EXT_OUTPUT_VER          1
+
+//  This structure indicates the Extended Symsrv.dll output data structure
+typedef struct
+{
+    DWORD   sizeOfStruct;           // size of the structure
+    DWORD   version;                // version number (EXT_OUTPUT_VER)
+    WCHAR   filePtrMsg[MAX_PATH + 1]; // File ptr message data buffer
+} SYMSRV_EXTENDED_OUTPUT_DATA, *PSYMSRV_EXTENDED_OUTPUT_DATA;
+
+typedef BOOL (WINAPI *PSYMBOLSERVERPROC)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERPROCA)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERPROCW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROC)(PCSTR, PCSTR, PCSTR, PSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCA)(PCSTR, PCSTR, PCSTR, PSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCW)(PCWSTR, PCWSTR, PCWSTR, PWSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVEROPENPROC)(VOID);
+typedef BOOL (WINAPI *PSYMBOLSERVERCLOSEPROC)(VOID);
+typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64);
+typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSWPROC)(UINT_PTR, ULONG64);
+typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action, ULONG64 data, ULONG64 context);
+typedef UINT_PTR (WINAPI *PSYMBOLSERVERGETOPTIONSPROC)();
+typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROC)(PCSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCA)(PCSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCW)(PCWSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETVERSION)(LPAPI_VERSION);
+typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAME)(PCSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAMEW)(PCWSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PWSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t, DWORD);
+typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t, DWORD);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRING)(PVOID, DWORD, DWORD, PSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRINGW)(PVOID, DWORD, DWORD, PWSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILE)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR, size_t, DWORD);
+typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILEW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR, size_t, DWORD);
+typedef BOOL (WINAPI *PSYMBOLSERVERISSTORE)(PCSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERISSTOREW)(PCWSTR);
+typedef DWORD (WINAPI *PSYMBOLSERVERVERSION)();
+typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERMESSAGEPROC)(UINT_PTR action, ULONG64 data, ULONG64 context);
+typedef BOOL (WINAPI *PSYMBOLSERVERWEXPROC)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR, PSYMSRV_EXTENDED_OUTPUT_DATA);
+typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCWEX)(PCWSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETOPTIONDATAPROC)(UINT_PTR, PULONG64);
+typedef BOOL (WINAPI *PSYMBOLSERVERSETHTTPAUTHHEADER)(_In_ PCWSTR pszAuthHeader);
+
+#define SYMSRV_VERSION              2
+
+#define SSRVOPT_CALLBACK            0x00000001
+#define SSRVOPT_DWORD               0x00000002
+#define SSRVOPT_DWORDPTR            0x00000004
+#define SSRVOPT_GUIDPTR             0x00000008
+#define SSRVOPT_OLDGUIDPTR          0x00000010
+#define SSRVOPT_UNATTENDED          0x00000020
+#define SSRVOPT_NOCOPY              0x00000040
+#define SSRVOPT_GETPATH             0x00000040
+#define SSRVOPT_PARENTWIN           0x00000080
+#define SSRVOPT_PARAMTYPE           0x00000100
+#define SSRVOPT_SECURE              0x00000200
+#define SSRVOPT_TRACE               0x00000400
+#define SSRVOPT_SETCONTEXT          0x00000800
+#define SSRVOPT_PROXY               0x00001000
+#define SSRVOPT_DOWNSTREAM_STORE    0x00002000
+#define SSRVOPT_OVERWRITE           0x00004000
+#define SSRVOPT_RESETTOU            0x00008000
+#define SSRVOPT_CALLBACKW           0x00010000
+#define SSRVOPT_FLAT_DEFAULT_STORE  0x00020000
+#define SSRVOPT_PROXYW              0x00040000
+#define SSRVOPT_MESSAGE             0x00080000
+#define SSRVOPT_SERVICE             0x00100000   // deprecated
+#define SSRVOPT_FAVOR_COMPRESSED    0x00200000
+#define SSRVOPT_STRING              0x00400000
+#define SSRVOPT_WINHTTP             0x00800000
+#define SSRVOPT_WININET             0x01000000
+#define SSRVOPT_DONT_UNCOMPRESS     0x02000000
+#define SSRVOPT_DISABLE_PING_HOST   0x04000000
+#define SSRVOPT_DISABLE_TIMEOUT     0x08000000
+#define SSRVOPT_ENABLE_COMM_MSG     0x10000000
+#define SSRVOPT_URI_FILTER          0x20000000
+#define SSRVOPT_URI_TIERS           0x40000000
+#define SSRVOPT_RETRY_APP_HANG      0x80000000
+
+#define SSRVOPT_MAX                 0x80000000
+
+#define SSRVOPT_RESET               ((ULONG_PTR)-1)
+
+#define NUM_SSRVOPTS                32
+
+#define SSRVURI_HTTP_NORMAL         0x01
+#define SSRVURI_HTTP_COMPRESSED     0x02
+#define SSRVURI_HTTP_FILEPTR        0x04
+
+#define SSRVURI_UNC_NORMAL          0x10
+#define SSRVURI_UNC_COMPRESSED      0x20
+#define SSRVURI_UNC_FILEPTR         0x40
+
+#define SSRVURI_HTTP_MASK           0x0F
+#define SSRVURI_UNC_MASK            0xF0
+#define SSRVURI_ALL                 0xFF
+
+// Legacy Names
+#define SSRVURI_NORMAL              SSRVURI_HTTP_NORMAL
+#define SSRVURI_COMPRESSED          SSRVURI_HTTP_COMPRESSED
+#define SSRVURI_FILEPTR             SSRVURI_HTTP_FILEPTR
+
+#define SSRVACTION_TRACE            1
+#define SSRVACTION_QUERYCANCEL      2
+#define SSRVACTION_EVENT            3
+#define SSRVACTION_EVENTW           4
+#define SSRVACTION_SIZE             5
+#define SSRVACTION_HTTPSTATUS       6
+#define SSRVACTION_XMLOUTPUT        7
+#define SSRVACTION_CHECKSUMSTATUS   8
+
+#endif WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+#pragma endregion
+
+#pragma region Application Family or OneCore Family or Games Family
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
+ #define SYMSTOREOPT_COMPRESS        0x01
+ #define SYMSTOREOPT_OVERWRITE       0x02
+ #define SYMSTOREOPT_RETURNINDEX     0x04
+ #define SYMSTOREOPT_POINTER         0x08
+ #define SYMSTOREOPT_ALT_INDEX       0x10
+ #define SYMSTOREOPT_UNICODE         0x20
+ #define SYMSTOREOPT_PASS_IF_EXISTS  0x40
+
+#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+#ifdef DBGHELP_TRANSLATE_TCHAR
+ #define SymInitialize                     SymInitializeW
+ #define SymAddSymbol                      SymAddSymbolW
+ #define SymDeleteSymbol                   SymDeleteSymbolW
+ #define SearchTreeForFile                 SearchTreeForFileW
+ #define UnDecorateSymbolName              UnDecorateSymbolNameW
+ #define SymGetLineFromName64              SymGetLineFromNameW64
+ #define SymGetLineFromAddr64              SymGetLineFromAddrW64
+ #define SymGetLineFromInlineContext       SymGetLineFromInlineContextW
+ #define SymGetLineNext64                  SymGetLineNextW64
+ #define SymGetLinePrev64                  SymGetLinePrevW64
+ #define SymFromName                       SymFromNameW
+ #define SymFindExecutableImage            SymFindExecutableImageW
+ #define FindExecutableImageEx             FindExecutableImageExW
+ #define SymSearch                         SymSearchW
+ #define SymEnumLines                      SymEnumLinesW
+ #define SymEnumSourceLines                SymEnumSourceLinesW
+ #define SymGetTypeFromName                SymGetTypeFromNameW
+ #define SymEnumSymbolsForAddr             SymEnumSymbolsForAddrW
+ #define SymFromAddr                       SymFromAddrW
+ #define SymFromInlineContext              SymFromInlineContextW
+ #define SymMatchString                    SymMatchStringW
+ #define SymEnumSourceFiles                SymEnumSourceFilesW
+ #define SymEnumSymbols                    SymEnumSymbolsW
+ #define SymEnumSymbolsEx                  SymEnumSymbolsExW
+ #define SymLoadModuleEx                   SymLoadModuleExW
+ #define SymSetSearchPath                  SymSetSearchPathW
+ #define SymGetSearchPath                  SymGetSearchPathW
+ #define EnumDirTree                       EnumDirTreeW
+ #define SymFromToken                      SymFromTokenW
+ #define SymFromIndex                      SymFromIndexW
+ #define SymGetScope                       SymGetScopeW
+ #define SymNext                           SymNextW
+ #define SymPrev                           SymPrevW
+ #define SymEnumTypes                      SymEnumTypesW
+ #define SymEnumTypesByName                SymEnumTypesByNameW
+ #define SymRegisterCallback64             SymRegisterCallbackW64
+ #define SymFindDebugInfoFile              SymFindDebugInfoFileW
+ #define FindDebugInfoFileEx               FindDebugInfoFileExW
+ #define SymFindFileInPath                 SymFindFileInPathW
+ #define SymEnumerateModules64             SymEnumerateModulesW64
+ #define SymSetHomeDirectory               SymSetHomeDirectoryW
+ #define SymGetHomeDirectory               SymGetHomeDirectoryW
+ #define SymGetSourceFile                  SymGetSourceFileW
+ #define SymGetSourceFileToken             SymGetSourceFileTokenW
+ #define SymGetSourceFileFromToken         SymGetSourceFileFromTokenW
+ #define SymGetSourceVarFromToken          SymGetSourceVarFromTokenW
+ #define SymGetSourceFileToken             SymGetSourceFileTokenW
+ #define SymGetFileLineOffsets64           SymGetFileLineOffsetsW64
+ #define SymFindFileInPath                 SymFindFileInPathW
+ #define SymMatchFileName                  SymMatchFileNameW
+ #define SymGetSourceFileFromToken         SymGetSourceFileFromTokenW
+ #define SymGetSourceVarFromToken          SymGetSourceVarFromTokenW
+ #define SymGetModuleInfo64                SymGetModuleInfoW64
+ #define SymAddSourceStream                SymAddSourceStreamW
+ #define SymSrvIsStore                     SymSrvIsStoreW
+ #define SymSrvDeltaName                   SymSrvDeltaNameW
+ #define SymSrvGetSupplement               SymSrvGetSupplementW
+ #define SymSrvStoreSupplement             SymSrvStoreSupplementW
+ #define SymSrvGetFileIndexes              SymSrvGetFileIndexes
+ #define SymSrvGetFileIndexString          SymSrvGetFileIndexStringW
+ #define SymSrvStoreFile                   SymSrvStoreFileW
+ #define SymGetSymbolFile                  SymGetSymbolFileW
+ #define EnumerateLoadedModules64          EnumerateLoadedModulesW64
+ #define EnumerateLoadedModulesEx          EnumerateLoadedModulesExW
+ #define SymSrvGetFileIndexInfo            SymSrvGetFileIndexInfoW
+
+ #define IMAGEHLP_LINE64                   IMAGEHLP_LINEW64
+ #define PIMAGEHLP_LINE64                  PIMAGEHLP_LINEW64
+ #define SYMBOL_INFO                       SYMBOL_INFOW
+ #define PSYMBOL_INFO                      PSYMBOL_INFOW
+ #define SYMBOL_INFO_PACKAGE               SYMBOL_INFO_PACKAGEW
+ #define PSYMBOL_INFO_PACKAGE              PSYMBOL_INFO_PACKAGEW
+ #define FIND_EXE_FILE_CALLBACK            FIND_EXE_FILE_CALLBACKW
+ #define PFIND_EXE_FILE_CALLBACK           PFIND_EXE_FILE_CALLBACKW
+ #define SYM_ENUMERATESYMBOLS_CALLBACK     SYM_ENUMERATESYMBOLS_CALLBACKW
+ #define PSYM_ENUMERATESYMBOLS_CALLBACK    PSYM_ENUMERATESYMBOLS_CALLBACKW
+ #define SRCCODEINFO                       SRCCODEINFOW
+ #define PSRCCODEINFO                      PSRCCODEINFOW
+ #define SOURCEFILE                        SOURCEFILEW
+ #define PSOURCEFILE                       PSOURCEFILEW
+ #define SYM_ENUMSOURECFILES_CALLBACK      SYM_ENUMSOURCEFILES_CALLBACKW
+ #define PSYM_ENUMSOURCEFILES_CALLBACK     PSYM_ENUMSOURECFILES_CALLBACKW
+ #define IMAGEHLP_CBA_EVENT                IMAGEHLP_CBA_EVENTW
+ #define PIMAGEHLP_CBA_EVENT               PIMAGEHLP_CBA_EVENTW
+ #define PENUMDIRTREE_CALLBACK             PENUMDIRTREE_CALLBACKW
+ #define IMAGEHLP_DEFERRED_SYMBOL_LOAD64   IMAGEHLP_DEFERRED_SYMBOL_LOADW64
+ #define PIMAGEHLP_DEFERRED_SYMBOL_LOAD64  PIMAGEHLP_DEFERRED_SYMBOL_LOADW64
+ #define PFIND_DEBUG_FILE_CALLBACK         PFIND_DEBUG_FILE_CALLBACKW
+ #define PFINDFILEINPATHCALLBACK           PFINDFILEINPATHCALLBACKW
+ #define IMAGEHLP_MODULE64                 IMAGEHLP_MODULEW64
+ #define PIMAGEHLP_MODULE64                PIMAGEHLP_MODULEW64
+ #define SYMSRV_INDEX_INFO                 SYMSRV_INDEX_INFOW
+ #define PSYMSRV_INDEX_INFO                PSYMSRV_INDEX_INFOW
+
+ #define PSYMBOLSERVERPROC                 PSYMBOLSERVERPROCW
+ #define PSYMBOLSERVERPINGPROC             PSYMBOLSERVERPINGPROCW
+
+#pragma endregion
+#endif WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS)
+
+
+// -----------------------------------------------------------------
+// The following APIs exist only for backwards compatibility
+// with a pre-release version documented in an MSDN release.
+
+// You should use SymFindFileInPath if you want to maintain
+// future compatibility.
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+FindFileInPath(
+    _In_ HANDLE hprocess,
+    _In_ PCSTR SearchPath,
+    _In_ PCSTR FileName,
+    _In_ PVOID id,
+    _In_ DWORD two,
+    _In_ DWORD three,
+    _In_ DWORD flags,
+    _Out_writes_(MAX_PATH + 1) PSTR FilePath
+    );
+
+// You should use SymFindFileInPath if you want to maintain
+// future compatibility.
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+FindFileInSearchPath(
+    _In_ HANDLE hprocess,
+    _In_ PCSTR SearchPath,
+    _In_ PCSTR FileName,
+    _In_ DWORD one,
+    _In_ DWORD two,
+    _In_ DWORD three,
+    _Out_writes_(MAX_PATH + 1) PSTR FilePath
+    );
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumSym(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumerateSymbols64(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumerateSymbolsW64(
+    _In_ HANDLE hProcess,
+    _In_ ULONG64 BaseOfDll,
+    _In_ PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymEnumerateSymbols SymEnumerateSymbols64
+#define SymEnumerateSymbolsW SymEnumerateSymbolsW64
+#else
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumerateSymbols(
+    _In_ HANDLE hProcess,
+    _In_ ULONG BaseOfDll,
+    _In_ PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumerateSymbolsW(
+    _In_ HANDLE hProcess,
+    _In_ ULONG BaseOfDll,
+    _In_ PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback,
+    _In_opt_ PVOID UserContext
+    );
+#endif
+
+// use SymLoadModuleEx
+
+DWORD64
+IMAGEAPI
+SymLoadModule64(
+    _In_ HANDLE hProcess,
+    _In_opt_ HANDLE hFile,
+    _In_opt_ PCSTR ImageName,
+    _In_opt_ PCSTR ModuleName,
+    _In_ DWORD64 BaseOfDll,
+    _In_ DWORD SizeOfDll
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymLoadModule SymLoadModule64
+#else
+DWORD
+IMAGEAPI
+SymLoadModule(
+    _In_ HANDLE hProcess,
+    _In_opt_ HANDLE hFile,
+    _In_opt_ PCSTR ImageName,
+    _In_opt_ PCSTR ModuleName,
+    _In_ DWORD BaseOfDll,
+    _In_ DWORD SizeOfDll
+    );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetSymNext64(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_SYMBOL64 Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymGetSymNextW64(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_SYMBOLW64 Symbol
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetSymNext SymGetSymNext64
+#define SymGetSymNextW SymGetSymNextW64
+#else
+BOOL
+IMAGEAPI
+SymGetSymNext(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_SYMBOL Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymGetSymNextW(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_SYMBOLW Symbol
+    );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetSymPrev64(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_SYMBOL64 Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymGetSymPrevW64(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_SYMBOLW64 Symbol
+    );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetSymPrev SymGetSymPrev64
+#define SymGetSymPrevW SymGetSymPrevW64
+#else
+BOOL
+IMAGEAPI
+SymGetSymPrev(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_SYMBOL Symbol
+    );
+
+BOOL
+IMAGEAPI
+SymGetSymPrevW(
+    _In_ HANDLE hProcess,
+    _Inout_ PIMAGEHLP_SYMBOLW Symbol
+    );
+#endif
+
+
+//  This type indicates the call back function type
+typedef ULONG (__stdcall *LPCALL_BACK_USER_INTERRUPT_ROUTINE )(VOID);
+
+//  Extra data to report for the symbol load summary
+typedef struct
+{
+    PCWSTR pBinPathNonExist;
+    PCWSTR pSymbolPathNonExist;
+}DBGHELP_DATA_REPORT_STRUCT, *PDBGHELP_DATA_REPORT_STRUCT;
+
+void
+IMAGEAPI
+SetCheckUserInterruptShared(
+    _In_ LPCALL_BACK_USER_INTERRUPT_ROUTINE lpStartAddress
+    );
+
+LPCALL_BACK_USER_INTERRUPT_ROUTINE
+IMAGEAPI
+GetCheckUserInterruptShared(
+    void
+    );
+
+DWORD
+IMAGEAPI
+GetSymLoadError(
+    void
+    );
+
+void
+IMAGEAPI
+SetSymLoadError(
+    _In_ DWORD error
+    );
+
+BOOL
+IMAGEAPI
+ReportSymbolLoadSummary(
+    _In_ HANDLE hProcess,
+    _In_opt_ PCWSTR pLoadModule,
+    _In_ PDBGHELP_DATA_REPORT_STRUCT pSymbolData
+    );
+
+void
+IMAGEAPI
+RemoveInvalidModuleList(
+    _In_ HANDLE hProcess
+    );
+
+// These values should not be used.
+// They have been replaced by SYMFLAG_ values.
+
+#define SYMF_OMAP_GENERATED   0x00000001
+#define SYMF_OMAP_MODIFIED    0x00000002
+#define SYMF_REGISTER         0x00000008
+#define SYMF_REGREL           0x00000010
+#define SYMF_FRAMEREL         0x00000020
+#define SYMF_PARAMETER        0x00000040
+#define SYMF_LOCAL            0x00000080
+#define SYMF_CONSTANT         0x00000100
+#define SYMF_EXPORT           0x00000200
+#define SYMF_FORWARDER        0x00000400
+#define SYMF_FUNCTION         0x00000800
+#define SYMF_VIRTUAL          0x00001000
+#define SYMF_THUNK            0x00002000
+#define SYMF_TLSREL           0x00004000
+
+// These values should also not be used.
+// They have been replaced by SYMFLAG_ values.
+
+#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT          1
+#define IMAGEHLP_SYMBOL_INFO_REGISTER              SYMF_REGISTER        // 0x0008
+#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE           SYMF_REGREL          // 0x0010
+#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE         SYMF_FRAMEREL        // 0x0020
+#define IMAGEHLP_SYMBOL_INFO_PARAMETER             SYMF_PARAMETER       // 0x0040
+#define IMAGEHLP_SYMBOL_INFO_LOCAL                 SYMF_LOCAL           // 0x0080
+#define IMAGEHLP_SYMBOL_INFO_CONSTANT              SYMF_CONSTANT        // 0x0100
+#define IMAGEHLP_SYMBOL_FUNCTION                   SYMF_FUNCTION        // 0x0800
+#define IMAGEHLP_SYMBOL_VIRTUAL                    SYMF_VIRTUAL         // 0x1000
+#define IMAGEHLP_SYMBOL_THUNK                      SYMF_THUNK           // 0x2000
+#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE           SYMF_TLSREL          // 0x4000
+
+//
+// RangeMap APIs.
+//
+PVOID
+IMAGEAPI
+RangeMapCreate(
+    VOID
+    );
+
+VOID
+IMAGEAPI
+RangeMapFree(
+    _In_opt_ PVOID RmapHandle
+    );
+
+#define IMAGEHLP_RMAP_MAPPED_FLAT                   0x00000001
+#define IMAGEHLP_RMAP_BIG_ENDIAN                    0x00000002
+#define IMAGEHLP_RMAP_IGNORE_MISCOMPARE             0x00000004
+
+#define IMAGEHLP_RMAP_LOAD_RW_DATA_SECTIONS         0x20000000
+#define IMAGEHLP_RMAP_OMIT_SHARED_RW_DATA_SECTIONS  0x40000000
+#define IMAGEHLP_RMAP_FIXUP_IMAGEBASE               0x80000000
+
+BOOL
+IMAGEAPI
+RangeMapAddPeImageSections(
+    _In_ PVOID RmapHandle,
+    _In_opt_ PCWSTR ImageName,
+    _In_reads_bytes_(MappingBytes) PVOID MappedImage,
+    _In_ DWORD MappingBytes,
+    _In_ DWORD64 ImageBase,
+    _In_ DWORD64 UserTag,
+    _In_ DWORD MappingFlags
+    );
+
+BOOL
+IMAGEAPI
+RangeMapRemove(
+    _In_ PVOID RmapHandle,
+    _In_ DWORD64 UserTag
+    );
+
+BOOL
+IMAGEAPI
+RangeMapRead(
+    _In_ PVOID RmapHandle,
+    _In_ DWORD64 Offset,
+    _Out_writes_bytes_to_(RequestBytes, *DoneBytes) PVOID Buffer,
+    _In_ DWORD RequestBytes,
+    _In_ DWORD Flags,
+    _Out_opt_ PDWORD DoneBytes
+    );
+
+BOOL
+IMAGEAPI
+RangeMapWrite(
+    _In_ PVOID RmapHandle,
+    _In_ DWORD64 Offset,
+    _In_reads_bytes_(RequestBytes) PVOID Buffer,
+    _In_ DWORD RequestBytes,
+    _In_ DWORD Flags,
+    _Out_opt_ PDWORD DoneBytes
+    );
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS | WINAPI_PARTITION_GAMES)
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <poppack.h>
+
+
+#include <minidumpapiset.h>
+
+
+#endif /* WINAPI_FAMILY_PARTITION(NONGAMESPARTITIONS) */
+#pragma endregion
+
+#endif // _DBGHELP_
diff --git a/src/SOS/inc/dbgeng/wdbgexts.h b/src/SOS/inc/dbgeng/wdbgexts.h
new file mode 100644 (file)
index 0000000..33a12b5
--- /dev/null
@@ -0,0 +1,2862 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+    wdbgexts.h
+
+Abstract:
+
+    This file contains the necessary prototypes and data types for a user
+    to write a debugger extension DLL.  This header file is also included
+    by the NT debuggers (WINDBG & KD).
+
+    This header file must be included after "windows.h" and "dbghelp.h".
+
+    Please see the NT DDK documentation for specific information about
+    how to write your own debugger extension DLL.
+
+Environment:
+
+    Win32 only.
+
+Revision History:
+
+--*/
+
+//@[contract("wdbgexts"), comment("MVI_tracked - https://osgwiki.com/wiki/Microsoft_Virus_Initiative")];
+
+#ifndef _WDBGEXTS_
+#define _WDBGEXTS_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+#include <winapifamily.h>
+
+#pragma region Desktop Family
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if _MSC_VER >= 1200
+#pragma warning(push)
+#endif
+#pragma warning(disable:4115 4201 4204 4214 4221)
+#pragma warning(disable:4668) // #if not_defined treated as #if 0
+#pragma warning(disable:4820) // padding added
+
+// Maximum value of MAXIMUM_PROCESSORS for all platforms.
+// NB: Keep in sync with extsfns.w/h (the !analyze public header)
+#define CROSS_PLATFORM_MAXIMUM_PROCESSORS 2048
+
+#if !defined(WDBGAPI)
+#define WDBGAPI __stdcall
+#endif
+
+#if !defined(WDBGAPIV)
+#define WDBGAPIV __cdecl
+#endif
+
+#ifndef _WINDEF_
+typedef CONST void *LPCVOID;
+#endif
+
+#ifndef _ULONGLONG_
+typedef unsigned __int64 ULONGLONG;
+typedef ULONGLONG *PULONGLONG;
+#endif
+
+#define WDBGEXTS_MAXSIZE_T ((SIZE_T)~((SIZE_T)0))
+
+typedef
+VOID
+(WDBGAPIV*PWINDBG_OUTPUT_ROUTINE)(
+    PCSTR lpFormat,
+    ...
+    );
+
+typedef
+ULONG_PTR
+(WDBGAPI*PWINDBG_GET_EXPRESSION)(
+    PCSTR lpExpression
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_GET_EXPRESSION32)(
+    PCSTR lpExpression
+    );
+
+typedef
+ULONG64
+(WDBGAPI*PWINDBG_GET_EXPRESSION64)(
+    PCSTR lpExpression
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_GET_SYMBOL)(
+    PVOID      offset,
+    PCHAR      pchBuffer,
+    ULONG_PTR *pDisplacement
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_GET_SYMBOL32)(
+    ULONG      offset,
+    PCHAR      pchBuffer,
+    PULONG     pDisplacement
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_GET_SYMBOL64)(
+    ULONG64    offset,
+    PCHAR      pchBuffer,
+    PULONG64   pDisplacement
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_DISASM)(
+    ULONG_PTR *lpOffset,
+    PCSTR      lpBuffer,
+    ULONG      fShowEffectiveAddress
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_DISASM32)(
+    ULONG     *lpOffset,
+    PCSTR      lpBuffer,
+    ULONG      fShowEffectiveAddress
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_DISASM64)(
+    ULONG64   *lpOffset,
+    PCSTR      lpBuffer,
+    ULONG      fShowEffectiveAddress
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_CHECK_CONTROL_C)(
+    VOID
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_READ_PROCESS_MEMORY_ROUTINE)(
+    ULONG_PTR  offset,
+    PVOID      lpBuffer,
+    ULONG      cb,
+    PULONG     lpcbBytesRead
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_READ_PROCESS_MEMORY_ROUTINE32)(
+    ULONG      offset,
+    PVOID      lpBuffer,
+    ULONG      cb,
+    PULONG     lpcbBytesRead
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_READ_PROCESS_MEMORY_ROUTINE64)(
+    ULONG64    offset,
+    PVOID      lpBuffer,
+    ULONG      cb,
+    PULONG     lpcbBytesRead
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE)(
+    ULONG_PTR  offset,
+    LPCVOID    lpBuffer,
+    ULONG      cb,
+    PULONG     lpcbBytesWritten
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE32)(
+    ULONG      offset,
+    LPCVOID    lpBuffer,
+    ULONG      cb,
+    PULONG     lpcbBytesWritten
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE64)(
+    ULONG64    offset,
+    LPCVOID    lpBuffer,
+    ULONG      cb,
+    PULONG     lpcbBytesWritten
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_GET_THREAD_CONTEXT_ROUTINE)(
+    ULONG       Processor,
+    PCONTEXT    lpContext,
+    ULONG       cbSizeOfContext
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_SET_THREAD_CONTEXT_ROUTINE)(
+    ULONG       Processor,
+    PCONTEXT    lpContext,
+    ULONG       cbSizeOfContext
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_IOCTL_ROUTINE)(
+    USHORT   IoctlType,
+    PVOID    lpvData,
+    ULONG    cbSize
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_OLDKD_READ_PHYSICAL_MEMORY)(
+    ULONGLONG        address,
+    PVOID            buffer,
+    ULONG            count,
+    PULONG           bytesread
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_OLDKD_WRITE_PHYSICAL_MEMORY)(
+    ULONGLONG        address,
+    PVOID            buffer,
+    ULONG            length,
+    PULONG           byteswritten
+    );
+
+
+typedef struct _EXTSTACKTRACE {
+    ULONG       FramePointer;
+    ULONG       ProgramCounter;
+    ULONG       ReturnAddress;
+    ULONG       Args[4];
+} EXTSTACKTRACE, *PEXTSTACKTRACE;
+
+typedef struct _EXTSTACKTRACE32 {
+    ULONG       FramePointer;
+    ULONG       ProgramCounter;
+    ULONG       ReturnAddress;
+    ULONG       Args[4];
+} EXTSTACKTRACE32, *PEXTSTACKTRACE32;
+
+typedef struct _EXTSTACKTRACE64 {
+    ULONG64     FramePointer;
+    ULONG64     ProgramCounter;
+    ULONG64     ReturnAddress;
+    ULONG64     Args[4];
+} EXTSTACKTRACE64, *PEXTSTACKTRACE64;
+
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_STACKTRACE_ROUTINE)(
+    ULONG             FramePointer,
+    ULONG             StackPointer,
+    ULONG             ProgramCounter,
+    PEXTSTACKTRACE    StackFrames,
+    ULONG             Frames
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_STACKTRACE_ROUTINE32)(
+    ULONG             FramePointer,
+    ULONG             StackPointer,
+    ULONG             ProgramCounter,
+    PEXTSTACKTRACE32  StackFrames,
+    ULONG             Frames
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_STACKTRACE_ROUTINE64)(
+    ULONG64           FramePointer,
+    ULONG64           StackPointer,
+    ULONG64           ProgramCounter,
+    PEXTSTACKTRACE64  StackFrames,
+    ULONG             Frames
+    );
+
+typedef struct _WINDBG_EXTENSION_APIS {
+    ULONG                                  nSize;
+    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
+    PWINDBG_GET_EXPRESSION                 lpGetExpressionRoutine;
+    PWINDBG_GET_SYMBOL                     lpGetSymbolRoutine;
+    PWINDBG_DISASM                         lpDisasmRoutine;
+    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
+    PWINDBG_READ_PROCESS_MEMORY_ROUTINE    lpReadProcessMemoryRoutine;
+    PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE   lpWriteProcessMemoryRoutine;
+    PWINDBG_GET_THREAD_CONTEXT_ROUTINE     lpGetThreadContextRoutine;
+    PWINDBG_SET_THREAD_CONTEXT_ROUTINE     lpSetThreadContextRoutine;
+    PWINDBG_IOCTL_ROUTINE                  lpIoctlRoutine;
+    PWINDBG_STACKTRACE_ROUTINE             lpStackTraceRoutine;
+} WINDBG_EXTENSION_APIS, *PWINDBG_EXTENSION_APIS;
+
+typedef struct _WINDBG_EXTENSION_APIS32 {
+    ULONG                                  nSize;
+    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
+    PWINDBG_GET_EXPRESSION32               lpGetExpressionRoutine;
+    PWINDBG_GET_SYMBOL32                   lpGetSymbolRoutine;
+    PWINDBG_DISASM32                       lpDisasmRoutine;
+    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
+    PWINDBG_READ_PROCESS_MEMORY_ROUTINE32  lpReadProcessMemoryRoutine;
+    PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE32 lpWriteProcessMemoryRoutine;
+    PWINDBG_GET_THREAD_CONTEXT_ROUTINE     lpGetThreadContextRoutine;
+    PWINDBG_SET_THREAD_CONTEXT_ROUTINE     lpSetThreadContextRoutine;
+    PWINDBG_IOCTL_ROUTINE                  lpIoctlRoutine;
+    PWINDBG_STACKTRACE_ROUTINE32           lpStackTraceRoutine;
+} WINDBG_EXTENSION_APIS32, *PWINDBG_EXTENSION_APIS32;
+
+typedef struct _WINDBG_EXTENSION_APIS64 {
+    ULONG                                  nSize;
+    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
+    PWINDBG_GET_EXPRESSION64               lpGetExpressionRoutine;
+    PWINDBG_GET_SYMBOL64                   lpGetSymbolRoutine;
+    PWINDBG_DISASM64                       lpDisasmRoutine;
+    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
+    PWINDBG_READ_PROCESS_MEMORY_ROUTINE64  lpReadProcessMemoryRoutine;
+    PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE64 lpWriteProcessMemoryRoutine;
+    PWINDBG_GET_THREAD_CONTEXT_ROUTINE     lpGetThreadContextRoutine;
+    PWINDBG_SET_THREAD_CONTEXT_ROUTINE     lpSetThreadContextRoutine;
+    PWINDBG_IOCTL_ROUTINE                  lpIoctlRoutine;
+    PWINDBG_STACKTRACE_ROUTINE64           lpStackTraceRoutine;
+} WINDBG_EXTENSION_APIS64, *PWINDBG_EXTENSION_APIS64;
+
+
+typedef struct _WINDBG_OLD_EXTENSION_APIS {
+    ULONG                                  nSize;
+    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
+    PWINDBG_GET_EXPRESSION                 lpGetExpressionRoutine;
+    PWINDBG_GET_SYMBOL                     lpGetSymbolRoutine;
+    PWINDBG_DISASM                         lpDisasmRoutine;
+    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
+} WINDBG_OLD_EXTENSION_APIS, *PWINDBG_OLD_EXTENSION_APIS;
+
+typedef struct _WINDBG_OLDKD_EXTENSION_APIS {
+    ULONG                                  nSize;
+    PWINDBG_OUTPUT_ROUTINE                 lpOutputRoutine;
+    PWINDBG_GET_EXPRESSION32               lpGetExpressionRoutine;
+    PWINDBG_GET_SYMBOL32                   lpGetSymbolRoutine;
+    PWINDBG_DISASM32                       lpDisasmRoutine;
+    PWINDBG_CHECK_CONTROL_C                lpCheckControlCRoutine;
+    PWINDBG_READ_PROCESS_MEMORY_ROUTINE32  lpReadVirtualMemRoutine;
+    PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE32 lpWriteVirtualMemRoutine;
+    PWINDBG_OLDKD_READ_PHYSICAL_MEMORY     lpReadPhysicalMemRoutine;
+    PWINDBG_OLDKD_WRITE_PHYSICAL_MEMORY    lpWritePhysicalMemRoutine;
+} WINDBG_OLDKD_EXTENSION_APIS, *PWINDBG_OLDKD_EXTENSION_APIS;
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_OLD_EXTENSION_ROUTINE)(
+    ULONG                   dwCurrentPc,
+    PWINDBG_EXTENSION_APIS  lpExtensionApis,
+    PCSTR                   lpArgumentString
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_EXTENSION_ROUTINE)(
+    HANDLE                  hCurrentProcess,
+    HANDLE                  hCurrentThread,
+    ULONG                   dwCurrentPc,
+    ULONG                   dwProcessor,
+    PCSTR                   lpArgumentString
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_EXTENSION_ROUTINE32)(
+    HANDLE                  hCurrentProcess,
+    HANDLE                  hCurrentThread,
+    ULONG                   dwCurrentPc,
+    ULONG                   dwProcessor,
+    PCSTR                   lpArgumentString
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_EXTENSION_ROUTINE64)(
+    HANDLE                  hCurrentProcess,
+    HANDLE                  hCurrentThread,
+    ULONG64                 dwCurrentPc,
+    ULONG                   dwProcessor,
+    PCSTR                   lpArgumentString
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_OLDKD_EXTENSION_ROUTINE)(
+    ULONG                        dwCurrentPc,
+    PWINDBG_OLDKD_EXTENSION_APIS lpExtensionApis,
+    PCSTR                        lpArgumentString
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_EXTENSION_DLL_INIT)(
+    PWINDBG_EXTENSION_APIS lpExtensionApis,
+    USHORT                 MajorVersion,
+    USHORT                 MinorVersion
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_EXTENSION_DLL_INIT32)(
+    PWINDBG_EXTENSION_APIS32 lpExtensionApis,
+    USHORT                   MajorVersion,
+    USHORT                   MinorVersion
+    );
+
+typedef
+VOID
+(WDBGAPI*PWINDBG_EXTENSION_DLL_INIT64)(
+    PWINDBG_EXTENSION_APIS64 lpExtensionApis,
+    USHORT                   MajorVersion,
+    USHORT                   MinorVersion
+    );
+
+typedef
+ULONG
+(WDBGAPI*PWINDBG_CHECK_VERSION)(
+    VOID
+    );
+
+#define EXT_API_VERSION_NUMBER   5
+#define EXT_API_VERSION_NUMBER32 5
+#define EXT_API_VERSION_NUMBER64 6
+
+typedef struct EXT_API_VERSION {
+    USHORT  MajorVersion;
+    USHORT  MinorVersion;
+    USHORT  Revision;
+    USHORT  Reserved;
+} EXT_API_VERSION, *LPEXT_API_VERSION;
+
+typedef
+LPEXT_API_VERSION
+(WDBGAPI*PWINDBG_EXTENSION_API_VERSION)(
+    VOID
+    );
+
+#define IG_KD_CONTEXT                  1
+#define IG_READ_CONTROL_SPACE          2
+#define IG_WRITE_CONTROL_SPACE         3
+#define IG_READ_IO_SPACE               4
+#define IG_WRITE_IO_SPACE              5
+#define IG_READ_PHYSICAL               6
+#define IG_WRITE_PHYSICAL              7
+#define IG_READ_IO_SPACE_EX            8
+#define IG_WRITE_IO_SPACE_EX           9
+#define IG_KSTACK_HELP                10   // obsolete
+#define IG_SET_THREAD                 11
+#define IG_READ_MSR                   12
+#define IG_WRITE_MSR                  13
+#define IG_GET_DEBUGGER_DATA          14
+#define IG_GET_KERNEL_VERSION         15
+#define IG_RELOAD_SYMBOLS             16
+#define IG_GET_SET_SYMPATH            17
+#define IG_GET_EXCEPTION_RECORD       18
+#define IG_IS_PTR64                   19
+#define IG_GET_BUS_DATA               20
+#define IG_SET_BUS_DATA               21
+#define IG_DUMP_SYMBOL_INFO           22
+#define IG_LOWMEM_CHECK               23
+#define IG_SEARCH_MEMORY              24
+#define IG_GET_CURRENT_THREAD         25
+#define IG_GET_CURRENT_PROCESS        26
+#define IG_GET_TYPE_SIZE              27
+#define IG_GET_CURRENT_PROCESS_HANDLE 28
+#define IG_GET_INPUT_LINE             29
+#define IG_GET_EXPRESSION_EX          30
+#define IG_TRANSLATE_VIRTUAL_TO_PHYSICAL 31
+#define IG_GET_CACHE_SIZE             32
+#define IG_READ_PHYSICAL_WITH_FLAGS   33
+#define IG_WRITE_PHYSICAL_WITH_FLAGS  34
+#define IG_POINTER_SEARCH_PHYSICAL    35
+#define IG_OBSOLETE_PLACEHOLDER_36    36
+#define IG_GET_THREAD_OS_INFO         37
+#define IG_GET_CLR_DATA_INTERFACE     38
+#define IG_MATCH_PATTERN_A            39
+#define IG_FIND_FILE                  40
+#define IG_TYPED_DATA_OBSOLETE        41
+#define IG_QUERY_TARGET_INTERFACE     42
+#define IG_TYPED_DATA                 43
+#define IG_DISASSEMBLE_BUFFER         44
+#define IG_GET_ANY_MODULE_IN_RANGE    45
+#define IG_VIRTUAL_TO_PHYSICAL        46
+#define IG_PHYSICAL_TO_VIRTUAL        47
+#define IG_GET_CONTEXT_EX             48
+
+#define IG_GET_TEB_ADDRESS           128
+#define IG_GET_PEB_ADDRESS           129
+
+typedef struct _PROCESSORINFO {
+    USHORT      Processor;                // current processor
+    USHORT      NumberProcessors;         // total number of processors
+} PROCESSORINFO, *PPROCESSORINFO;
+
+typedef struct _READCONTROLSPACE {
+    USHORT      Processor;
+    ULONG       Address;
+    ULONG       BufLen;
+    UCHAR       Buf[1];
+} READCONTROLSPACE, *PREADCONTROLSPACE;
+
+typedef struct _READCONTROLSPACE32 {
+    USHORT      Processor;
+    ULONG       Address;
+    ULONG       BufLen;
+    UCHAR       Buf[1];
+} READCONTROLSPACE32, *PREADCONTROLSPACE32;
+
+typedef struct _READCONTROLSPACE64 {
+    USHORT      Processor;
+    ULONG64     Address;
+    ULONG       BufLen;
+    UCHAR       Buf[1];
+} READCONTROLSPACE64, *PREADCONTROLSPACE64;
+
+typedef struct _IOSPACE {
+    ULONG       Address;
+    ULONG       Length;                   // 1, 2, or 4 bytes
+    ULONG       Data;
+} IOSPACE, *PIOSPACE;
+
+typedef struct _IOSPACE32 {
+    ULONG       Address;
+    ULONG       Length;                   // 1, 2, or 4 bytes
+    ULONG       Data;
+} IOSPACE32, *PIOSPACE32;
+
+typedef struct _IOSPACE64 {
+    ULONG64     Address;
+    ULONG       Length;                   // 1, 2, or 4 bytes
+    ULONG       Data;
+} IOSPACE64, *PIOSPACE64;
+
+typedef struct _IOSPACE_EX {
+    ULONG       Address;
+    ULONG       Length;                   // 1, 2, or 4 bytes
+    ULONG       Data;
+    ULONG       InterfaceType;
+    ULONG       BusNumber;
+    ULONG       AddressSpace;
+} IOSPACE_EX, *PIOSPACE_EX;
+
+typedef struct _IOSPACE_EX32 {
+    ULONG       Address;
+    ULONG       Length;                   // 1, 2, or 4 bytes
+    ULONG       Data;
+    ULONG       InterfaceType;
+    ULONG       BusNumber;
+    ULONG       AddressSpace;
+} IOSPACE_EX32, *PIOSPACE_EX32;
+
+typedef struct _IOSPACE_EX64 {
+    ULONG64     Address;
+    ULONG       Length;                   // 1, 2, or 4 bytes
+    ULONG       Data;
+    ULONG       InterfaceType;
+    ULONG       BusNumber;
+    ULONG       AddressSpace;
+} IOSPACE_EX64, *PIOSPACE_EX64;
+
+typedef struct _GETSETBUSDATA {
+    ULONG       BusDataType;
+    ULONG       BusNumber;
+    ULONG       SlotNumber;
+    PVOID       Buffer;
+    ULONG       Offset;
+    ULONG       Length;
+} BUSDATA, *PBUSDATA;
+
+typedef struct _SEARCHMEMORY {
+    ULONG64 SearchAddress;
+    ULONG64 SearchLength;
+    ULONG64 FoundAddress;
+    ULONG   PatternLength;
+    PVOID   Pattern;
+} SEARCHMEMORY, *PSEARCHMEMORY;
+
+typedef struct _PHYSICAL {
+    ULONGLONG              Address;
+    ULONG                  BufLen;
+    UCHAR                  Buf[1];
+} PHYSICAL, *PPHYSICAL;
+
+#define PHYS_FLAG_DEFAULT        0
+#define PHYS_FLAG_CACHED         1
+#define PHYS_FLAG_UNCACHED       2
+#define PHYS_FLAG_WRITE_COMBINED 3
+
+typedef struct _PHYSICAL_WITH_FLAGS {
+    ULONGLONG              Address;
+    ULONG                  BufLen;
+    ULONG                  Flags;
+    UCHAR                  Buf[1];
+} PHYSICAL_WITH_FLAGS, *PPHYSICAL_WITH_FLAGS;
+
+typedef struct _READ_WRITE_MSR {
+    ULONG       Msr;
+    LONGLONG    Value;
+} READ_WRITE_MSR, *PREAD_WRITE_MSR;
+
+typedef struct _GET_SET_SYMPATH {
+    PCSTR       Args;       // args to !reload command
+    PSTR        Result;     // returns new path
+    int         Length;     // Length of result buffer
+} GET_SET_SYMPATH, *PGET_SET_SYMPATH;
+
+typedef struct _GET_TEB_ADDRESS {
+    ULONGLONG   Address;
+} GET_TEB_ADDRESS, *PGET_TEB_ADDRESS;
+
+typedef struct _GET_PEB_ADDRESS {
+    ULONG64     CurrentThread;
+    ULONGLONG   Address;
+} GET_PEB_ADDRESS, *PGET_PEB_ADDRESS;
+
+typedef struct _GET_CURRENT_THREAD_ADDRESS {
+    ULONG       Processor;
+    ULONG64     Address;
+} GET_CURRENT_THREAD_ADDRESS, *PGET_CURRENT_THREAD_ADDRESS;
+
+typedef struct _GET_CURRENT_PROCESS_ADDRESS {
+    ULONG       Processor;
+    ULONG64     CurrentThread;
+    ULONG64     Address;
+} GET_CURRENT_PROCESS_ADDRESS, *PGET_CURRENT_PROCESS_ADDRESS;
+
+typedef struct _GET_INPUT_LINE {
+    PCSTR       Prompt;
+    PSTR        Buffer;
+    ULONG       BufferSize;
+    ULONG       InputSize;
+} GET_INPUT_LINE, *PGET_INPUT_LINE;
+
+typedef struct _GET_EXPRESSION_EX {
+    PCSTR       Expression;
+    PCSTR       Remainder;
+    ULONG64     Value;
+} GET_EXPRESSION_EX, *PGET_EXPRESSION_EX;
+
+typedef struct _TRANSLATE_VIRTUAL_TO_PHYSICAL {
+    ULONG64     Virtual;
+    ULONG64     Physical;
+} TRANSLATE_VIRTUAL_TO_PHYSICAL, *PTRANSLATE_VIRTUAL_TO_PHYSICAL;
+
+typedef struct _VIRTUAL_TO_PHYSICAL {
+    ULONG       Status;
+    ULONG       Size;
+    ULONG64     PdeAddress;
+    ULONG64     Virtual;
+    ULONG64     Physical;
+} VIRTUAL_TO_PHYSICAL, *PVIRTUAL_TO_PHYSICAL;
+
+typedef struct _PHYSICAL_TO_VIRTUAL {
+    ULONG       Status;
+    ULONG       Size;
+    ULONG64     PdeAddress;
+} PHYSICAL_TO_VIRTUAL, *PPHYSICAL_TO_VIRTUAL;
+
+typedef struct _GET_CONTEXT_EX {
+    ULONG       Status;
+    ULONG       ContextSize;
+    PVOID       pContext;
+} GET_CONTEXT_EX, *PGET_CONTEXT_EX;
+
+#define PTR_SEARCH_PHYS_ALL_HITS         0x00000001
+#define PTR_SEARCH_PHYS_PTE              0x00000002
+#define PTR_SEARCH_PHYS_RANGE_CHECK_ONLY 0x00000004
+
+#define PTR_SEARCH_PHYS_SIZE_SHIFT 3
+#define PTR_SEARCH_PHYS_SIZE_MASK  (0xf << PTR_SEARCH_PHYS_SIZE_SHIFT)
+
+#define PTR_SEARCH_NO_SYMBOL_CHECK  0x80000000
+
+typedef struct _POINTER_SEARCH_PHYSICAL {
+    IN ULONG64 Offset;
+    IN ULONG64 Length;
+    IN ULONG64 PointerMin;
+    IN ULONG64 PointerMax;
+    IN ULONG Flags;
+    OUT PULONG64 MatchOffsets;
+    IN ULONG MatchOffsetsSize;
+    OUT ULONG MatchOffsetsCount;
+} POINTER_SEARCH_PHYSICAL, *PPOINTER_SEARCH_PHYSICAL;
+
+typedef struct _WDBGEXTS_THREAD_OS_INFO {
+    // System thread ID input.
+    ULONG ThreadId;
+
+    //
+    // Output information.
+    //
+
+    // Exit status is STILL_ACTIVE by default.
+    ULONG ExitStatus;
+    // Priority class is zero if not known.
+    ULONG PriorityClass;
+    // Priority defaults to normal.
+    ULONG Priority;
+    // Times can be zero if not known.
+    ULONG64 CreateTime;
+    ULONG64 ExitTime;
+    ULONG64 KernelTime;
+    ULONG64 UserTime;
+    // Start offset is zero if not known.
+    ULONG64 StartOffset;
+    // Affinity is zero if not known.
+    ULONG64 Affinity;
+} WDBGEXTS_THREAD_OS_INFO, *PWDBGEXTS_THREAD_OS_INFO;
+
+typedef struct _WDBGEXTS_CLR_DATA_INTERFACE {
+    // Interface requested.
+    const IID* Iid;
+    // Interface pointer return.
+    PVOID Iface;
+} WDBGEXTS_CLR_DATA_INTERFACE, *PWDBGEXTS_CLR_DATA_INTERFACE;
+
+typedef struct _EXT_MATCH_PATTERN_A {
+    IN PCSTR Str;
+    IN PCSTR Pattern;
+    IN ULONG CaseSensitive;
+} EXT_MATCH_PATTERN_A, *PEXT_MATCH_PATTERN_A;
+
+#define EXT_FIND_FILE_ALLOW_GIVEN_PATH 0x00000001
+
+typedef struct _EXT_FIND_FILE {
+    IN PCWSTR FileName;
+    IN ULONG64 IndexedSize;
+    IN ULONG ImageTimeDateStamp;
+    // Pass zero to ignore.
+    IN ULONG ImageCheckSum;
+    IN OPTIONAL PVOID ExtraInfo;
+    IN ULONG ExtraInfoSize;
+    IN ULONG Flags;
+    // Free with UnmapViewOfFile.
+    OUT PVOID FileMapping;
+    OUT ULONG64 FileMappingSize;
+    // Free with CloseHandle.
+    OUT HANDLE FileHandle;
+    // Must be at least MAX_PATH characters if set.
+    OUT OPTIONAL PWSTR FoundFileName;
+    OUT ULONG FoundFileNameChars;
+} EXT_FIND_FILE, *PEXT_FIND_FILE;
+
+#define DEBUG_TYPED_DATA_IS_IN_MEMORY            0x00000001
+#define DEBUG_TYPED_DATA_PHYSICAL_DEFAULT        0x00000002
+#define DEBUG_TYPED_DATA_PHYSICAL_CACHED         0x00000004
+#define DEBUG_TYPED_DATA_PHYSICAL_UNCACHED       0x00000006
+#define DEBUG_TYPED_DATA_PHYSICAL_WRITE_COMBINED 0x00000008
+
+// Mask for all physical flags.
+#define DEBUG_TYPED_DATA_PHYSICAL_MEMORY 0x0000000e
+
+typedef struct _DEBUG_TYPED_DATA
+{
+    ULONG64 ModBase;
+    ULONG64 Offset;
+    ULONG64 EngineHandle;
+    ULONG64 Data;
+    ULONG Size;
+    ULONG Flags;
+    ULONG TypeId;
+    ULONG BaseTypeId;
+    ULONG Tag;
+    ULONG Register;
+    ULONG64 Internal[9];
+} DEBUG_TYPED_DATA, *PDEBUG_TYPED_DATA;
+
+typedef enum _EXT_TDOP {
+    EXT_TDOP_COPY,
+    EXT_TDOP_RELEASE,
+    EXT_TDOP_SET_FROM_EXPR,
+    EXT_TDOP_SET_FROM_U64_EXPR,
+    EXT_TDOP_GET_FIELD,
+    EXT_TDOP_EVALUATE,
+    EXT_TDOP_GET_TYPE_NAME,
+    EXT_TDOP_OUTPUT_TYPE_NAME,
+    EXT_TDOP_OUTPUT_SIMPLE_VALUE,
+    EXT_TDOP_OUTPUT_FULL_VALUE,
+    EXT_TDOP_HAS_FIELD,
+    EXT_TDOP_GET_FIELD_OFFSET,
+    EXT_TDOP_GET_ARRAY_ELEMENT,
+    EXT_TDOP_GET_DEREFERENCE,
+    EXT_TDOP_GET_TYPE_SIZE,
+    EXT_TDOP_OUTPUT_TYPE_DEFINITION,
+    EXT_TDOP_GET_POINTER_TO,
+    EXT_TDOP_SET_FROM_TYPE_ID_AND_U64,
+    EXT_TDOP_SET_PTR_FROM_TYPE_ID_AND_U64,
+
+    EXT_TDOP_COUNT
+} EXT_TDOP;
+
+// EXT_TDF physical flags must match DEBUG_TYPED.
+#define EXT_TDF_PHYSICAL_DEFAULT        0x00000002
+#define EXT_TDF_PHYSICAL_CACHED         0x00000004
+#define EXT_TDF_PHYSICAL_UNCACHED       0x00000006
+#define EXT_TDF_PHYSICAL_WRITE_COMBINED 0x00000008
+#define EXT_TDF_PHYSICAL_MEMORY         0x0000000e
+
+// NOTE: Every DEBUG_TYPED_DATA should be released
+// via EXT_TDOP_RELEASE when it is no longer needed.
+typedef struct _EXT_TYPED_DATA {
+    IN EXT_TDOP Operation;
+    IN ULONG Flags;
+    IN DEBUG_TYPED_DATA InData;
+    OUT DEBUG_TYPED_DATA OutData;
+    IN ULONG InStrIndex;
+    IN ULONG In32;
+    OUT ULONG Out32;
+    IN ULONG64 In64;
+    OUT ULONG64 Out64;
+    OUT ULONG StrBufferIndex;
+    IN ULONG StrBufferChars;
+    OUT ULONG StrCharsNeeded;
+    IN OUT ULONG DataBufferIndex;
+    IN ULONG DataBufferBytes;
+    OUT ULONG DataBytesNeeded;
+    OUT HRESULT Status;
+    // Must be zeroed.
+    ULONG64 Reserved[8];
+} EXT_TYPED_DATA, *PEXT_TYPED_DATA;
+
+typedef struct _WDBGEXTS_QUERY_INTERFACE {
+    // Interface requested.
+    const IID* Iid;
+    // Interface pointer return.
+    PVOID Iface;
+} WDBGEXTS_QUERY_INTERFACE, *PWDBGEXTS_QUERY_INTERFACE;
+
+#define WDBGEXTS_ADDRESS_DEFAULT   0x00000000
+#define WDBGEXTS_ADDRESS_SEG16     0x00000001
+#define WDBGEXTS_ADDRESS_SEG32     0x00000002
+#define WDBGEXTS_ADDRESS_RESERVED0 0x80000000
+
+typedef struct _WDBGEXTS_DISASSEMBLE_BUFFER {
+    IN ULONG64 InOffset;
+    OUT ULONG64 OutOffset;
+    // AddrFlags are from above.
+    IN ULONG AddrFlags;
+    // FormatFlags are from dbgeng's DEBUG_DISASM_*.
+    IN ULONG FormatFlags;
+    IN ULONG DataBufferBytes;
+    IN ULONG DisasmBufferChars;
+    IN OPTIONAL PVOID DataBuffer;
+    OUT PWSTR DisasmBuffer;
+    IN ULONG64 Reserved0[3];
+} WDBGEXTS_DISASSEMBLE_BUFFER, *PWDBGEXTS_DISASSEMBLE_BUFFER;
+
+typedef struct _WDBGEXTS_MODULE_IN_RANGE {
+    IN ULONG64 Start;
+    // Inclusive ending offset.
+    IN ULONG64 End;
+    OUT ULONG64 FoundModBase;
+    OUT ULONG FoundModSize;
+} WDBGEXTS_MODULE_IN_RANGE, *PWDBGEXTS_MODULE_IN_RANGE;
+
+//
+// If DBGKD_VERS_FLAG_DATA is set in Flags, info should be retrieved from
+// the KDDEBUGGER_DATA block rather than from the DBGKD_GET_VERSION
+// packet.  The data will remain in the version packet for a while to
+// reduce compatibility problems.
+//
+
+#define DBGKD_VERS_FLAG_MP          0x0001   // kernel is MP built
+#define DBGKD_VERS_FLAG_DATA        0x0002   // DebuggerDataList is valid
+#define DBGKD_VERS_FLAG_PTR64       0x0004   // native pointers are 64 bits
+#define DBGKD_VERS_FLAG_NOMM        0x0008   // No MM - don't decode PTEs
+#define DBGKD_VERS_FLAG_HSS         0x0010   // hardware stepping support
+#define DBGKD_VERS_FLAG_PARTITIONS  0x0020   // multiple OS partitions exist
+#define DBGKD_VERS_FLAG_HAL_IN_NTOS 0x0040   // HAL is linked into NTOS kernel
+
+#define KDBG_TAG    'GBDK'
+
+//
+// KD version MajorVersion high-byte identifiers.
+//
+
+typedef enum _DBGKD_MAJOR_TYPES
+{
+    DBGKD_MAJOR_NT,
+    DBGKD_MAJOR_XBOX,
+    DBGKD_MAJOR_BIG,
+    DBGKD_MAJOR_EXDI,
+    DBGKD_MAJOR_NTBD,
+    DBGKD_MAJOR_EFI,
+    DBGKD_MAJOR_TNT,
+    DBGKD_MAJOR_SINGULARITY,
+    DBGKD_MAJOR_HYPERVISOR,
+    DBGKD_MAJOR_MIDORI,
+    DBGKD_MAJOR_CE,
+    DBGKD_MAJOR_COUNT
+} DBGKD_MAJOR_TYPES;
+
+#define DBGKD_MAJOR_TYPE(MajorVersion) \
+    ((DBGKD_MAJOR_TYPES)((MajorVersion) >> 8))
+
+
+// **********************************************************************
+// DO NOT CHANGE THESE 32 BIT STRUCTURES!
+// ONLY MAKE CHAGES TO THE 64 BIT VERSION BELOW!!
+// **********************************************************************
+
+//
+// The following structure has changed in more than pointer size.
+//
+// This is the version packet for pre-NT5 Beta 2 systems.
+// For now, it is also still used on x86
+//
+typedef struct _DBGKD_GET_VERSION32 {
+    USHORT  MajorVersion;
+    USHORT  MinorVersion;
+    USHORT  ProtocolVersion;
+    USHORT  Flags;
+    ULONG   KernBase;
+    ULONG   PsLoadedModuleList;
+
+    USHORT  MachineType;
+
+    //
+    // help for walking stacks with user callbacks:
+    //
+
+    //
+    // The address of the thread structure is provided in the
+    // WAIT_STATE_CHANGE packet.  This is the offset from the base of
+    // the thread structure to the pointer to the kernel stack frame
+    // for the currently active usermode callback.
+    //
+
+    USHORT  ThCallbackStack;            // offset in thread data
+
+    //
+    // these values are offsets into that frame:
+    //
+
+    USHORT  NextCallback;               // saved pointer to next callback frame
+    USHORT  FramePointer;               // saved frame pointer
+
+    //
+    // Address of the kernel callout routine.
+    //
+
+    ULONG   KiCallUserMode;             // kernel routine
+
+    //
+    // Address of the usermode entry point for callbacks.
+    //
+
+    ULONG   KeUserCallbackDispatcher;   // address in ntdll
+
+    //
+    // DbgBreakPointWithStatus is a function which takes a ULONG argument
+    // and hits a breakpoint.  This field contains the address of the
+    // breakpoint instruction.  When the debugger sees a breakpoint
+    // at this address, it may retrieve the argument from the first
+    // argument register, or on x86 the eax register.
+    //
+
+    ULONG   BreakpointWithStatus;       // address of breakpoint
+
+    //
+    // Components may register a debug data block for use by
+    // debugger extensions.  This is the address of the list head.
+    //
+
+    ULONG   DebuggerDataList;
+
+} DBGKD_GET_VERSION32, *PDBGKD_GET_VERSION32;
+
+
+//
+// This is the debugger data packet for pre NT5 Beta 2 systems.
+// For now, it is still used on x86
+//
+
+typedef struct _DBGKD_DEBUG_DATA_HEADER32 {
+
+    LIST_ENTRY32 List;
+    ULONG           OwnerTag;
+    ULONG           Size;
+
+} DBGKD_DEBUG_DATA_HEADER32, *PDBGKD_DEBUG_DATA_HEADER32;
+
+typedef struct _KDDEBUGGER_DATA32 {
+
+    DBGKD_DEBUG_DATA_HEADER32 Header;
+    ULONG   KernBase;
+    ULONG   BreakpointWithStatus;       // address of breakpoint
+    ULONG   SavedContext;
+    USHORT  ThCallbackStack;            // offset in thread data
+    USHORT  NextCallback;               // saved pointer to next callback frame
+    USHORT  FramePointer;               // saved frame pointer
+    USHORT  PaeEnabled:1;
+    ULONG   KiCallUserMode;             // kernel routine
+    ULONG   KeUserCallbackDispatcher;   // address in ntdll
+
+    ULONG   PsLoadedModuleList;
+    ULONG   PsActiveProcessHead;
+    ULONG   PspCidTable;
+
+    ULONG   ExpSystemResourcesList;
+    ULONG   ExpPagedPoolDescriptor;
+    ULONG   ExpNumberOfPagedPools;
+
+    ULONG   KeTimeIncrement;
+    ULONG   KeBugCheckCallbackListHead;
+    ULONG   KiBugcheckData;
+
+    ULONG   IopErrorLogListHead;
+
+    ULONG   ObpRootDirectoryObject;
+    ULONG   ObpTypeObjectType;
+
+    ULONG   MmSystemCacheStart;
+    ULONG   MmSystemCacheEnd;
+    ULONG   MmSystemCacheWs;
+
+    ULONG   MmPfnDatabase;
+    ULONG   MmSystemPtesStart;
+    ULONG   MmSystemPtesEnd;
+    ULONG   MmSubsectionBase;
+    ULONG   MmNumberOfPagingFiles;
+
+    ULONG   MmLowestPhysicalPage;
+    ULONG   MmHighestPhysicalPage;
+    ULONG   MmNumberOfPhysicalPages;
+
+    ULONG   MmMaximumNonPagedPoolInBytes;
+    ULONG   MmNonPagedSystemStart;
+    ULONG   MmNonPagedPoolStart;
+    ULONG   MmNonPagedPoolEnd;
+
+    ULONG   MmPagedPoolStart;
+    ULONG   MmPagedPoolEnd;
+    ULONG   MmPagedPoolInformation;
+    ULONG   MmPageSize;
+
+    ULONG   MmSizeOfPagedPoolInBytes;
+
+    ULONG   MmTotalCommitLimit;
+    ULONG   MmTotalCommittedPages;
+    ULONG   MmSharedCommit;
+    ULONG   MmDriverCommit;
+    ULONG   MmProcessCommit;
+    ULONG   MmPagedPoolCommit;
+    ULONG   MmExtendedCommit;
+
+    ULONG   MmZeroedPageListHead;
+    ULONG   MmFreePageListHead;
+    ULONG   MmStandbyPageListHead;
+    ULONG   MmModifiedPageListHead;
+    ULONG   MmModifiedNoWritePageListHead;
+    ULONG   MmAvailablePages;
+    ULONG   MmResidentAvailablePages;
+
+    ULONG   PoolTrackTable;
+    ULONG   NonPagedPoolDescriptor;
+
+    ULONG   MmHighestUserAddress;
+    ULONG   MmSystemRangeStart;
+    ULONG   MmUserProbeAddress;
+
+    ULONG   KdPrintCircularBuffer;
+    ULONG   KdPrintCircularBufferEnd;
+    ULONG   KdPrintWritePointer;
+    ULONG   KdPrintRolloverCount;
+
+    ULONG   MmLoadedUserImageList;
+
+} KDDEBUGGER_DATA32, *PKDDEBUGGER_DATA32;
+
+// **********************************************************************
+//
+// DO NOT CHANGE KDDEBUGGER_DATA32!!
+// ONLY MAKE CHANGES TO KDDEBUGGER_DATA64!!!
+//
+// **********************************************************************
+
+
+enum
+{
+    DBGKD_SIMULATION_NONE,
+    DBGKD_SIMULATION_EXDI
+};
+
+#define KD_SECONDARY_VERSION_DEFAULT 0
+
+#define KD_SECONDARY_VERSION_AMD64_OBSOLETE_CONTEXT_1 0
+#define KD_SECONDARY_VERSION_AMD64_OBSOLETE_CONTEXT_2 1
+#define KD_SECONDARY_VERSION_AMD64_CONTEXT            2
+
+#ifdef _AMD64_
+#define CURRENT_KD_SECONDARY_VERSION \
+    KD_SECONDARY_VERSION_AMD64_CONTEXT
+#else
+#define CURRENT_KD_SECONDARY_VERSION KD_SECONDARY_VERSION_DEFAULT
+#endif
+
+typedef struct _DBGKD_GET_VERSION64 {
+    USHORT  MajorVersion;
+    USHORT  MinorVersion;
+    UCHAR   ProtocolVersion;
+    UCHAR   KdSecondaryVersion; // Cannot be 'A' for compat with dump header
+    USHORT  Flags;
+    USHORT  MachineType;
+
+    //
+    // Protocol command support descriptions.
+    // These allow the debugger to automatically
+    // adapt to different levels of command support
+    // in different kernels.
+    //
+
+    // One beyond highest packet type understood, zero based.
+    UCHAR   MaxPacketType;
+    // One beyond highest state change understood, zero based.
+    UCHAR   MaxStateChange;
+    // One beyond highest state manipulate message understood, zero based.
+    UCHAR   MaxManipulate;
+
+    // Kind of execution environment the kernel is running in,
+    // such as a real machine or a simulator.  Written back
+    // by the simulation if one exists.
+    UCHAR   Simulation;
+
+    USHORT  Unused[1];
+
+    ULONG64 KernBase;
+    ULONG64 PsLoadedModuleList;
+
+    //
+    // Components may register a debug data block for use by
+    // debugger extensions.  This is the address of the list head.
+    //
+    // There will always be an entry for the debugger.
+    //
+
+    ULONG64 DebuggerDataList;
+
+} DBGKD_GET_VERSION64, *PDBGKD_GET_VERSION64;
+
+
+//
+// This structure is used by the debugger for all targets
+// It is the same size as DBGKD_DATA_HEADER on all systems
+//
+typedef struct _DBGKD_DEBUG_DATA_HEADER64 {
+
+    //
+    // Link to other blocks
+    //
+
+    LIST_ENTRY64 List;
+
+    //
+    // This is a unique tag to identify the owner of the block.
+    // If your component only uses one pool tag, use it for this, too.
+    //
+
+    ULONG           OwnerTag;
+
+    //
+    // This must be initialized to the size of the data block,
+    // including this structure.
+    //
+
+    ULONG           Size;
+
+} DBGKD_DEBUG_DATA_HEADER64, *PDBGKD_DEBUG_DATA_HEADER64;
+
+
+//
+// This structure is the same size on all systems.  The only field
+// which must be translated by the debugger is Header.List.
+//
+
+//
+// DO NOT ADD OR REMOVE FIELDS FROM THE MIDDLE OF THIS STRUCTURE!!!
+//
+// If you remove a field, replace it with an "unused" placeholder.
+// Do not reuse fields until there has been enough time for old debuggers
+// and extensions to age out.
+//
+typedef struct _KDDEBUGGER_DATA64 {
+
+    DBGKD_DEBUG_DATA_HEADER64 Header;
+
+    //
+    // Base address of kernel image
+    //
+
+    ULONG64   KernBase;
+
+    //
+    // DbgBreakPointWithStatus is a function which takes an argument
+    // and hits a breakpoint.  This field contains the address of the
+    // breakpoint instruction.  When the debugger sees a breakpoint
+    // at this address, it may retrieve the argument from the first
+    // argument register, or on x86 the eax register.
+    //
+
+    ULONG64   BreakpointWithStatus;       // address of breakpoint
+
+    //
+    // Address of the saved context record during a bugcheck
+    //
+    // N.B. This is an automatic in KeBugcheckEx's frame, and
+    // is only valid after a bugcheck.
+    //
+
+    ULONG64   SavedContext;
+
+    //
+    // help for walking stacks with user callbacks:
+    //
+
+    //
+    // The address of the thread structure is provided in the
+    // WAIT_STATE_CHANGE packet.  This is the offset from the base of
+    // the thread structure to the pointer to the kernel stack frame
+    // for the currently active usermode callback.
+    //
+
+    USHORT  ThCallbackStack;            // offset in thread data
+
+    //
+    // these values are offsets into that frame:
+    //
+
+    USHORT  NextCallback;               // saved pointer to next callback frame
+    USHORT  FramePointer;               // saved frame pointer
+
+    //
+    // pad to a quad boundary
+    //
+    USHORT  PaeEnabled:1;
+
+    //
+    // Address of the kernel callout routine.
+    //
+
+    ULONG64   KiCallUserMode;             // kernel routine
+
+    //
+    // Address of the usermode entry point for callbacks.
+    //
+
+    ULONG64   KeUserCallbackDispatcher;   // address in ntdll
+
+
+    //
+    // Addresses of various kernel data structures and lists
+    // that are of interest to the kernel debugger.
+    //
+
+    ULONG64   PsLoadedModuleList;
+    ULONG64   PsActiveProcessHead;
+    ULONG64   PspCidTable;
+
+    ULONG64   ExpSystemResourcesList;
+    ULONG64   ExpPagedPoolDescriptor;
+    ULONG64   ExpNumberOfPagedPools;
+
+    ULONG64   KeTimeIncrement;
+    ULONG64   KeBugCheckCallbackListHead;
+    ULONG64   KiBugcheckData;
+
+    ULONG64   IopErrorLogListHead;
+
+    ULONG64   ObpRootDirectoryObject;
+    ULONG64   ObpTypeObjectType;
+
+    ULONG64   MmSystemCacheStart;
+    ULONG64   MmSystemCacheEnd;
+    ULONG64   MmSystemCacheWs;
+
+    ULONG64   MmPfnDatabase;
+    ULONG64   MmSystemPtesStart;
+    ULONG64   MmSystemPtesEnd;
+    ULONG64   MmSubsectionBase;
+    ULONG64   MmNumberOfPagingFiles;
+
+    ULONG64   MmLowestPhysicalPage;
+    ULONG64   MmHighestPhysicalPage;
+    ULONG64   MmNumberOfPhysicalPages;
+
+    ULONG64   MmMaximumNonPagedPoolInBytes;
+    ULONG64   MmNonPagedSystemStart;
+    ULONG64   MmNonPagedPoolStart;
+    ULONG64   MmNonPagedPoolEnd;
+
+    ULONG64   MmPagedPoolStart;
+    ULONG64   MmPagedPoolEnd;
+    ULONG64   MmPagedPoolInformation;
+    ULONG64   MmPageSize;
+
+    ULONG64   MmSizeOfPagedPoolInBytes;
+
+    ULONG64   MmTotalCommitLimit;
+    ULONG64   MmTotalCommittedPages;
+    ULONG64   MmSharedCommit;
+    ULONG64   MmDriverCommit;
+    ULONG64   MmProcessCommit;
+    ULONG64   MmPagedPoolCommit;
+    ULONG64   MmExtendedCommit;
+
+    ULONG64   MmZeroedPageListHead;
+    ULONG64   MmFreePageListHead;
+    ULONG64   MmStandbyPageListHead;
+    ULONG64   MmModifiedPageListHead;
+    ULONG64   MmModifiedNoWritePageListHead;
+    ULONG64   MmAvailablePages;
+    ULONG64   MmResidentAvailablePages;
+
+    ULONG64   PoolTrackTable;
+    ULONG64   NonPagedPoolDescriptor;
+
+    ULONG64   MmHighestUserAddress;
+    ULONG64   MmSystemRangeStart;
+    ULONG64   MmUserProbeAddress;
+
+    ULONG64   KdPrintCircularBuffer;
+    ULONG64   KdPrintCircularBufferEnd;
+    ULONG64   KdPrintWritePointer;
+    ULONG64   KdPrintRolloverCount;
+
+    ULONG64   MmLoadedUserImageList;
+
+    // NT 5.1 Addition
+
+    ULONG64   NtBuildLab;
+    ULONG64   KiNormalSystemCall;
+
+    // NT 5.0 hotfix addition
+
+    ULONG64   KiProcessorBlock;
+    ULONG64   MmUnloadedDrivers;
+    ULONG64   MmLastUnloadedDriver;
+    ULONG64   MmTriageActionTaken;
+    ULONG64   MmSpecialPoolTag;
+    ULONG64   KernelVerifier;
+    ULONG64   MmVerifierData;
+    ULONG64   MmAllocatedNonPagedPool;
+    ULONG64   MmPeakCommitment;
+    ULONG64   MmTotalCommitLimitMaximum;
+    ULONG64   CmNtCSDVersion;
+
+    // NT 5.1 Addition
+
+    ULONG64   MmPhysicalMemoryBlock;
+    ULONG64   MmSessionBase;
+    ULONG64   MmSessionSize;
+    ULONG64   MmSystemParentTablePage;
+
+    // Server 2003 addition
+
+    ULONG64   MmVirtualTranslationBase;
+
+    USHORT    OffsetKThreadNextProcessor;
+    USHORT    OffsetKThreadTeb;
+    USHORT    OffsetKThreadKernelStack;
+    USHORT    OffsetKThreadInitialStack;
+
+    USHORT    OffsetKThreadApcProcess;
+    USHORT    OffsetKThreadState;
+    USHORT    OffsetKThreadBStore;
+    USHORT    OffsetKThreadBStoreLimit;
+
+    USHORT    SizeEProcess;
+    USHORT    OffsetEprocessPeb;
+    USHORT    OffsetEprocessParentCID;
+    USHORT    OffsetEprocessDirectoryTableBase;
+
+    USHORT    SizePrcb;
+    USHORT    OffsetPrcbDpcRoutine;
+    USHORT    OffsetPrcbCurrentThread;
+    USHORT    OffsetPrcbMhz;
+
+    USHORT    OffsetPrcbCpuType;
+    USHORT    OffsetPrcbVendorString;
+    USHORT    OffsetPrcbProcStateContext;
+    USHORT    OffsetPrcbNumber;
+
+    USHORT    SizeEThread;
+
+    UCHAR     L1tfHighPhysicalBitIndex;  // Windows 10 19H1 Addition
+    UCHAR     L1tfSwizzleBitIndex;       // Windows 10 19H1 Addition
+
+    ULONG     Padding0;
+
+    ULONG64   KdPrintCircularBufferPtr;
+    ULONG64   KdPrintBufferSize;
+
+    ULONG64   KeLoaderBlock;
+
+    USHORT    SizePcr;
+    USHORT    OffsetPcrSelfPcr;
+    USHORT    OffsetPcrCurrentPrcb;
+    USHORT    OffsetPcrContainedPrcb;
+
+    USHORT    OffsetPcrInitialBStore;
+    USHORT    OffsetPcrBStoreLimit;
+    USHORT    OffsetPcrInitialStack;
+    USHORT    OffsetPcrStackLimit;
+
+    USHORT    OffsetPrcbPcrPage;
+    USHORT    OffsetPrcbProcStateSpecialReg;
+    USHORT    GdtR0Code;
+    USHORT    GdtR0Data;
+
+    USHORT    GdtR0Pcr;
+    USHORT    GdtR3Code;
+    USHORT    GdtR3Data;
+    USHORT    GdtR3Teb;
+
+    USHORT    GdtLdt;
+    USHORT    GdtTss;
+    USHORT    Gdt64R3CmCode;
+    USHORT    Gdt64R3CmTeb;
+
+    ULONG64   IopNumTriageDumpDataBlocks;
+    ULONG64   IopTriageDumpDataBlocks;
+
+    // Longhorn addition
+
+    ULONG64   VfCrashDataBlock;
+    ULONG64   MmBadPagesDetected;
+    ULONG64   MmZeroedPageSingleBitErrorsDetected;
+
+    // Windows 7 addition
+
+    ULONG64   EtwpDebuggerData;
+    USHORT    OffsetPrcbContext;
+
+    // Windows 8 addition
+
+    USHORT    OffsetPrcbMaxBreakpoints;
+    USHORT    OffsetPrcbMaxWatchpoints;
+
+    ULONG     OffsetKThreadStackLimit;
+    ULONG     OffsetKThreadStackBase;
+    ULONG     OffsetKThreadQueueListEntry;
+    ULONG     OffsetEThreadIrpList;
+
+    USHORT    OffsetPrcbIdleThread;
+    USHORT    OffsetPrcbNormalDpcState;
+    USHORT    OffsetPrcbDpcStack;
+    USHORT    OffsetPrcbIsrStack;
+
+    USHORT    SizeKDPC_STACK_FRAME;
+
+    // Windows 8.1 Addition
+
+    USHORT    OffsetKPriQueueThreadListHead;
+    USHORT    OffsetKThreadWaitReason;
+
+    // Windows 10 RS1 Addition
+
+    USHORT    Padding1;
+    ULONG64   PteBase;
+
+    // Windows 10 RS5 Addition
+
+    ULONG64   RetpolineStubFunctionTable;
+    ULONG     RetpolineStubFunctionTableSize;
+    ULONG     RetpolineStubOffset;
+    ULONG     RetpolineStubSize;
+
+} KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64;
+
+
+
+/************************************
+
+   Type Dump Ioctl
+
+*************************************/
+
+
+//
+// Fields are not indented if this is set
+//
+#define DBG_DUMP_NO_INDENT                0x00000001
+//
+// Offsets are not printed if this is set
+//
+#define DBG_DUMP_NO_OFFSET                0x00000002
+//
+// Verbose output
+//
+#define DBG_DUMP_VERBOSE                  0x00000004
+//
+// Callback is done for each of fields
+//
+#define DBG_DUMP_CALL_FOR_EACH            0x00000008
+//
+// A list of type is dumped, listLink should have info about next element pointer
+//
+#define DBG_DUMP_LIST                     0x00000020
+//
+// Nothing is printed if this is set (only callbacks and data copies done)
+//
+#define DBG_DUMP_NO_PRINT                 0x00000040
+//
+// Ioctl returns the size as usual, but will not do field prints/callbacks if this is set
+//
+#define DBG_DUMP_GET_SIZE_ONLY            0x00000080
+//
+// Specifies how much deep into structs we can go
+//
+#define DBG_DUMP_RECUR_LEVEL(l)           ((l & 0xf) << 8)
+//
+// No newlines are printed after each field
+//
+#define DBG_DUMP_COMPACT_OUT              0x00002000
+//
+// An array of type is dumped, number of elements can be specified in listLink->size
+//
+#define DBG_DUMP_ARRAY                    0x00008000
+//
+// The specified addr value is actually the address of field listLink->fName
+//
+#define DBG_DUMP_ADDRESS_OF_FIELD         0x00010000
+
+//
+// The specified addr value is actually the adress at the end of type
+//
+#define DBG_DUMP_ADDRESS_AT_END           0x00020000
+
+//
+// This could be used to copy only the primitive types like ULONG, PVOID etc.
+//    - will not work with structures/unions
+//
+#define DBG_DUMP_COPY_TYPE_DATA           0x00040000
+//
+// Flag to allow read directly from physical memory
+//
+#define DBG_DUMP_READ_PHYSICAL            0x00080000
+//
+// This causes a function type to be dumped in format function(arg1, arg2, ...)
+//
+#define DBG_DUMP_FUNCTION_FORMAT          0x00100000
+//
+// This recurses on a struct but doesn't expand pointers
+//
+#define DBG_DUMP_BLOCK_RECURSE            0x00200000
+//
+// Match the type size to resolve ambiguity in case multiple matches with same name are available
+//
+#define DBG_DUMP_MATCH_SIZE               0x00400000
+
+//
+// Obsolete defs
+//
+#define DBG_RETURN_TYPE                   0
+#define DBG_RETURN_SUBTYPES               0
+#define DBG_RETURN_TYPE_VALUES            0
+
+//
+// Dump and callback optons for fields - Options used in FIELD_INFO.fOptions
+//
+
+//
+// Callback is done before printing the field if this is set
+//
+#define DBG_DUMP_FIELD_CALL_BEFORE_PRINT  0x00000001
+//
+// No callback is done
+//
+#define DBG_DUMP_FIELD_NO_CALLBACK_REQ    0x00000002
+//
+// Subfields of the fields are processesed
+//
+#define DBG_DUMP_FIELD_RECUR_ON_THIS      0x00000004
+//
+// fName must match completely for the field to be dumped instead just a prefix
+//  match by default
+//
+#define DBG_DUMP_FIELD_FULL_NAME          0x00000008
+//
+// This causes array elements of an array field to be printed
+//
+#define DBG_DUMP_FIELD_ARRAY              0x00000010
+//
+// The data of the field is copied into fieldCallBack
+//
+#define DBG_DUMP_FIELD_COPY_FIELD_DATA    0x00000020
+//
+// In callback or when Ioctl returns, the FIELD_INFO.address has the address of field.
+//  If no address is supplied for the type, it contains total offset of the field.
+//
+#define DBG_DUMP_FIELD_RETURN_ADDRESS     0x00001000
+//
+// Return the offset and size in bits instead of bytes is case of Bitfield
+//
+#define DBG_DUMP_FIELD_SIZE_IN_BITS       0x00002000
+//
+// Nothing is printed  for field if this is set (only callbacks and data copies done)
+//
+#define DBG_DUMP_FIELD_NO_PRINT           0x00004000
+//
+// If the field is a pointer, it is dumped as a string, ANSI, WCHAR, MULTI or GUID
+// depending on following options
+//
+#define DBG_DUMP_FIELD_DEFAULT_STRING     0x00010000
+#define DBG_DUMP_FIELD_WCHAR_STRING       0x00020000
+#define DBG_DUMP_FIELD_MULTI_STRING       0x00040000
+#define DBG_DUMP_FIELD_GUID_STRING        0x00080000
+#define DBG_DUMP_FIELD_UTF32_STRING       0x00100000
+
+
+//
+// Error status returned on TYPE DUMP Ioctl failure
+//
+#define MEMORY_READ_ERROR            0x01
+#define SYMBOL_TYPE_INDEX_NOT_FOUND  0x02
+#define SYMBOL_TYPE_INFO_NOT_FOUND   0x03
+#define FIELDS_DID_NOT_MATCH         0x04
+#define NULL_SYM_DUMP_PARAM          0x05
+#define NULL_FIELD_NAME              0x06
+#define INCORRECT_VERSION_INFO       0x07
+#define EXIT_ON_CONTROLC             0x08
+#define CANNOT_ALLOCATE_MEMORY       0x09
+#define INSUFFICIENT_SPACE_TO_COPY   0x0a
+#define ADDRESS_TYPE_INDEX_NOT_FOUND 0x0b
+#define UNAVAILABLE_ERROR            0x0c
+
+
+//////////////////////////////////////////////////////////////////////////*/
+
+
+typedef
+ULONG
+(WDBGAPI*PSYM_DUMP_FIELD_CALLBACK)(
+    struct _FIELD_INFO *pField,
+    PVOID UserContext
+    );
+
+typedef struct _FIELD_INFO {
+   PUCHAR       fName;          // Name of the field
+   PUCHAR       printName;      // Name to be printed at dump
+   ULONG        size;           // Size of the field
+   ULONG        fOptions;       // Dump Options for the field
+   ULONG64      address;        // address of the field
+   union {
+       PVOID    fieldCallBack;  // Return info or callBack routine for the field
+       PVOID    pBuffer;        // the type data is copied into this
+   };
+   ULONG        TypeId;         // OUT Type index of the field
+   ULONG        FieldOffset;    // OUT Offset of field inside struct
+   ULONG        BufferSize;     // size of buffer used with DBG_DUMP_FIELD_COPY_FIELD_DATA
+   struct _BitField {
+       USHORT Position;         // OUT set to start position for bitfield
+       USHORT Size;             // OUT set to size for bitfields
+   } BitField;
+   ULONG        fPointer:2;     // OUT set to 1 for pointers, 3 for 64bit pointers
+   ULONG        fArray:1;       // OUT set to 1 for array types
+   ULONG        fStruct:1;      // OUT set to 1 for struct/class tyoes
+   ULONG        fConstant:1;    // OUT set to 1 for constants (enumerate as fields)
+   ULONG        fStatic:1;      // OUT set to 1 for statics (class/struct static members)
+   ULONG        Reserved:26;    // unused
+} FIELD_INFO, *PFIELD_INFO;
+
+typedef struct _SYM_DUMP_PARAM {
+   ULONG               size;          // size of this struct
+   PUCHAR              sName;         // type name
+   ULONG               Options;       // Dump options
+   ULONG64             addr;          // Address to take data for type
+   PFIELD_INFO         listLink;      // fName here would be used to do list dump
+   union {
+       PVOID           Context;       // Usercontext passed to CallbackRoutine
+       PVOID           pBuffer;       // the type data is copied into this
+   };
+   PSYM_DUMP_FIELD_CALLBACK CallbackRoutine;
+                                      // Routine called back
+   ULONG               nFields;       // # elements in Fields
+   _Field_size_opt_(nFields) PFIELD_INFO         Fields;        // Used to return information about field
+   ULONG64             ModBase;       // OUT Module base address containing type
+   ULONG               TypeId;        // OUT Type index of the symbol
+   ULONG               TypeSize;      // OUT Size of type
+   ULONG               BufferSize;    // IN size of buffer (used with DBG_DUMP_COPY_TYPE_DATA)
+   ULONG               fPointer:2;    // OUT set to 1 for pointers, 3 for 64bit pointers
+   ULONG               fArray:1;      // OUT set to 1 for array types
+   ULONG               fStruct:1;     // OUT set to 1 for struct/class tyoes
+   ULONG               fConstant:1;   // OUT set to 1 for constant types (unused)
+   ULONG               Reserved:27;   // unused
+} SYM_DUMP_PARAM, *PSYM_DUMP_PARAM;
+
+#ifdef __cplusplus
+#define CPPMOD extern "C"
+#else
+#define CPPMOD
+#endif
+
+
+#ifndef NOEXTAPI
+
+#if   defined(KDEXT_64BIT)
+#define WINDBG_EXTENSION_APIS WINDBG_EXTENSION_APIS64
+#define PWINDBG_EXTENSION_APIS PWINDBG_EXTENSION_APIS64
+#define PWINDBG_EXTENSION_ROUTINE PWINDBG_EXTENSION_ROUTINE64
+#define DECLARE_API(s) DECLARE_API64(s)
+#elif defined(KDEXT_32BIT)
+#define WINDBG_EXTENSION_APIS WINDBG_EXTENSION_APIS32
+#define PWINDBG_EXTENSION_APIS PWINDBG_EXTENSION_APIS32
+#define PWINDBG_EXTENSION_ROUTINE PWINDBG_EXTENSION_ROUTINE32
+#define DECLARE_API(s) DECLARE_API32(s)
+#else
+#define DECLARE_API(s)                             \
+    CPPMOD VOID                                    \
+    s(                                             \
+        HANDLE                 hCurrentProcess,    \
+        HANDLE                 hCurrentThread,     \
+        ULONG                  dwCurrentPc,        \
+        ULONG                  dwProcessor,        \
+        PCSTR                  args                \
+     )
+#endif
+
+#define DECLARE_API32(s)                           \
+    CPPMOD VOID                                    \
+    s(                                             \
+        HANDLE                 hCurrentProcess,    \
+        HANDLE                 hCurrentThread,     \
+        ULONG                  dwCurrentPc,        \
+        ULONG                  dwProcessor,        \
+        PCSTR                  args                \
+     )
+
+#define DECLARE_API64(s)                           \
+    CPPMOD VOID                                    \
+    s(                                             \
+        HANDLE                 hCurrentProcess,    \
+        HANDLE                 hCurrentThread,     \
+        ULONG64                dwCurrentPc,        \
+        ULONG                  dwProcessor,        \
+        PCSTR                  args                \
+     )
+
+
+extern WINDBG_EXTENSION_APIS   ExtensionApis;
+
+
+#define dprintf          (ExtensionApis.lpOutputRoutine)
+#define GetExpression    (ExtensionApis.lpGetExpressionRoutine)
+#define CheckControlC    (ExtensionApis.lpCheckControlCRoutine)
+#define GetContext       (ExtensionApis.lpGetThreadContextRoutine)
+#define SetContext       (ExtensionApis.lpSetThreadContextRoutine)
+#define Ioctl            (ExtensionApis.lpIoctlRoutine)
+#define Disasm           (ExtensionApis.lpDisasmRoutine)
+#define GetSymbol        (ExtensionApis.lpGetSymbolRoutine)
+#define ReadMemory       (ExtensionApis.lpReadProcessMemoryRoutine)
+#define WriteMemory      (ExtensionApis.lpWriteProcessMemoryRoutine)
+#define StackTrace       (ExtensionApis.lpStackTraceRoutine)
+
+
+#define GetKdContext(ppi) \
+    Ioctl( IG_KD_CONTEXT, (PVOID)ppi, sizeof(*ppi) )
+
+
+//
+// BOOL
+// GetDebuggerData(
+//     ULONG Tag,
+//     PVOID Buf,
+//     ULONG Size
+//     )
+//
+
+#define GetDebuggerData(TAG, BUF, SIZE)                             \
+      ( (((PDBGKD_DEBUG_DATA_HEADER64)(BUF))->OwnerTag = (TAG)),      \
+        (((PDBGKD_DEBUG_DATA_HEADER64)(BUF))->Size = (SIZE)),         \
+        Ioctl( IG_GET_DEBUGGER_DATA, (PVOID)(BUF), (SIZE) ) )
+
+// Check if LocalAlloc is prototyped
+//#ifdef _WINBASE_
+
+__inline VOID
+ReadPhysical(
+    ULONG64             address,
+    _Out_writes_bytes_to_(size, *sizer) PVOID buf,
+    ULONG               size,
+    _Out_ PULONG        sizer
+    )
+{
+    PPHYSICAL phy = NULL;
+    *sizer = 0;
+    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*phy)) {
+        phy = (PPHYSICAL)LocalAlloc(LPTR,  sizeof(*phy) + size );
+    }
+    if (phy) {
+        ZeroMemory( phy->Buf, size );
+        phy->Address = address;
+        phy->BufLen = size;
+        Ioctl( IG_READ_PHYSICAL, (PVOID)phy, sizeof(*phy) + size );
+        *sizer = (phy->BufLen > size) ? size : phy->BufLen;
+        CopyMemory( buf, phy->Buf, *sizer );
+        LocalFree( phy );
+    }
+}
+
+__inline VOID
+WritePhysical(
+    ULONG64             address,
+    _In_reads_bytes_(size) PVOID buf,
+    ULONG               size,
+    _Out_ PULONG        sizew
+    )
+{
+    PPHYSICAL phy = NULL;
+    *sizew = 0;
+    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*phy)) {
+        phy = (PPHYSICAL)LocalAlloc(LPTR, sizeof(*phy) + size );
+    }
+    if (phy) {
+        ZeroMemory( phy->Buf, size );
+        phy->Address = address;
+        phy->BufLen = size;
+        CopyMemory( phy->Buf, buf, size );
+        Ioctl( IG_WRITE_PHYSICAL, (PVOID)phy, sizeof(*phy) + size );
+        *sizew = phy->BufLen;
+        LocalFree( phy );
+    }
+}
+
+__inline VOID
+ReadPhysicalWithFlags(
+    ULONG64             address,
+    _Out_writes_bytes_to_(size, *sizer) PVOID buf,
+    ULONG               size,
+    ULONG               flags,
+    _Out_ PULONG        sizer
+    )
+{
+    PPHYSICAL_WITH_FLAGS phy = NULL;
+    *sizer = 0;
+    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*phy)) {
+        phy = (PPHYSICAL_WITH_FLAGS)LocalAlloc(LPTR,  sizeof(*phy) + size );
+    }
+    if (phy) {
+        ZeroMemory( phy->Buf, size );
+        phy->Address = address;
+        phy->BufLen = size;
+        phy->Flags = flags;
+        Ioctl( IG_READ_PHYSICAL_WITH_FLAGS, (PVOID)phy, sizeof(*phy) + size );
+        *sizer = (phy->BufLen > size) ? size : phy->BufLen;
+        CopyMemory( buf, phy->Buf, *sizer );
+        LocalFree( phy );
+    }
+}
+
+__inline VOID
+WritePhysicalWithFlags(
+    ULONG64             address,
+    _In_reads_bytes_(size) PVOID buf,
+    ULONG               size,
+    ULONG               flags,
+    _Out_ PULONG        sizew
+    )
+{
+    PPHYSICAL_WITH_FLAGS phy = NULL;
+    *sizew = 0;
+    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*phy)) {
+        phy = (PPHYSICAL_WITH_FLAGS)LocalAlloc(LPTR, sizeof(*phy) + size );
+    }
+    if (phy) {
+        ZeroMemory( phy->Buf, size );
+        phy->Address = address;
+        phy->BufLen = size;
+        phy->Flags = flags;
+        CopyMemory( phy->Buf, buf, size );
+        Ioctl( IG_WRITE_PHYSICAL_WITH_FLAGS, (PVOID)phy, sizeof(*phy) + size );
+        *sizew = phy->BufLen;
+        LocalFree( phy );
+    }
+}
+
+__inline VOID
+ReadMsr(
+    ULONG       MsrReg,
+    _Out_ ULONGLONG *MsrValue
+    )
+{
+    READ_WRITE_MSR msr;
+
+    msr.Msr = MsrReg;
+    Ioctl( IG_READ_MSR, (PVOID)&msr, sizeof(msr) );
+
+    *MsrValue = msr.Value;
+}
+
+__inline VOID
+WriteMsr(
+    ULONG       MsrReg,
+    ULONGLONG   MsrValue
+    )
+{
+    READ_WRITE_MSR msr;
+
+    msr.Msr = MsrReg;
+    msr.Value = MsrValue;
+    Ioctl( IG_WRITE_MSR, (PVOID)&msr, sizeof(msr) );
+}
+
+__inline VOID
+SetThreadForOperation(
+    ULONG_PTR * Thread
+    )
+{
+    Ioctl(IG_SET_THREAD, (PVOID)Thread, sizeof(PULONG));
+}
+
+__inline VOID
+SetThreadForOperation32(
+    ULONG Thread
+    )
+{
+    Ioctl(IG_SET_THREAD, (PVOID)LongToPtr(Thread), sizeof(ULONG));
+}
+
+__inline VOID
+SetThreadForOperation64(
+    PULONG64 Thread
+    )
+{
+    Ioctl(IG_SET_THREAD, (PVOID)Thread, sizeof(ULONG64));
+}
+
+
+__inline VOID
+ReadControlSpace(
+    USHORT  processor,
+    ULONG   address,
+    _Out_writes_bytes_to_(size, 0) PVOID   buf,
+    ULONG   size
+    )
+{
+    PREADCONTROLSPACE prc = NULL;
+    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*prc)) {
+        prc = (PREADCONTROLSPACE)LocalAlloc(LPTR, sizeof(*prc) + size );
+    }
+    if (prc) {
+        ZeroMemory( prc->Buf, size );
+        prc->Processor = processor;
+        prc->Address = address;
+        prc->BufLen = size;
+        Ioctl( IG_READ_CONTROL_SPACE, (PVOID)prc, sizeof(*prc) + size );
+        CopyMemory( buf, prc->Buf, size );
+        LocalFree( prc );
+    }
+}
+
+__inline VOID
+ReadControlSpace32(
+    USHORT  processor,
+    ULONG   address,
+    _Out_writes_bytes_to_(size, 0) PVOID   buf,
+    ULONG   size
+    )
+{
+    PREADCONTROLSPACE32 prc = NULL;
+    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*prc)) {
+        prc = (PREADCONTROLSPACE32)LocalAlloc(LPTR, sizeof(*prc) + size );
+    }
+    if (prc) {
+        ZeroMemory( prc->Buf, size );
+        prc->Processor = processor;
+        prc->Address = address;
+        prc->BufLen = size;
+        Ioctl( IG_READ_CONTROL_SPACE, (PVOID)prc, sizeof(*prc) + size );
+        CopyMemory( buf, prc->Buf, size );
+        LocalFree( prc );
+    }
+}
+
+#define ReadTypedControlSpace32( _Proc, _Addr, _Buf )  \
+     ReadControlSpace64( (USHORT)(_Proc), (ULONG)(_Addr), (PVOID)&(_Buf), (ULONG)sizeof(_Buf) )
+
+__inline VOID
+ReadControlSpace64(
+    USHORT  processor,
+    ULONG64 address,
+    _Out_writes_bytes_to_(size, 0) PVOID   buf,
+    ULONG   size
+    )
+{
+    PREADCONTROLSPACE64 prc = NULL;
+    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*prc)) {
+        prc = (PREADCONTROLSPACE64)LocalAlloc(LPTR, sizeof(*prc) + size );
+    }
+    if (prc) {
+        ZeroMemory( prc->Buf, size );
+        prc->Processor = processor;
+        prc->Address = address;
+        prc->BufLen = size;
+        Ioctl( IG_READ_CONTROL_SPACE, (PVOID)prc, sizeof(*prc) + size );
+        CopyMemory( buf, prc->Buf, size );
+        LocalFree( prc );
+    }
+}
+
+#define ReadTypedControlSpace64( _Proc, _Addr, _Buf )  \
+     ReadControlSpace64( (USHORT)(_Proc), (ULONG64)(_Addr), (PVOID)&(_Buf), (ULONG)sizeof(_Buf) )
+
+__inline VOID
+WriteControlSpace(
+    USHORT  processor,
+    ULONG   address,
+    _In_reads_bytes_(size) PVOID   buf,
+    ULONG   size
+    )
+{
+    PREADCONTROLSPACE64 prc = NULL;
+    if (size <= WDBGEXTS_MAXSIZE_T - sizeof(*prc)) {
+        prc = (PREADCONTROLSPACE64)LocalAlloc(LPTR, sizeof(*prc) + size );
+    }
+    if (prc) {
+        ZeroMemory( prc->Buf, size );
+        prc->Processor = processor;
+        prc->Address = address;
+        prc->BufLen = size;
+        CopyMemory( prc->Buf, buf, size );
+        Ioctl( IG_WRITE_CONTROL_SPACE, (PVOID)prc, sizeof(*prc) + size );
+        LocalFree( prc );
+    }
+}
+
+// #endif //  _WINBASE_
+
+__inline VOID
+ReadIoSpace(
+    ULONG   address,
+    _Out_writes_bytes_(*size) PULONG  data,
+    _Inout_ PULONG  size
+    )
+{
+    IOSPACE is;
+    is.Address = address;
+    is.Length = *size;
+    Ioctl( IG_READ_IO_SPACE, (PVOID)&is, sizeof(is) );
+    *size = (is.Length > *size) ? *size : is.Length;
+    memcpy(data, &is.Data, *size);
+}
+
+__inline VOID
+ReadIoSpace32(
+    ULONG   address,
+    _Out_writes_bytes_(*size) PULONG  data,
+    _Inout_ PULONG  size
+    )
+{
+    IOSPACE32 is;
+    is.Address = address;
+    is.Length = *size;
+    Ioctl( IG_READ_IO_SPACE, (PVOID)&is, sizeof(is) );
+    *size = (is.Length > *size) ? *size : is.Length;
+    memcpy(data, &is.Data, *size);
+}
+
+__inline VOID
+ReadIoSpace64(
+    ULONG64 address,
+    _Out_writes_bytes_(*size) PULONG  data,
+    _Inout_ PULONG  size
+    )
+{
+    IOSPACE64 is;
+    is.Address = address;
+    is.Length = *size;
+    Ioctl( IG_READ_IO_SPACE, (PVOID)&is, sizeof(is) );
+    *size = (is.Length > *size) ? *size : is.Length;
+    memcpy(data, &is.Data, *size);
+}
+
+__inline VOID
+WriteIoSpace(
+    ULONG   address,
+    ULONG   data,
+    _Inout_ PULONG  size
+    )
+{
+    IOSPACE is;
+    is.Address = (ULONG)address;
+    is.Length = *size;
+    is.Data = data;
+    Ioctl( IG_WRITE_IO_SPACE, (PVOID)&is, sizeof(is) );
+    *size = is.Length;
+}
+
+__inline VOID
+WriteIoSpace32(
+    ULONG   address,
+    ULONG   data,
+    _Inout_ PULONG  size
+    )
+{
+    IOSPACE32 is;
+    is.Address = address;
+    is.Length = *size;
+    is.Data = data;
+    Ioctl( IG_WRITE_IO_SPACE, (PVOID)&is, sizeof(is) );
+    *size = is.Length;
+}
+
+__inline VOID
+WriteIoSpace64(
+    ULONG64 address,
+    ULONG   data,
+    _Inout_ PULONG  size
+    )
+{
+    IOSPACE64 is;
+    is.Address = address;
+    is.Length = *size;
+    is.Data = data;
+    Ioctl( IG_WRITE_IO_SPACE, (PVOID)&is, sizeof(is) );
+    *size = is.Length;
+}
+
+__inline VOID
+ReadIoSpaceEx(
+    ULONG   address,
+    _Out_ PULONG  data,
+    _Inout_ PULONG  size,
+    ULONG   interfacetype,
+    ULONG   busnumber,
+    ULONG   addressspace
+    )
+{
+    IOSPACE_EX is;
+    is.Address = (ULONG)address;
+    is.Length = *size;
+    is.Data = 0;
+    is.InterfaceType = interfacetype;
+    is.BusNumber = busnumber;
+    is.AddressSpace = addressspace;
+    Ioctl( IG_READ_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
+    *data = is.Data;
+    *size = is.Length;
+}
+
+__inline VOID
+ReadIoSpaceEx32(
+    ULONG   address,
+    _Out_ PULONG  data,
+    _Inout_ PULONG  size,
+    ULONG   interfacetype,
+    ULONG   busnumber,
+    ULONG   addressspace
+    )
+{
+    IOSPACE_EX32 is;
+    is.Address = address;
+    is.Length = *size;
+    is.Data = 0;
+    is.InterfaceType = interfacetype;
+    is.BusNumber = busnumber;
+    is.AddressSpace = addressspace;
+    Ioctl( IG_READ_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
+    *data = is.Data;
+    *size = is.Length;
+}
+
+__inline VOID
+ReadIoSpaceEx64(
+    ULONG64 address,
+    _Out_ PULONG  data,
+    _Inout_ PULONG  size,
+    ULONG   interfacetype,
+    ULONG   busnumber,
+    ULONG   addressspace
+    )
+{
+    IOSPACE_EX64 is;
+    is.Address = address;
+    is.Length = *size;
+    is.Data = 0;
+    is.InterfaceType = interfacetype;
+    is.BusNumber = busnumber;
+    is.AddressSpace = addressspace;
+    Ioctl( IG_READ_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
+    *data = is.Data;
+    *size = is.Length;
+}
+
+__inline VOID
+WriteIoSpaceEx(
+    ULONG   address,
+    ULONG   data,
+    _Inout_ PULONG  size,
+    ULONG   interfacetype,
+    ULONG   busnumber,
+    ULONG   addressspace
+    )
+{
+    IOSPACE_EX is;
+    is.Address = (ULONG)address;
+    is.Length = *size;
+    is.Data = data;
+    is.InterfaceType = interfacetype;
+    is.BusNumber = busnumber;
+    is.AddressSpace = addressspace;
+    Ioctl( IG_WRITE_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
+    *size = is.Length;
+}
+
+__inline VOID
+WriteIoSpaceEx32(
+    ULONG   address,
+    ULONG   data,
+    _Inout_ PULONG  size,
+    ULONG   interfacetype,
+    ULONG   busnumber,
+    ULONG   addressspace
+    )
+{
+    IOSPACE_EX32 is;
+    is.Address = address;
+    is.Length = *size;
+    is.Data = data;
+    is.InterfaceType = interfacetype;
+    is.BusNumber = busnumber;
+    is.AddressSpace = addressspace;
+    Ioctl( IG_WRITE_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
+    *size = is.Length;
+}
+
+__inline VOID
+WriteIoSpaceEx64(
+    ULONG64 address,
+    ULONG   data,
+    _Inout_ PULONG  size,
+    ULONG   interfacetype,
+    ULONG   busnumber,
+    ULONG   addressspace
+    )
+{
+    IOSPACE_EX64 is;
+    is.Address = address;
+    is.Length = *size;
+    is.Data = data;
+    is.InterfaceType = interfacetype;
+    is.BusNumber = busnumber;
+    is.AddressSpace = addressspace;
+    Ioctl( IG_WRITE_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
+    *size = is.Length;
+}
+
+__inline VOID
+ReloadSymbols(
+    _In_ PSTR Arg OPTIONAL
+    )
+/*++
+
+Routine Description:
+
+    Calls the debugger to reload symbols.
+
+Arguments:
+
+    Args - Supplies the tail of a !reload command string.
+
+        !reload [flags] [module[=address]]
+        flags:   /n  do not load from usermode list
+                 /u  unload symbols, no reload
+                 /v  verbose
+
+        A value of NULL is equivalent to an empty string
+
+Return Value:
+
+    None
+
+--*/
+{
+    Ioctl(IG_RELOAD_SYMBOLS, (PVOID)Arg, Arg?((ULONG)strlen(Arg)+1):0);
+}
+
+__inline VOID
+GetSetSympath(
+    _In_ PSTR Arg,
+    _Out_writes_to_opt_(Length, 0) PSTR Result OPTIONAL,
+    int Length
+    )
+/*++
+
+Routine Description:
+
+    Calls the debugger to set or retrieve symbol search path.
+
+Arguments:
+
+    Arg - Supplies new search path.  If Arg is NULL or string is empty,
+            the search path is not changed and the current setting is
+            returned in Result.  When the symbol search path is changed,
+            a call to ReloadSymbols is made implicitly.
+
+    Result - OPTIONAL Returns the symbol search path setting.
+
+    Length - Supplies the size of the buffer supplied by Result.
+
+Return Value:
+
+    None
+
+--*/
+{
+    GET_SET_SYMPATH gss;
+    gss.Args = Arg;
+    gss.Result = Result;
+    gss.Length = Length;
+    Ioctl(IG_GET_SET_SYMPATH, (PVOID)&gss, sizeof(gss));
+    if (Result)
+    {
+        Result[Length - 1] = 0;
+    }
+}
+
+#if   defined(KDEXT_64BIT)
+
+__inline
+ULONG
+IsPtr64(
+    void
+    )
+{
+    ULONG flag;
+    ULONG dw;
+
+    if (Ioctl(IG_IS_PTR64, &dw, sizeof(dw))) {
+        flag = ((dw != 0) ? 1 : 0);
+    } else {
+        flag = 0;
+    }
+    return flag;
+}
+
+__inline
+ULONG
+ReadListEntry(
+    ULONG64 Address,
+    PLIST_ENTRY64 List
+    )
+{
+    ULONG cb;
+    if (IsPtr64()) {
+        return (ReadMemory(Address, (PVOID)List, sizeof(*List), &cb) &&
+                cb == sizeof(*List));
+    } else {
+        LIST_ENTRY32 List32;
+        ULONG Status;
+        Status = ReadMemory(Address,
+                            (PVOID)&List32,
+                            sizeof(List32),
+                            &cb);
+        if (Status && cb == sizeof(List32)) {
+            List->Flink = (ULONG64)(LONG64)(LONG)List32.Flink;
+            List->Blink = (ULONG64)(LONG64)(LONG)List32.Blink;
+            return 1;
+        }
+        return 0;
+    }
+}
+
+__inline
+ULONG
+ReadPointer(
+    ULONG64 Address,
+    PULONG64 Pointer
+    )
+{
+    ULONG cb;
+    if (IsPtr64()) {
+        return (ReadMemory(Address, (PVOID)Pointer, sizeof(*Pointer), &cb) &&
+                cb == sizeof(*Pointer));
+    } else {
+        ULONG Pointer32;
+        ULONG Status;
+        Status = ReadMemory(Address,
+                            (PVOID)&Pointer32,
+                            sizeof(Pointer32),
+                            &cb);
+        if (Status && cb == sizeof(Pointer32)) {
+            *Pointer = (ULONG64)(LONG64)(LONG)Pointer32;
+            return 1;
+        }
+        return 0;
+    }
+}
+
+__inline
+ULONG
+WritePointer(
+    ULONG64 Address,
+    ULONG64 Pointer
+    )
+{
+    ULONG cb;
+    if (IsPtr64()) {
+        return (WriteMemory(Address, &Pointer, sizeof(Pointer), &cb) &&
+                cb == sizeof(Pointer));
+    } else {
+        ULONG Pointer32 = (ULONG)Pointer;
+        ULONG Status;
+        Status = WriteMemory(Address,
+                             &Pointer32,
+                             sizeof(Pointer32),
+                             &cb);
+        return (Status && cb == sizeof(Pointer32)) ? 1 : 0;
+    }
+}
+
+/**
+   This does Ioctl call for type info and returns size of the type on success.
+
+ **/
+__inline
+ULONG
+GetTypeSize (
+   IN LPCSTR    Type
+   )
+{
+   SYM_DUMP_PARAM Sym = {
+      sizeof (SYM_DUMP_PARAM), (PUCHAR)Type, DBG_DUMP_NO_PRINT | DBG_DUMP_GET_SIZE_ONLY, 0,
+      NULL, NULL, NULL, 0, NULL
+   };
+
+   return Ioctl( IG_GET_TYPE_SIZE, &Sym, Sym.size );
+}
+
+/**
+    GetFieldData
+
+   Copies the value of the specified field into pOutValue assuming TypeAddress
+   points to start of the type in debugee.
+
+   If the Field is NULL and the size of Type is <= 8 Whole type value is read into
+   pOutValue. This is to allow to read in primitive types suchas ULONG, PVOID etc.
+
+   If address is zero this considers Type a global variable.
+
+   It raises an exception if OutSize is less than size to be copied.
+
+   Returns 0 on success, errorvalue (defined with SYM_DUMP_PARAM) otherwise.
+
+ **/
+__inline
+ULONG
+GetFieldData (
+    _In_ ULONG64 TypeAddress,
+    _In_ LPCSTR  Type,
+    _In_ LPCSTR  Field,
+    _In_ ULONG   OutSize,
+    _Out_writes_bytes_(OutSize) PVOID pOutValue
+   )
+{
+   FIELD_INFO flds = {(PUCHAR)Field, NULL, 0, DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_COPY_FIELD_DATA | DBG_DUMP_FIELD_RETURN_ADDRESS, 0, pOutValue};
+   SYM_DUMP_PARAM Sym = {
+      sizeof (SYM_DUMP_PARAM), (PUCHAR)Type, DBG_DUMP_NO_PRINT, TypeAddress,
+      NULL, NULL, NULL, 1, &flds
+   };
+   ULONG RetVal;
+
+   if (!Field) {
+       Sym.nFields =0; Sym.Options |= DBG_DUMP_COPY_TYPE_DATA;
+       Sym.Context = pOutValue;
+   }
+
+   ZeroMemory(pOutValue, OutSize);
+   RetVal = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
+
+   if (OutSize < ((Field == NULL) ? 8 : flds.size)) {
+       // Fail
+       dprintf("Not enough space to read %s-%s\n", Type, Field);
+       RaiseException((DWORD)EXCEPTION_ACCESS_VIOLATION, 0, 0, NULL);
+       return 0;
+   }
+   return RetVal;
+}
+
+//
+// Typecast the buffer where value is to be read
+//
+#define GetFieldValue(Addr, Type, Field, OutValue)         \
+     GetFieldData(Addr, Type, Field, sizeof(OutValue), (PVOID) &(OutValue))
+
+//
+// Used to read in value of a short (<= 8 bytes) fields
+//
+__inline
+ULONG64
+GetShortField (
+    IN  ULONG64 TypeAddress,
+    IN  LPCSTR  Name,
+    IN  USHORT  StoreAddress
+   )
+{
+    static ULONG64 SavedAddress;
+    static PUCHAR  SavedName;
+    static ULONG   ReadPhysical;
+    FIELD_INFO flds = {(PUCHAR) Name, NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL};
+    SYM_DUMP_PARAM Sym = {
+       (ULONG)sizeof (SYM_DUMP_PARAM), SavedName, DBG_DUMP_NO_PRINT | ((StoreAddress & 2) ? DBG_DUMP_READ_PHYSICAL : (ULONG)0),
+       SavedAddress, NULL, NULL, NULL, 1, &flds
+    };
+
+
+    if (StoreAddress) {
+        Sym.sName = (PUCHAR) Name;
+        Sym.nFields = 0;
+        SavedName = (PUCHAR) Name;
+        Sym.addr = SavedAddress = TypeAddress;
+        ReadPhysical = (StoreAddress & 2);
+        return SavedAddress ? Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size ) : MEMORY_READ_ERROR; // zero on success
+    } else {
+        Sym.Options |= ReadPhysical ? DBG_DUMP_READ_PHYSICAL : 0;
+    }
+
+    if (!Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size )) {
+        return flds.address;
+    }
+    return 0;
+}
+
+//
+// Stores the address and type name for future reads
+//
+#define InitTypeRead(Addr, Type)  GetShortField(Addr, #Type, 1)
+#define InitTypeStrRead(Addr, TypeStr)  GetShortField(Addr, TypeStr, 1)
+
+//
+// Stores the address and type name for future reads
+//
+#define InitTypeReadPhysical(Addr, Type)  GetShortField(Addr, #Type, 3)
+#define InitTypeStrReadPhysical(Addr, TypeStr)  GetShortField(Addr, TypeStr, 3)
+
+//
+// Returns the field's value as ULONG64 if size of field is <= sizeof (ULONG64)
+//
+#define ReadField(Field)          GetShortField(0, #Field, 0)
+#define ReadFieldStr(FieldStr)          GetShortField(0, FieldStr, 0)
+
+//
+// Read in a pointer value
+//
+__inline
+ULONG
+ReadPtr(
+    ULONG64 Addr,
+    PULONG64 pPointer
+    )
+{
+    return !ReadPointer(Addr, pPointer);
+}
+
+/*
+ * ListType
+ *
+ *  Routine ListType gives a callback on each element in the list of Type.
+ *
+ *   Type  :  Name of the type to be listed
+ *
+ *   NextPointer : Name of field which gives address of next element in list
+ *
+ *   Context, CallbackRoutine :
+ *            Context and the callback routine. The address field in PFIELD_INFO
+ *            parameter of callback contains the address of next Type element in list.
+ *
+ *   Address, ListByFieldAddress :
+ *      if ListByFieldAddress is 0, Adress is the address of first element of Type List.
+ *
+ *   Lists by LIST_ENTRY are also handled implicitly (by Ioctl). If the NextPointer
+ *   is a pointer to LIST_ENTRY type, the type address is properly calculated by
+ *   subtracting the offsets.
+ *
+ *      If ListByFieldAddress is 1, the Address is considered to be the address of field
+ *   "NextPointer" of the first Type element and first element address is derived
+ *   from it.
+ *
+ */
+
+__inline
+ULONG
+ListType (
+    IN LPCSTR  Type,
+    IN ULONG64 Address,
+    IN USHORT  ListByFieldAddress,
+    IN LPCSTR  NextPointer,
+    IN PVOID   Context,
+    IN PSYM_DUMP_FIELD_CALLBACK CallbackRoutine
+    )
+{
+    FIELD_INFO flds = {(PUCHAR)NextPointer, NULL, 0, 0, 0, NULL};
+    SYM_DUMP_PARAM Sym = {
+       sizeof (SYM_DUMP_PARAM), (PUCHAR) Type, DBG_DUMP_NO_PRINT | DBG_DUMP_LIST, Address,
+       &flds, Context, CallbackRoutine, 0, NULL
+    };
+
+    if (ListByFieldAddress==1) {
+        //
+        // Address is the address of "NextPointer"
+        //
+        Sym.Options |= DBG_DUMP_ADDRESS_OF_FIELD;
+    }
+
+    return Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
+}
+
+
+/**
+
+   Routine to get offset of a "Field" of "Type" on a debugee machine. This uses
+   Ioctl call for type info.
+   Returns 0 on success, Ioctl error value otherwise.
+
+ **/
+
+__inline
+ULONG
+GetFieldOffset (
+   IN LPCSTR     Type,
+   IN LPCSTR     Field,
+   OUT PULONG   pOffset
+   )
+{
+   FIELD_INFO flds = {
+       (PUCHAR)Field,
+       (PUCHAR)"",
+       0,
+       DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_RETURN_ADDRESS,
+       0,
+       NULL};
+
+   SYM_DUMP_PARAM Sym = {
+      sizeof (SYM_DUMP_PARAM),
+      (PUCHAR)Type,
+      DBG_DUMP_NO_PRINT,
+      0,
+      NULL,
+      NULL,
+      NULL,
+      1,
+      &flds
+   };
+
+   ULONG Err;
+
+   Sym.nFields = 1;
+   Err = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
+   *pOffset = (ULONG) flds.FieldOffset;
+   return Err;
+}
+
+
+#endif // defined(KDEXT_64BIT)
+
+__inline VOID
+ GetCurrentProcessHandle(
+    PHANDLE hp
+    )
+{
+    Ioctl(IG_GET_CURRENT_PROCESS_HANDLE, hp, sizeof(HANDLE));
+}
+
+__inline VOID
+ GetTebAddress(
+    PULONGLONG Address
+    )
+{
+    GET_TEB_ADDRESS gpt;
+    gpt.Address = 0;
+    Ioctl(IG_GET_TEB_ADDRESS, (PVOID)&gpt, sizeof(gpt));
+    *Address = gpt.Address;
+}
+
+__inline VOID
+ GetPebAddress(
+    ULONG64 CurrentThread,
+    PULONGLONG Address
+    )
+{
+    GET_PEB_ADDRESS gpt;
+    gpt.CurrentThread = CurrentThread;
+    gpt.Address = 0;
+    Ioctl(IG_GET_PEB_ADDRESS, (PVOID)&gpt, sizeof(gpt));
+    *Address = gpt.Address;
+}
+
+__inline VOID
+ GetCurrentThreadAddr(
+    DWORD    Processor,
+    PULONG64  Address
+    )
+{
+    GET_CURRENT_THREAD_ADDRESS ct;
+    ct.Processor = Processor;
+    Ioctl(IG_GET_CURRENT_THREAD, (PVOID)&ct, sizeof(ct));
+    *Address = ct.Address;
+}
+
+__inline VOID
+ GetCurrentProcessAddr(
+    DWORD    Processor,
+    ULONG64  CurrentThread,
+    PULONG64 Address
+    )
+{
+    GET_CURRENT_PROCESS_ADDRESS cp;
+    cp.Processor = Processor;
+    cp.CurrentThread = CurrentThread;
+    Ioctl(IG_GET_CURRENT_PROCESS, (PVOID)&cp, sizeof(cp));
+    *Address = cp.Address;
+}
+
+__inline VOID
+SearchMemory(
+    ULONG64  SearchAddress,
+    ULONG64  SearchLength,
+    ULONG    PatternLength,
+    PVOID    Pattern,
+    PULONG64 FoundAddress
+    )
+{
+    SEARCHMEMORY sm;
+    sm.SearchAddress = SearchAddress;
+    sm.SearchLength  = SearchLength;
+    sm.FoundAddress  = 0;
+    sm.PatternLength = PatternLength;
+    sm.Pattern       = Pattern;
+    Ioctl(IG_SEARCH_MEMORY, (PVOID)&sm, sizeof(sm));
+    *FoundAddress = sm.FoundAddress;
+}
+
+__inline ULONG
+GetInputLine(
+    PCSTR Prompt,
+    _Out_writes_to_(BufferSize, 0) PSTR Buffer,
+    ULONG BufferSize
+    )
+{
+    GET_INPUT_LINE InLine;
+    InLine.Prompt = Prompt;
+    InLine.Buffer = Buffer;
+    InLine.BufferSize = BufferSize;
+    if (Ioctl(IG_GET_INPUT_LINE, (PVOID)&InLine, sizeof(InLine)))
+    {
+        Buffer[BufferSize - 1] = 0;
+        return InLine.InputSize;
+    }
+    else
+    {
+        Buffer[BufferSize - 1] = 0;
+        return 0;
+    }
+}
+
+__inline BOOL
+GetExpressionEx(
+    PCSTR Expression,
+    ULONG64* Value,
+    PCSTR* Remainder
+    )
+{
+    GET_EXPRESSION_EX Expr;
+    Expr.Expression = Expression;
+    if (Ioctl(IG_GET_EXPRESSION_EX, (PVOID)&Expr, sizeof(Expr)))
+    {
+        *Value = Expr.Value;
+
+        if (Remainder != NULL)
+        {
+            *Remainder = Expr.Remainder;
+        }
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+__inline BOOL
+TranslateVirtualToPhysical(
+    ULONG64 Virtual,
+    ULONG64* Physical
+    )
+{
+    TRANSLATE_VIRTUAL_TO_PHYSICAL VToP;
+    VToP.Virtual = Virtual;
+    if (Ioctl(IG_TRANSLATE_VIRTUAL_TO_PHYSICAL, (PVOID)&VToP, sizeof(VToP)))
+    {
+        *Physical = VToP.Physical;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+__inline BOOL
+GetDebuggerCacheSize(
+    OUT PULONG64 CacheSize
+    )
+{
+    return Ioctl(IG_GET_CACHE_SIZE, (PVOID) CacheSize, sizeof(ULONG64));
+}
+
+__inline BOOL
+ExtMatchPatternA(
+    IN PCSTR Str,
+    IN PCSTR Pattern,
+    IN BOOL CaseSensitive
+    )
+{
+    EXT_MATCH_PATTERN_A Args;
+
+    Args.Str = Str;
+    Args.Pattern = Pattern;
+    Args.CaseSensitive = CaseSensitive;
+    return Ioctl(IG_MATCH_PATTERN_A, (PVOID)&Args, sizeof(Args));
+}
+
+#endif
+
+#pragma warning(default:4115 4201 4204 4214 4221)
+#if _MSC_VER >= 1200
+#pragma warning(pop)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
+#pragma endregion
+
+#endif // _WDBGEXTS_
diff --git a/src/SOS/inc/host.h b/src/SOS/inc/host.h
new file mode 100644 (file)
index 0000000..33e9003
--- /dev/null
@@ -0,0 +1,59 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#pragma once
+
+#include <stdarg.h>
+#include <unknwn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ITarget;
+
+/// <summary>
+/// IHost - Provides native services from the host to SOS.
+/// </summary>
+MIDL_INTERFACE("E0CD8534-A88B-40D7-91BA-1B4C925761E9")
+IHost : public IUnknown
+{
+public:
+    /// <summary>
+    /// The type hosting the native SOS code. Must match HostType.
+    /// </summary>
+    enum HostType
+    {
+        DotnetDump,
+        Lldb,
+        DbgEng,
+        Vs
+    };
+
+    /// <summary>
+    /// Returns the host type
+    /// </summary>
+    virtual HostType STDMETHODCALLTYPE GetHostType() = 0;
+
+    /// <summary>
+    /// Returns the native service for the given interface id. There is 
+    /// only a limited set of services that can be queried through this
+    /// function. Adds a reference like QueryInterface.
+    /// </summary>
+    /// <param name="serviceId">guid of the service</param>
+    /// <param name="service">pointer to return service instance</param>
+    /// <returns>S_OK or E_NOINTERFACE</returns>
+    virtual HRESULT STDMETHODCALLTYPE GetService(REFIID serviceId, PVOID* service) = 0;
+
+    /// <summary>
+    /// Returns the current target instance or null. Adds a reference.
+    /// </summary>
+    /// <param name="ppTarget">pointer to write current target instance</param>
+    /// <returns>error code</returns>
+    virtual HRESULT STDMETHODCALLTYPE GetCurrentTarget(ITarget** ppTarget) = 0;
+};
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/src/SOS/inc/lldbservices.h b/src/SOS/inc/lldbservices.h
new file mode 100644 (file)
index 0000000..9808685
--- /dev/null
@@ -0,0 +1,586 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+//----------------------------------------------------------------------------
+//
+// LLDB debugger services for sos
+//
+//----------------------------------------------------------------------------
+
+#pragma once
+
+#include <stdarg.h>
+#include <unknwn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Output mask bits.
+// Normal output.
+#define DEBUG_OUTPUT_NORMAL            0x00000001
+// Error output.
+#define DEBUG_OUTPUT_ERROR             0x00000002
+// Warnings.
+#define DEBUG_OUTPUT_WARNING           0x00000004
+// Additional output.
+#define DEBUG_OUTPUT_VERBOSE           0x00000008
+// Prompt output.
+#define DEBUG_OUTPUT_PROMPT            0x00000010
+// Register dump before prompt.
+#define DEBUG_OUTPUT_PROMPT_REGISTERS  0x00000020
+// Warnings specific to extension operation.
+#define DEBUG_OUTPUT_EXTENSION_WARNING 0x00000040
+// Debuggee debug output, such as from OutputDebugString.
+#define DEBUG_OUTPUT_DEBUGGEE          0x00000080
+// Debuggee-generated prompt, such as from DbgPrompt.
+#define DEBUG_OUTPUT_DEBUGGEE_PROMPT   0x00000100
+// Symbol messages, such as for !sym noisy.
+#define DEBUG_OUTPUT_SYMBOLS           0x00000200
+
+#define DEBUG_OUTCTL_DML               0x00000020
+#define DEBUG_OUTCTL_AMBIENT_DML       0xfffffffe
+
+// Execute and ExecuteCommandFile flags.
+// These flags only apply to the command
+// text itself; output from the executed
+// command is controlled by the output
+// control parameter.
+// Default execution.  Command is logged
+// but not output.
+#define DEBUG_EXECUTE_DEFAULT    0x00000000
+// Echo commands during execution.  In
+// ExecuteCommandFile also echoes the prompt
+// for each line of the file.
+#define DEBUG_EXECUTE_ECHO       0x00000001
+// Do not log or output commands during execution.
+// Overridden by DEBUG_EXECUTE_ECHO.
+#define DEBUG_EXECUTE_NOT_LOGGED 0x00000002
+// If this flag is not set an empty string
+// to Execute will repeat the last Execute
+// string.
+#define DEBUG_EXECUTE_NO_REPEAT  0x00000004
+
+// Classes of debuggee.  Each class
+// has different qualifiers for specific
+// kinds of debuggees.
+#define DEBUG_CLASS_UNINITIALIZED 0
+#define DEBUG_CLASS_KERNEL        1
+#define DEBUG_CLASS_USER_WINDOWS  2
+#define DEBUG_CLASS_IMAGE_FILE    3
+
+// Generic dump types.  These can be used
+// with either user or kernel sessions.
+// Session-type-specific aliases are also
+// provided.
+#define DEBUG_DUMP_SMALL      1024
+#define DEBUG_DUMP_DEFAULT    1025
+#define DEBUG_DUMP_FULL       1026
+#define DEBUG_DUMP_IMAGE_FILE 1027
+#define DEBUG_DUMP_TRACE_LOG  1028
+#define DEBUG_DUMP_WINDOWS_CE 1029
+
+#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.
+#define IMAGE_FILE_MACHINE_ARMNT             0x01c4  // ARM Thumb-2 Little-Endian
+#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
+#define IMAGE_FILE_MACHINE_ARM64             0xAA64  // ARM64 Little-Endian
+
+// Execution status codes used for waiting,
+// for returning current status and for
+// event method return values.
+#define DEBUG_STATUS_NO_CHANGE           0
+#define DEBUG_STATUS_GO                  1
+#define DEBUG_STATUS_GO_HANDLED          2
+#define DEBUG_STATUS_GO_NOT_HANDLED      3
+#define DEBUG_STATUS_STEP_OVER           4
+#define DEBUG_STATUS_STEP_INTO           5
+#define DEBUG_STATUS_BREAK               6
+#define DEBUG_STATUS_NO_DEBUGGEE         7
+#define DEBUG_STATUS_STEP_BRANCH         8
+#define DEBUG_STATUS_IGNORE_EVENT        9
+#define DEBUG_STATUS_RESTART_REQUESTED   10
+#define DEBUG_STATUS_REVERSE_GO          11
+#define DEBUG_STATUS_REVERSE_STEP_BRANCH 12
+#define DEBUG_STATUS_REVERSE_STEP_OVER   13
+#define DEBUG_STATUS_REVERSE_STEP_INTO   14
+#define DEBUG_STATUS_OUT_OF_SYNC         15
+#define DEBUG_STATUS_WAIT_INPUT          16
+#define DEBUG_STATUS_TIMEOUT             17
+
+#define DEBUG_STATUS_MASK                0x1f
+
+#define DEBUG_EVENT_EXCEPTION            0x00000002
+
+typedef struct _DEBUG_LAST_EVENT_INFO_EXCEPTION
+{
+    EXCEPTION_RECORD64 ExceptionRecord;
+    ULONG FirstChance;
+} DEBUG_LAST_EVENT_INFO_EXCEPTION, *PDEBUG_LAST_EVENT_INFO_EXCEPTION;
+
+//
+// Information about a module.
+//
+
+// Flags.
+#define DEBUG_MODULE_LOADED            0x00000000
+#define DEBUG_MODULE_UNLOADED          0x00000001
+#define DEBUG_MODULE_USER_MODE         0x00000002
+#define DEBUG_MODULE_EXPLICIT          0x00000008
+#define DEBUG_MODULE_SECONDARY         0x00000010
+#define DEBUG_MODULE_SYNTHETIC         0x00000020
+#define DEBUG_MODULE_SYM_BAD_CHECKSUM  0x00010000
+
+// Symbol types.
+#define DEBUG_SYMTYPE_NONE     0
+#define DEBUG_SYMTYPE_COFF     1
+#define DEBUG_SYMTYPE_CODEVIEW 2
+#define DEBUG_SYMTYPE_PDB      3
+#define DEBUG_SYMTYPE_EXPORT   4
+#define DEBUG_SYMTYPE_DEFERRED 5
+#define DEBUG_SYMTYPE_SYM      6
+#define DEBUG_SYMTYPE_DIA      7
+
+typedef struct _DEBUG_MODULE_PARAMETERS
+{
+    ULONG64 Base;
+    ULONG Size;
+    ULONG TimeDateStamp;
+    ULONG Checksum;
+    ULONG Flags;
+    ULONG SymbolType;
+    ULONG ImageNameSize;
+    ULONG ModuleNameSize;
+    ULONG LoadedImageNameSize;
+    ULONG SymbolFileNameSize;
+    ULONG MappedImageNameSize;
+    ULONG64 Reserved[2];
+} DEBUG_MODULE_PARAMETERS, *PDEBUG_MODULE_PARAMETERS;
+
+// FindSourceFile flags.
+#define DEBUG_FIND_SOURCE_DEFAULT      0x00000000
+// Returns fully-qualified paths only.  If this
+// is not set the path returned may be relative.
+#define DEBUG_FIND_SOURCE_FULL_PATH    0x00000001
+// Scans all the path elements for a match and
+// returns the one that has the most similarity
+// between the given file and the matching element.
+#define DEBUG_FIND_SOURCE_BEST_MATCH   0x00000002
+// Do not search source server paths.
+#define DEBUG_FIND_SOURCE_NO_SRCSRV    0x00000004
+// Restrict FindSourceFileAndToken to token lookup only.
+#define DEBUG_FIND_SOURCE_TOKEN_LOOKUP 0x00000008
+
+// A special value marking an offset that should not
+// be treated as a valid offset.  This is only used
+// in special situations where it is unlikely that
+// this value would be a valid offset.
+#define DEBUG_INVALID_OFFSET ((ULONG64)-1)
+
+// General unspecified ID constant.
+#define DEBUG_ANY_ID 0xffffffff
+
+typedef struct _DEBUG_STACK_FRAME
+{
+    ULONG64 InstructionOffset;
+    ULONG64 ReturnOffset;
+    ULONG64 FrameOffset;
+    ULONG64 StackOffset;
+    ULONG64 FuncTableEntry;
+    ULONG64 Params[4];
+    ULONG64 Reserved[6];
+    BOOL    Virtual;
+    ULONG   FrameNumber;
+} DEBUG_STACK_FRAME, *PDEBUG_STACK_FRAME;
+
+#define DBG_FRAME_DEFAULT                0 // the same as INLINE_FRAME_CONTEXT_INIT in dbghelp.h
+#define DBG_FRAME_IGNORE_INLINE 0xFFFFFFFF // the same as INLINE_FRAME_CONTEXT_IGNORE in dbghelp.h
+
+typedef struct _DEBUG_STACK_FRAME_EX
+{
+    // First DEBUG_STACK_FRAME structure
+    ULONG64 InstructionOffset;
+    ULONG64 ReturnOffset;
+    ULONG64 FrameOffset;
+    ULONG64 StackOffset;
+    ULONG64 FuncTableEntry;
+    ULONG64 Params[4];
+    ULONG64 Reserved[6];
+    BOOL    Virtual;
+    ULONG   FrameNumber;
+
+    // Extended DEBUG_STACK_FRAME fields.
+    ULONG InlineFrameContext;
+    ULONG Reserved1; // For alignment purpose.
+} DEBUG_STACK_FRAME_EX, *PDEBUG_STACK_FRAME_EX;
+
+// The types of inline frame context.
+#define STACK_FRAME_TYPE_INIT   0x00
+#define STACK_FRAME_TYPE_STACK  0x01
+#define STACK_FRAME_TYPE_INLINE 0x02
+#define STACK_FRAME_TYPE_RA     0x80 // Whether the instruction pointer is the current IP or a RA from callee frame.
+#define STACK_FRAME_TYPE_IGNORE 0xFF
+
+//
+// options that are set/returned by SymSetOptions() & SymGetOptions()
+// these are used as a mask
+//
+#define SYMOPT_LOAD_LINES                0x00000010
+
+interface ILLDBServices;
+typedef HRESULT (*PFN_EXCEPTION_CALLBACK)(ILLDBServices *services);
+typedef HRESULT (*PFN_RUNTIME_LOADED_CALLBACK)(ILLDBServices *services);
+
+//----------------------------------------------------------------------------
+// ILLDBServices
+//----------------------------------------------------------------------------
+
+MIDL_INTERFACE("2E6C569A-9E14-4DA4-9DFC-CDB73A532566")
+ILLDBServices : public IUnknown
+{
+public:
+    //----------------------------------------------------------------------------
+    // ILLDBServices
+    //----------------------------------------------------------------------------
+
+    // Returns the coreclr module directory found by lldb plugin 
+    // in the target process.
+    virtual PCSTR STDMETHODCALLTYPE GetCoreClrDirectory() = 0;
+
+    // Evaluates a lldb expression into a value.
+    virtual ULONG64 STDMETHODCALLTYPE GetExpression(
+        /* [in] */ PCSTR exp) = 0;
+
+    // Unwind one native stack frame given a thread and register context
+    virtual HRESULT STDMETHODCALLTYPE VirtualUnwind(
+        /* [in] */ DWORD threadID,
+        /* [in] */ ULONG32 contextSize,
+        /* [in, out, size_is(contextSize)] */ PBYTE context) = 0;
+
+    // Set an exception throw callback
+    virtual HRESULT STDMETHODCALLTYPE SetExceptionCallback(
+        /* [in] */ PFN_EXCEPTION_CALLBACK callback) = 0;
+
+    // Clear the exception throw callback
+    virtual HRESULT STDMETHODCALLTYPE ClearExceptionCallback() = 0;
+
+    //------------------------------------------------
+    // IDebugControl2
+    //------------------------------------------------
+
+    // Checks for a user interrupt, such a Ctrl-C
+    // or stop button.
+    // This method is reentrant.
+    virtual HRESULT STDMETHODCALLTYPE GetInterrupt(
+        void) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE OutputVaList(
+        ULONG mask,
+        PCSTR format,
+        va_list args) = 0;
+
+    // Returns information about the debuggee such
+    // as user vs. kernel, dump vs. live, etc.
+    virtual HRESULT STDMETHODCALLTYPE GetDebuggeeType(
+        PULONG debugClass,
+        PULONG qualifier) = 0;
+
+    // Returns the page size for the currently executing
+    // processor context.  The page size may vary between
+    // processor types.
+    virtual HRESULT STDMETHODCALLTYPE GetPageSize(
+        PULONG size) = 0;
+
+    // Returns the type of processor used in the
+    // current processor context.
+    virtual HRESULT STDMETHODCALLTYPE GetExecutingProcessorType(
+        PULONG type) = 0;
+
+    // Executes the given command string.
+    // If the string has multiple commands
+    // Execute will not return until all
+    // of them have been executed.  If this
+    // requires waiting for the debuggee to
+    // execute an internal wait will be done
+    // so Execute can take an arbitrary amount
+    // of time.
+    virtual HRESULT STDMETHODCALLTYPE Execute(
+        ULONG outputControl,
+        PCSTR command,
+        ULONG flags) = 0;
+
+    // Retrieves information about the last event that occurred.
+    // EventType is one of the event callback mask bits.
+    // ExtraInformation contains additional event-specific
+    // information.  Not all events have additional information.
+    virtual HRESULT STDMETHODCALLTYPE GetLastEventInformation(
+        PULONG type,
+        PULONG processId,
+        PULONG threadId,
+        PVOID extraInformation,
+        ULONG extraInformationSize,
+        PULONG extraInformationUsed,
+        PSTR description,
+        ULONG descriptionSize,
+        PULONG descriptionUsed) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE Disassemble(
+        ULONG64 offset,
+        ULONG flags,
+        PSTR buffer,
+        ULONG bufferSize,
+        PULONG disassemblySize,
+        PULONG64 endOffset) = 0;
+
+    //----------------------------------------------------------------------------
+    // IDebugControl4
+    //----------------------------------------------------------------------------
+
+    // Stack tracing with a full initial context
+    // and full context return for each frame.
+    // The FrameContextsSize parameter is the total
+    // byte size of FrameContexts.  FrameContextsEntrySize
+    // gives the byte size of each entry in
+    // FrameContexts.
+    virtual HRESULT STDMETHODCALLTYPE GetContextStackTrace(
+        PVOID startContext,
+        ULONG startContextSize,
+        PDEBUG_STACK_FRAME frames,
+        ULONG framesSize,
+        PVOID frameContexts,
+        ULONG frameContextsSize,
+        ULONG frameContextsEntrySize,
+        PULONG framesFilled) = 0;
+    
+    //------------------------------------------------
+    // IDebugDataSpaces
+    //------------------------------------------------
+
+    virtual HRESULT STDMETHODCALLTYPE ReadVirtual(
+        ULONG64 offset,
+        PVOID buffer,
+        ULONG bufferSize,
+        PULONG bytesRead) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE WriteVirtual(
+        ULONG64 offset,
+        PVOID buffer,
+        ULONG bufferSize,
+        PULONG bytesWritten) = 0;
+
+    //------------------------------------------------
+    // IDebugSymbols
+    //------------------------------------------------
+
+    // Controls the symbol options used during
+    // symbol operations.
+    // Uses the same flags as dbghelps SymSetOptions.
+    virtual HRESULT STDMETHODCALLTYPE GetSymbolOptions(
+        PULONG options) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE GetNameByOffset(
+        ULONG64 offset,
+        PSTR nameBuffer,
+        ULONG nameBufferSize,
+        PULONG nameSize,
+        PULONG64 displacement) = 0;
+
+    // Enumerates the engines list of modules
+    // loaded for the current process.  This may
+    // or may not match the system module list
+    // for the process.  Reload can be used to
+    // synchronize the engines list with the system
+    // if necessary.
+    // Some sessions also track recently unloaded
+    // code modules for help in analyzing failures
+    // where an attempt is made to call unloaded code.
+    // These modules are indexed after the loaded
+    // modules.
+    virtual HRESULT STDMETHODCALLTYPE GetNumberModules(
+        PULONG loaded,
+        PULONG unloaded) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE GetModuleByIndex(
+        ULONG index,
+        PULONG64 base) = 0;
+
+    // The module name may not be unique.
+    // This method returns the first match.
+    virtual HRESULT STDMETHODCALLTYPE GetModuleByModuleName(
+        PCSTR name,
+        ULONG startIndex,
+        PULONG index,
+        PULONG64 base) = 0;
+
+    // Offset can be any offset within
+    // the module extent.  Extents may
+    // not be unique when including unloaded
+    // drivers.  This method returns the
+    // first match.
+    virtual HRESULT STDMETHODCALLTYPE GetModuleByOffset(
+        ULONG64 offset,
+        ULONG startIndex,
+        PULONG index,
+        PULONG64 base) = 0;
+
+    // If Index is DEBUG_ANY_ID the base address
+    // is used to look up the module instead.
+    virtual HRESULT STDMETHODCALLTYPE GetModuleNames(
+        ULONG index,
+        ULONG64 base,
+        PSTR imageNameBuffer,
+        ULONG imageNameBufferSize,
+        PULONG imageNameSize,
+        PSTR moduleNameBuffer,
+        ULONG moduleNameBufferSize,
+        PULONG moduleNameSize,
+        PSTR loadedImageNameBuffer,
+        ULONG loadedImageNameBufferSize,
+        PULONG loadedImageNameSize) = 0;
+
+    HRESULT virtual STDMETHODCALLTYPE GetLineByOffset(
+        ULONG64 offset,
+        PULONG line,
+        PSTR fileBuffer,
+        ULONG fileBufferSize,
+        PULONG fileSize,
+        PULONG64 displacement) = 0;
+     
+    HRESULT virtual STDMETHODCALLTYPE GetSourceFileLineOffsets(
+        PCSTR file,
+        PULONG64 buffer,
+        ULONG bufferLines,
+        PULONG fileLines) = 0;
+
+    // Uses the given file path and the source path
+    // information to try and locate an existing file.
+    // The given file path is merged with elements
+    // of the source path and checked for existence.
+    // If a match is found the element used is returned.
+    // A starting element can be specified to restrict
+    // the search to a subset of the path elements;
+    // this can be useful when checking for multiple
+    // matches along the source path.
+    // The returned element can be 1, indicating
+    // the file was found directly and not on the path.
+    HRESULT virtual STDMETHODCALLTYPE FindSourceFile(
+        ULONG startElement,
+        PCSTR file,
+        ULONG flags,
+        PULONG foundElement,
+        PSTR buffer,
+        ULONG bufferSize,
+        PULONG foundSize) = 0;
+    
+    //------------------------------------------------
+    // IDebugSystemObjects
+    //------------------------------------------------
+
+    virtual HRESULT STDMETHODCALLTYPE GetCurrentProcessSystemId(
+        PULONG id) = 0;
+
+    // Controls implicit thread used by the
+    // debug engine.  The debuggers current
+    // thread is just a piece of data held
+    // by the debugger for calls which use
+    // thread-specific information.  In those
+    // calls the debuggers current thread is used.
+    // The debuggers current thread is not related
+    // to any system thread attribute.
+    // IDs for threads are small integer IDs
+    // maintained by the engine.  They are not
+    // related to system thread IDs.
+    virtual HRESULT STDMETHODCALLTYPE GetCurrentThreadId(
+        PULONG id) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE SetCurrentThreadId(
+        ULONG id) = 0;
+
+    // Returns the system unique ID for the current thread.
+    // Not currently supported when kernel debugging.
+    virtual HRESULT STDMETHODCALLTYPE GetCurrentThreadSystemId(
+        PULONG sysId) = 0;
+
+    // Looks up a debugger thread ID for the given
+    // system thread ID.
+    // Currently when kernel debugging this will fail
+    // if the thread is not executing on a processor.
+    virtual HRESULT STDMETHODCALLTYPE GetThreadIdBySystemId(
+        ULONG sysId,
+        PULONG id) = 0;
+
+    // This is a special sos/lldb function used to implement the ICLRDataTarget interface and
+    // not actually part of dbgeng's IDebugSystemObjects interface.
+    virtual HRESULT STDMETHODCALLTYPE GetThreadContextBySystemId(
+        /* [in] */ ULONG32 sysId,
+        /* [in] */ ULONG32 contextFlags,
+        /* [in] */ ULONG32 contextSize,
+        /* [out, size_is(contextSize)] */ PBYTE context) = 0;
+
+    //------------------------------------------------
+    // IDebugRegister
+    //------------------------------------------------
+
+    // This is the combination of dbgeng's GetIndexByName and GetValue and not
+    // actually part of the dbgeng's IDebugRegister interface.
+    virtual HRESULT STDMETHODCALLTYPE GetValueByName(
+        PCSTR name,
+        PDWORD_PTR value) = 0;
+
+    // Abstracted pieces of processor information.
+    // The mapping of these values to architectural
+    // registers is architecture-specific and their
+    // interpretation and existence may vary.  They
+    // are intended to be directly compatible with
+    // calls which take this information, such as
+    // stack walking.
+    virtual HRESULT STDMETHODCALLTYPE GetInstructionOffset(
+        PULONG64 offset) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE GetStackOffset(
+        PULONG64 offset) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE GetFrameOffset(
+        PULONG64 offset) = 0;
+};
+
+typedef void (*PFN_MODULE_LOAD_CALLBACK)(void* param, const char* moduleFilePath, ULONG64 moduleAddress, int moduleSize);
+
+MIDL_INTERFACE("012F32F0-33BA-4E8E-BC01-037D382D8A5E")
+ILLDBServices2: public IUnknown
+{
+public:
+    //----------------------------------------------------------------------------
+    // ILLDBServices2
+    //----------------------------------------------------------------------------
+
+    virtual HRESULT STDMETHODCALLTYPE LoadNativeSymbols(
+        bool runtimeOnly,
+        PFN_MODULE_LOAD_CALLBACK callback) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE AddModuleSymbol(
+        void* param, 
+        const char* symbolFilePath) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE GetModuleInfo(
+        ULONG index,
+        PULONG64 moduleBase,
+        PULONG64 moduleSize,
+        PULONG timestamp,
+        PULONG checksum) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE GetModuleVersionInformation(
+        ULONG index,
+        ULONG64 base,
+        PCSTR item,
+        PVOID buffer,
+        ULONG bufferSize,
+        PULONG versionInfoSize) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE SetRuntimeLoadedCallback(
+        PFN_RUNTIME_LOADED_CALLBACK callback) = 0;
+};
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/src/SOS/inc/runtime.h b/src/SOS/inc/runtime.h
new file mode 100644 (file)
index 0000000..009b712
--- /dev/null
@@ -0,0 +1,84 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#pragma once
+
+#include <stdarg.h>
+#include <unknwn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// <summary>
+/// IRuntime - the native interface 
+/// </summary>
+MIDL_INTERFACE("A5F152B9-BA78-4512-9228-5091A4CB7E35")
+IRuntime : public IUnknown
+{
+public:
+    /// <summary>
+    /// The runtime OS and type. Must match RuntimeWrapper.RuntimeConfiguration.
+    /// </summary>
+    enum RuntimeConfiguration
+    {
+        WindowsDesktop      = 0,
+        WindowsCore         = 1,
+        UnixCore            = 2,
+        OSXCore             = 3,
+        ConfigurationEnd,
+#ifdef FEATURE_PAL
+#ifdef __APPLE__
+        Core = OSXCore
+#else
+        Core = UnixCore
+#endif
+#else
+        Core = WindowsCore
+#endif
+    };
+
+    /// <summary>
+    /// Returns the runtime configuration 
+    /// </summary>
+    virtual RuntimeConfiguration STDMETHODCALLTYPE GetRuntimeConfiguration() const = 0;
+
+    /// <summary>
+    /// Returns the runtime module base address 
+    /// </summary>
+    virtual ULONG64 STDMETHODCALLTYPE GetModuleAddress() const = 0;
+
+    /// <summary>
+    /// Returns the runtime module size 
+    /// </summary>
+    virtual ULONG64 STDMETHODCALLTYPE GetModuleSize() const = 0;
+
+    /// <summary>
+    /// Returns the directory of the runtime file
+    /// </summary>
+    virtual LPCSTR STDMETHODCALLTYPE GetRuntimeDirectory() = 0;
+
+    /// <summary>
+    /// Returns the DAC data process instance
+    /// </summary>
+    virtual HRESULT STDMETHODCALLTYPE GetClrDataProcess(IXCLRDataProcess** ppClrDataProcess) = 0;
+
+    /// <summary>
+    /// Initializes and returns the DBI debugging interface instance 
+    /// </summary>
+    virtual HRESULT STDMETHODCALLTYPE GetCorDebugInterface(ICorDebugProcess** ppCorDebugProcess) = 0;
+
+    /// <summary>
+    /// Gets version info for the CLR in the debuggee process. 
+    /// </summary>
+    /// <param name="pFileInfo">the file version fields are filled with the runtime module's version</param>
+    /// <param name="fileVersionBuffer">buffer to return the full file version string with commit id, etc. or null</param>
+    /// <param name="fileVersionBufferSizeInBytes">size of fileVersionBuffer</param>
+    /// <returns></returns>
+    virtual HRESULT STDMETHODCALLTYPE GetEEVersion(VS_FIXEDFILEINFO* pFileInfo, char* fileVersionBuffer, int fileVersionBufferSizeInBytes) = 0;
+};
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/src/SOS/inc/target.h b/src/SOS/inc/target.h
new file mode 100644 (file)
index 0000000..1cf51e5
--- /dev/null
@@ -0,0 +1,72 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#pragma once
+
+#include <stdarg.h>
+#include <unknwn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct IRuntime;
+
+/// <summary>
+/// ITarget - the native target interface
+/// </summary>
+MIDL_INTERFACE("B4640016-6CA0-468E-BA2C-1FFF28DE7B72")
+ITarget : public IUnknown
+{
+public:
+    /// <summary>
+    /// Target OS values. Must match TargetWrapper.OperatingSystem
+    /// </summary>
+    enum OperatingSystem
+    {
+        Unknown         = 0,
+        Windows         = 1,
+        Linux           = 2,
+        OSX             = 3,
+    };
+
+    /// <summary>
+    /// Returns the OperatingSystem for the target
+    /// </summary>
+    /// <returns>target operating system</returns>
+    virtual OperatingSystem STDMETHODCALLTYPE GetOperatingSystem() = 0;
+
+    /// <summary>
+    /// Returns the unique temporary directory for this instance of SOS
+    /// </summary>
+    /// <returns>temporary directory string</returns>
+    virtual LPCSTR STDMETHODCALLTYPE GetTempDirectory() = 0;
+
+    /// <summary>
+    /// Returns the directory of the runtime file
+    /// </summary>
+    /// <returns>runtime directory or null if none set</returns>
+    virtual LPCSTR STDMETHODCALLTYPE GetRuntimeDirectory() = 0;
+
+    /// <summary>
+    /// Returns the current runtime instance
+    /// </summary>
+    /// <param name="ppRuntime">pointer to return IRuntime instance</param>
+    /// <returns>error code</returns>
+    virtual HRESULT STDMETHODCALLTYPE GetRuntime(IRuntime** ppRuntime) = 0;
+
+    /// <summary>
+    /// Flushes any internal caching or state 
+    /// </summary>
+    virtual void STDMETHODCALLTYPE Flush() = 0;
+
+    /// <summary>
+    /// Cleans up any internal resources 
+    /// </summary>
+    virtual void STDMETHODCALLTYPE Close() = 0;
+};
+
+#ifdef __cplusplus
+};
+#endif
index af15c9612704fd7d0a972589cbe5207042f72ba4..79c0ea1fb1cd4321e03cd56aa9ba68b115e3cc38 100644 (file)
@@ -130,7 +130,8 @@ message(STATUS "LLDB_H: ${LLDB_H}")
 
 add_compile_options(-Wno-delete-non-virtual-dtor)
 
-include_directories(inc)
+include_directories(${ROOT_DIR}/src/SOS/inc)
+
 include_directories("${LLDB_H}")
 
 set(SOURCES
diff --git a/src/SOS/lldbplugin/inc/lldbservices.h b/src/SOS/lldbplugin/inc/lldbservices.h
deleted file mode 100644 (file)
index d96aaa8..0000000
+++ /dev/null
@@ -1,588 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//----------------------------------------------------------------------------
-//
-// LLDB debugger services for sos
-//
-//----------------------------------------------------------------------------
-
-#ifndef __LLDBSERVICES_H__
-#define __LLDBSERVICES_H__
-
-#include <stdarg.h>
-#include <palrt.h>
-#include <unknwn.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Output mask bits.
-// Normal output.
-#define DEBUG_OUTPUT_NORMAL            0x00000001
-// Error output.
-#define DEBUG_OUTPUT_ERROR             0x00000002
-// Warnings.
-#define DEBUG_OUTPUT_WARNING           0x00000004
-// Additional output.
-#define DEBUG_OUTPUT_VERBOSE           0x00000008
-// Prompt output.
-#define DEBUG_OUTPUT_PROMPT            0x00000010
-// Register dump before prompt.
-#define DEBUG_OUTPUT_PROMPT_REGISTERS  0x00000020
-// Warnings specific to extension operation.
-#define DEBUG_OUTPUT_EXTENSION_WARNING 0x00000040
-// Debuggee debug output, such as from OutputDebugString.
-#define DEBUG_OUTPUT_DEBUGGEE          0x00000080
-// Debuggee-generated prompt, such as from DbgPrompt.
-#define DEBUG_OUTPUT_DEBUGGEE_PROMPT   0x00000100
-// Symbol messages, such as for !sym noisy.
-#define DEBUG_OUTPUT_SYMBOLS           0x00000200
-
-#define DEBUG_OUTCTL_DML               0x00000020
-#define DEBUG_OUTCTL_AMBIENT_DML       0xfffffffe
-
-// Execute and ExecuteCommandFile flags.
-// These flags only apply to the command
-// text itself; output from the executed
-// command is controlled by the output
-// control parameter.
-// Default execution.  Command is logged
-// but not output.
-#define DEBUG_EXECUTE_DEFAULT    0x00000000
-// Echo commands during execution.  In
-// ExecuteCommandFile also echoes the prompt
-// for each line of the file.
-#define DEBUG_EXECUTE_ECHO       0x00000001
-// Do not log or output commands during execution.
-// Overridden by DEBUG_EXECUTE_ECHO.
-#define DEBUG_EXECUTE_NOT_LOGGED 0x00000002
-// If this flag is not set an empty string
-// to Execute will repeat the last Execute
-// string.
-#define DEBUG_EXECUTE_NO_REPEAT  0x00000004
-
-// Classes of debuggee.  Each class
-// has different qualifiers for specific
-// kinds of debuggees.
-#define DEBUG_CLASS_UNINITIALIZED 0
-#define DEBUG_CLASS_KERNEL        1
-#define DEBUG_CLASS_USER_WINDOWS  2
-#define DEBUG_CLASS_IMAGE_FILE    3
-
-// Generic dump types.  These can be used
-// with either user or kernel sessions.
-// Session-type-specific aliases are also
-// provided.
-#define DEBUG_DUMP_SMALL      1024
-#define DEBUG_DUMP_DEFAULT    1025
-#define DEBUG_DUMP_FULL       1026
-#define DEBUG_DUMP_IMAGE_FILE 1027
-#define DEBUG_DUMP_TRACE_LOG  1028
-#define DEBUG_DUMP_WINDOWS_CE 1029
-
-#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.
-#define IMAGE_FILE_MACHINE_ARMNT             0x01c4  // ARM Thumb-2 Little-Endian
-#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
-#define IMAGE_FILE_MACHINE_ARM64             0xAA64  // ARM64 Little-Endian
-
-// Execution status codes used for waiting,
-// for returning current status and for
-// event method return values.
-#define DEBUG_STATUS_NO_CHANGE           0
-#define DEBUG_STATUS_GO                  1
-#define DEBUG_STATUS_GO_HANDLED          2
-#define DEBUG_STATUS_GO_NOT_HANDLED      3
-#define DEBUG_STATUS_STEP_OVER           4
-#define DEBUG_STATUS_STEP_INTO           5
-#define DEBUG_STATUS_BREAK               6
-#define DEBUG_STATUS_NO_DEBUGGEE         7
-#define DEBUG_STATUS_STEP_BRANCH         8
-#define DEBUG_STATUS_IGNORE_EVENT        9
-#define DEBUG_STATUS_RESTART_REQUESTED   10
-#define DEBUG_STATUS_REVERSE_GO          11
-#define DEBUG_STATUS_REVERSE_STEP_BRANCH 12
-#define DEBUG_STATUS_REVERSE_STEP_OVER   13
-#define DEBUG_STATUS_REVERSE_STEP_INTO   14
-#define DEBUG_STATUS_OUT_OF_SYNC         15
-#define DEBUG_STATUS_WAIT_INPUT          16
-#define DEBUG_STATUS_TIMEOUT             17
-
-#define DEBUG_STATUS_MASK                0x1f
-
-#define DEBUG_EVENT_EXCEPTION            0x00000002
-
-typedef struct _DEBUG_LAST_EVENT_INFO_EXCEPTION
-{
-    EXCEPTION_RECORD64 ExceptionRecord;
-    ULONG FirstChance;
-} DEBUG_LAST_EVENT_INFO_EXCEPTION, *PDEBUG_LAST_EVENT_INFO_EXCEPTION;
-
-//
-// Information about a module.
-//
-
-// Flags.
-#define DEBUG_MODULE_LOADED            0x00000000
-#define DEBUG_MODULE_UNLOADED          0x00000001
-#define DEBUG_MODULE_USER_MODE         0x00000002
-#define DEBUG_MODULE_EXPLICIT          0x00000008
-#define DEBUG_MODULE_SECONDARY         0x00000010
-#define DEBUG_MODULE_SYNTHETIC         0x00000020
-#define DEBUG_MODULE_SYM_BAD_CHECKSUM  0x00010000
-
-// Symbol types.
-#define DEBUG_SYMTYPE_NONE     0
-#define DEBUG_SYMTYPE_COFF     1
-#define DEBUG_SYMTYPE_CODEVIEW 2
-#define DEBUG_SYMTYPE_PDB      3
-#define DEBUG_SYMTYPE_EXPORT   4
-#define DEBUG_SYMTYPE_DEFERRED 5
-#define DEBUG_SYMTYPE_SYM      6
-#define DEBUG_SYMTYPE_DIA      7
-
-typedef struct _DEBUG_MODULE_PARAMETERS
-{
-    ULONG64 Base;
-    ULONG Size;
-    ULONG TimeDateStamp;
-    ULONG Checksum;
-    ULONG Flags;
-    ULONG SymbolType;
-    ULONG ImageNameSize;
-    ULONG ModuleNameSize;
-    ULONG LoadedImageNameSize;
-    ULONG SymbolFileNameSize;
-    ULONG MappedImageNameSize;
-    ULONG64 Reserved[2];
-} DEBUG_MODULE_PARAMETERS, *PDEBUG_MODULE_PARAMETERS;
-
-// FindSourceFile flags.
-#define DEBUG_FIND_SOURCE_DEFAULT      0x00000000
-// Returns fully-qualified paths only.  If this
-// is not set the path returned may be relative.
-#define DEBUG_FIND_SOURCE_FULL_PATH    0x00000001
-// Scans all the path elements for a match and
-// returns the one that has the most similarity
-// between the given file and the matching element.
-#define DEBUG_FIND_SOURCE_BEST_MATCH   0x00000002
-// Do not search source server paths.
-#define DEBUG_FIND_SOURCE_NO_SRCSRV    0x00000004
-// Restrict FindSourceFileAndToken to token lookup only.
-#define DEBUG_FIND_SOURCE_TOKEN_LOOKUP 0x00000008
-
-// A special value marking an offset that should not
-// be treated as a valid offset.  This is only used
-// in special situations where it is unlikely that
-// this value would be a valid offset.
-#define DEBUG_INVALID_OFFSET ((ULONG64)-1)
-
-// General unspecified ID constant.
-#define DEBUG_ANY_ID 0xffffffff
-
-typedef struct _DEBUG_STACK_FRAME
-{
-    ULONG64 InstructionOffset;
-    ULONG64 ReturnOffset;
-    ULONG64 FrameOffset;
-    ULONG64 StackOffset;
-    ULONG64 FuncTableEntry;
-    ULONG64 Params[4];
-    ULONG64 Reserved[6];
-    BOOL    Virtual;
-    ULONG   FrameNumber;
-} DEBUG_STACK_FRAME, *PDEBUG_STACK_FRAME;
-
-#define DBG_FRAME_DEFAULT                0 // the same as INLINE_FRAME_CONTEXT_INIT in dbghelp.h
-#define DBG_FRAME_IGNORE_INLINE 0xFFFFFFFF // the same as INLINE_FRAME_CONTEXT_IGNORE in dbghelp.h
-
-typedef struct _DEBUG_STACK_FRAME_EX
-{
-    // First DEBUG_STACK_FRAME structure
-    ULONG64 InstructionOffset;
-    ULONG64 ReturnOffset;
-    ULONG64 FrameOffset;
-    ULONG64 StackOffset;
-    ULONG64 FuncTableEntry;
-    ULONG64 Params[4];
-    ULONG64 Reserved[6];
-    BOOL    Virtual;
-    ULONG   FrameNumber;
-
-    // Extended DEBUG_STACK_FRAME fields.
-    ULONG InlineFrameContext;
-    ULONG Reserved1; // For alignment purpose.
-} DEBUG_STACK_FRAME_EX, *PDEBUG_STACK_FRAME_EX;
-
-// The types of inline frame context.
-#define STACK_FRAME_TYPE_INIT   0x00
-#define STACK_FRAME_TYPE_STACK  0x01
-#define STACK_FRAME_TYPE_INLINE 0x02
-#define STACK_FRAME_TYPE_RA     0x80 // Whether the instruction pointer is the current IP or a RA from callee frame.
-#define STACK_FRAME_TYPE_IGNORE 0xFF
-
-//
-// options that are set/returned by SymSetOptions() & SymGetOptions()
-// these are used as a mask
-//
-#define SYMOPT_LOAD_LINES                0x00000010
-
-interface ILLDBServices;
-typedef HRESULT (*PFN_EXCEPTION_CALLBACK)(ILLDBServices *services);
-typedef HRESULT (*PFN_RUNTIME_LOADED_CALLBACK)(ILLDBServices *services);
-
-//----------------------------------------------------------------------------
-// ILLDBServices
-//----------------------------------------------------------------------------
-
-MIDL_INTERFACE("2E6C569A-9E14-4DA4-9DFC-CDB73A532566")
-ILLDBServices : public IUnknown
-{
-public:
-    //----------------------------------------------------------------------------
-    // ILLDBServices
-    //----------------------------------------------------------------------------
-
-    // Returns the coreclr module directory found by lldb plugin 
-    // in the target process.
-    virtual PCSTR GetCoreClrDirectory() = 0;
-
-    // Evaluates a lldb expression into a value.
-    virtual DWORD_PTR GetExpression(
-        /* [in] */ PCSTR exp) = 0;
-
-    // Unwind one native stack frame given a thread and register context
-    virtual HRESULT VirtualUnwind(
-        /* [in] */ DWORD threadID,
-        /* [in] */ ULONG32 contextSize,
-        /* [in, out, size_is(contextSize)] */ PBYTE context) = 0;
-
-    // Set an exception throw callback
-    virtual HRESULT SetExceptionCallback(
-        /* [in] */ PFN_EXCEPTION_CALLBACK callback) = 0;
-
-    // Clear the exception throw callback
-    virtual HRESULT ClearExceptionCallback() = 0;
-
-    //------------------------------------------------
-    // IDebugControl2
-    //------------------------------------------------
-
-    // Checks for a user interrupt, such a Ctrl-C
-    // or stop button.
-    // This method is reentrant.
-    virtual HRESULT GetInterrupt(
-        void) = 0;
-
-    virtual HRESULT OutputVaList(
-        ULONG mask,
-        PCSTR format,
-        va_list args) = 0;
-
-    // Returns information about the debuggee such
-    // as user vs. kernel, dump vs. live, etc.
-    virtual HRESULT GetDebuggeeType(
-        PULONG debugClass,
-        PULONG qualifier) = 0;
-
-    // Returns the page size for the currently executing
-    // processor context.  The page size may vary between
-    // processor types.
-    virtual HRESULT GetPageSize(
-        PULONG size) = 0;
-
-    // Returns the type of processor used in the
-    // current processor context.
-    virtual HRESULT GetExecutingProcessorType(
-        PULONG type) = 0;
-
-    // Executes the given command string.
-    // If the string has multiple commands
-    // Execute will not return until all
-    // of them have been executed.  If this
-    // requires waiting for the debuggee to
-    // execute an internal wait will be done
-    // so Execute can take an arbitrary amount
-    // of time.
-    virtual HRESULT Execute(
-        ULONG outputControl,
-        PCSTR command,
-        ULONG flags) = 0;
-
-    // Retrieves information about the last event that occurred.
-    // EventType is one of the event callback mask bits.
-    // ExtraInformation contains additional event-specific
-    // information.  Not all events have additional information.
-    virtual HRESULT GetLastEventInformation(
-        PULONG type,
-        PULONG processId,
-        PULONG threadId,
-        PVOID extraInformation,
-        ULONG extraInformationSize,
-        PULONG extraInformationUsed,
-        PSTR description,
-        ULONG descriptionSize,
-        PULONG descriptionUsed) = 0;
-
-    virtual HRESULT Disassemble(
-        ULONG64 offset,
-        ULONG flags,
-        PSTR buffer,
-        ULONG bufferSize,
-        PULONG disassemblySize,
-        PULONG64 endOffset) = 0;
-
-    //----------------------------------------------------------------------------
-    // IDebugControl4
-    //----------------------------------------------------------------------------
-
-    // Stack tracing with a full initial context
-    // and full context return for each frame.
-    // The FrameContextsSize parameter is the total
-    // byte size of FrameContexts.  FrameContextsEntrySize
-    // gives the byte size of each entry in
-    // FrameContexts.
-    virtual HRESULT GetContextStackTrace(
-        PVOID startContext,
-        ULONG startContextSize,
-        PDEBUG_STACK_FRAME frames,
-        ULONG framesSize,
-        PVOID frameContexts,
-        ULONG frameContextsSize,
-        ULONG frameContextsEntrySize,
-        PULONG framesFilled) = 0;
-    
-    //------------------------------------------------
-    // IDebugDataSpaces
-    //------------------------------------------------
-
-    virtual HRESULT ReadVirtual(
-        ULONG64 offset,
-        PVOID buffer,
-        ULONG bufferSize,
-        PULONG bytesRead) = 0;
-
-    virtual HRESULT WriteVirtual(
-        ULONG64 offset,
-        PVOID buffer,
-        ULONG bufferSize,
-        PULONG bytesWritten) = 0;
-
-    //------------------------------------------------
-    // IDebugSymbols
-    //------------------------------------------------
-
-    // Controls the symbol options used during
-    // symbol operations.
-    // Uses the same flags as dbghelps SymSetOptions.
-    virtual HRESULT GetSymbolOptions(
-        PULONG options) = 0;
-
-    virtual HRESULT GetNameByOffset(
-        ULONG64 offset,
-        PSTR nameBuffer,
-        ULONG nameBufferSize,
-        PULONG nameSize,
-        PULONG64 displacement) = 0;
-
-    // Enumerates the engines list of modules
-    // loaded for the current process.  This may
-    // or may not match the system module list
-    // for the process.  Reload can be used to
-    // synchronize the engines list with the system
-    // if necessary.
-    // Some sessions also track recently unloaded
-    // code modules for help in analyzing failures
-    // where an attempt is made to call unloaded code.
-    // These modules are indexed after the loaded
-    // modules.
-    virtual HRESULT GetNumberModules(
-        PULONG loaded,
-        PULONG unloaded) = 0;
-
-    virtual HRESULT GetModuleByIndex(
-        ULONG index,
-        PULONG64 base) = 0;
-
-    // The module name may not be unique.
-    // This method returns the first match.
-    virtual HRESULT GetModuleByModuleName(
-        PCSTR name,
-        ULONG startIndex,
-        PULONG index,
-        PULONG64 base) = 0;
-
-    // Offset can be any offset within
-    // the module extent.  Extents may
-    // not be unique when including unloaded
-    // drivers.  This method returns the
-    // first match.
-    virtual HRESULT GetModuleByOffset(
-        ULONG64 offset,
-        ULONG startIndex,
-        PULONG index,
-        PULONG64 base) = 0;
-
-    // If Index is DEBUG_ANY_ID the base address
-    // is used to look up the module instead.
-    virtual HRESULT GetModuleNames(
-        ULONG index,
-        ULONG64 base,
-        PSTR imageNameBuffer,
-        ULONG imageNameBufferSize,
-        PULONG imageNameSize,
-        PSTR moduleNameBuffer,
-        ULONG moduleNameBufferSize,
-        PULONG moduleNameSize,
-        PSTR loadedImageNameBuffer,
-        ULONG loadedImageNameBufferSize,
-        PULONG loadedImageNameSize) = 0;
-
-    HRESULT virtual GetLineByOffset(
-        ULONG64 offset,
-        PULONG line,
-        PSTR fileBuffer,
-        ULONG fileBufferSize,
-        PULONG fileSize,
-        PULONG64 displacement) = 0;
-     
-    HRESULT virtual GetSourceFileLineOffsets(
-        PCSTR file,
-        PULONG64 buffer,
-        ULONG bufferLines,
-        PULONG fileLines) = 0;
-
-    // Uses the given file path and the source path
-    // information to try and locate an existing file.
-    // The given file path is merged with elements
-    // of the source path and checked for existence.
-    // If a match is found the element used is returned.
-    // A starting element can be specified to restrict
-    // the search to a subset of the path elements;
-    // this can be useful when checking for multiple
-    // matches along the source path.
-    // The returned element can be 1, indicating
-    // the file was found directly and not on the path.
-    HRESULT virtual FindSourceFile(
-        ULONG startElement,
-        PCSTR file,
-        ULONG flags,
-        PULONG foundElement,
-        PSTR buffer,
-        ULONG bufferSize,
-        PULONG foundSize) = 0;
-    
-    //------------------------------------------------
-    // IDebugSystemObjects
-    //------------------------------------------------
-
-    virtual HRESULT GetCurrentProcessId(
-        PULONG id) = 0;
-
-    // Controls implicit thread used by the
-    // debug engine.  The debuggers current
-    // thread is just a piece of data held
-    // by the debugger for calls which use
-    // thread-specific information.  In those
-    // calls the debuggers current thread is used.
-    // The debuggers current thread is not related
-    // to any system thread attribute.
-    // IDs for threads are small integer IDs
-    // maintained by the engine.  They are not
-    // related to system thread IDs.
-    virtual HRESULT GetCurrentThreadId(
-        PULONG id) = 0;
-
-    virtual HRESULT SetCurrentThreadId(
-        ULONG id) = 0;
-
-    // Returns the system unique ID for the current thread.
-    // Not currently supported when kernel debugging.
-    virtual HRESULT GetCurrentThreadSystemId(
-        PULONG sysId) = 0;
-
-    // Looks up a debugger thread ID for the given
-    // system thread ID.
-    // Currently when kernel debugging this will fail
-    // if the thread is not executing on a processor.
-    virtual HRESULT GetThreadIdBySystemId(
-        ULONG sysId,
-        PULONG id) = 0;
-
-    // This is a special sos/lldb function used to implement the ICLRDataTarget interface and
-    // not actually part of dbgeng's IDebugSystemObjects interface.
-    virtual HRESULT GetThreadContextById(
-        /* [in] */ ULONG32 threadID,
-        /* [in] */ ULONG32 contextFlags,
-        /* [in] */ ULONG32 contextSize,
-        /* [out, size_is(contextSize)] */ PBYTE context) = 0;
-
-    //------------------------------------------------
-    // IDebugRegister
-    //------------------------------------------------
-
-    // This is the combination of dbgeng's GetIndexByName and GetValue and not
-    // actually part of the dbgeng's IDebugRegister interface.
-    virtual HRESULT GetValueByName(
-        PCSTR name,
-        PDWORD_PTR value) = 0;
-
-    // Abstracted pieces of processor information.
-    // The mapping of these values to architectural
-    // registers is architecture-specific and their
-    // interpretation and existence may vary.  They
-    // are intended to be directly compatible with
-    // calls which take this information, such as
-    // stack walking.
-    virtual HRESULT GetInstructionOffset(
-        PULONG64 offset) = 0;
-
-    virtual HRESULT GetStackOffset(
-        PULONG64 offset) = 0;
-
-    virtual HRESULT GetFrameOffset(
-        PULONG64 offset) = 0;
-};
-
-typedef void (*PFN_MODULE_LOAD_CALLBACK)(void* param, const char* moduleFilePath, ULONG64 moduleAddress, int moduleSize);
-
-MIDL_INTERFACE("012F32F0-33BA-4E8E-BC01-037D382D8A5E")
-ILLDBServices2: public IUnknown
-{
-public:
-    //----------------------------------------------------------------------------
-    // ILLDBServices2
-    //----------------------------------------------------------------------------
-
-    virtual HRESULT LoadNativeSymbols(
-        bool runtimeOnly,
-        PFN_MODULE_LOAD_CALLBACK callback) = 0;
-
-    virtual HRESULT AddModuleSymbol(
-        void* param, 
-        const char* symbolFilePath) = 0;
-
-    virtual HRESULT GetModuleInfo(
-        ULONG index,
-        PULONG64 base,
-        PULONG64 size) = 0;
-
-    virtual HRESULT GetModuleVersionInformation(
-        ULONG index,
-        ULONG64 base,
-        PCSTR item,
-        PVOID buffer,
-        ULONG bufferSize,
-        PULONG versionInfoSize) = 0;
-
-    virtual HRESULT SetRuntimeLoadedCallback(
-        PFN_RUNTIME_LOADED_CALLBACK callback) = 0;
-};
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // #ifndef __LLDBSERVICES_H__
index c9a75821d837645364531d3c4139681b0f3aee2a..aec305122daf461d0cdcf3d36437672cd035a27c 100644 (file)
@@ -54,6 +54,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <OutDir>$(ArtifactsBinDir)Linux.$(Platform).$(Configuration)\</OutDir>
     <IntDir>$(ArtifactsObjDir)Linux.$(Platform).$(Configuration)\</IntDir>
+    <IncludePath>$(SolutionDir)src\SOS\lldbplugin;$(SolutionDir)src\SOS\inc;$(SolutionDir)src\SOS\lldbplugin\swift-4.0;$(SolutionDir)src\pal\prebuilt\inc;$(SolutionDir)src\inc;$(SolutionDir)src\pal\inc;$(SolutionDir)src\pal\inc\rt;$(IncludePath)</IncludePath>
   </PropertyGroup>
   <ItemGroup>
     <ClCompile Include="services.cpp" />
@@ -63,7 +64,6 @@
     <ClCompile Include="sosplugin.cpp" />
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="inc\lldbservices.h" />
     <ClInclude Include="mstypes.h" />
     <ClInclude Include="services.h" />
     <ClInclude Include="sosplugin.h" />
     <ClInclude Include="swift-4.0\lldb\Utility\Timeout.h" />
     <ClInclude Include="swift-4.0\lldb\Utility\Utils.h" />
   </ItemGroup>
+  <ItemGroup>
+    <Text Include="CMakeLists.txt" />
+  </ItemGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)src\pal\prebuilt\inc;$(SolutionDir)src\inc;$(SolutionDir)src\pal\inc;$(SolutionDir)src\pal\inc\rt;$(SolutionDir)src\SOS\lldbplugin\inc;$(SolutionDir)src\SOS\lldbplugin\swift-4.0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)src\pal\inc;$(SolutionDir)src\pal\inc\rt;$(SolutionDir)src\pal\inc\rt\cpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_AMD64_;_WIN64;AMD64;_TARGET_64BIT_=1;_TARGET_AMD64_=1;DBG_TARGET_64BIT=1;DBG_TARGET_AMD64=1;DBG_TARGET_WIN64=1;DBG_TARGET_AMD64_UNIX;BIT64=1;PAL_STDCPP_COMPAT;_SECURE_SCL=0;LINUX64;PLATFORM_UNIX=1;FEATURE_PAL;FEATURE_PAL_ANSI;UNIX_AMD64_ABI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
index b1e7b11756420920a5f2ec87ed1efbdaecc844db..73994935468bff2d81efe4dbf07cc8a823905182 100644 (file)
@@ -11,9 +11,6 @@
     <ClInclude Include="mstypes.h" />
     <ClInclude Include="services.h" />
     <ClInclude Include="sosplugin.h" />
-    <ClInclude Include="inc\lldbservices.h">
-      <Filter>inc</Filter>
-    </ClInclude>
     <ClInclude Include="swift-4.0\lldb\lldb-defines.h">
       <Filter>swift-4.0\lldb</Filter>
     </ClInclude>
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
-    <Filter Include="inc">
-      <UniqueIdentifier>{32c8e536-f88f-4485-a168-9f9e9fab5822}</UniqueIdentifier>
-    </Filter>
     <Filter Include="swift-4.0">
       <UniqueIdentifier>{218787e9-5d31-4db1-bc35-232897746e27}</UniqueIdentifier>
     </Filter>
       <UniqueIdentifier>{ffdcee4c-ef55-4963-9791-6f0784ba4151}</UniqueIdentifier>
     </Filter>
   </ItemGroup>
+  <ItemGroup>
+    <Text Include="CMakeLists.txt" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
index 7203ac50ad1640550eedd5fae82669f05e3d9590..5929485ad8976cb6383ee4079302b111e86fdd99 100644 (file)
@@ -4,12 +4,11 @@
 
 #include <cstdarg>
 #include <cstdlib>
-#include "sosplugin.h"
 #include <string.h>
 #include <string>
 #include <dlfcn.h>
-#include <pthread.h>
-#include <arrayholder.h>
+#include "sosplugin.h"
+#include "arrayholder.h"
 
 #define CONVERT_FROM_SIGN_EXTENDED(offset) ((ULONG_PTR)(offset))
 
@@ -18,15 +17,13 @@ ULONG g_currentThreadSystemId = (ULONG)-1;
 char *g_coreclrDirectory = nullptr;
 char *g_pluginModuleDirectory = nullptr;
 
-LLDBServices::LLDBServices(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject, lldb::SBProcess *process, lldb::SBThread *thread) : 
+LLDBServices::LLDBServices(lldb::SBDebugger debugger, lldb::SBProcess *process, lldb::SBThread *thread) : 
     m_ref(1),
     m_debugger(debugger),
-    m_returnObject(returnObject),
     m_currentProcess(process),
     m_currentThread(thread)
 {
     ClearCache();
-    returnObject.SetStatus(lldb::eReturnStatusSuccessFinishResult);
 }
 
 LLDBServices::~LLDBServices()
@@ -46,13 +43,13 @@ LLDBServices::QueryInterface(
     if (InterfaceId == __uuidof(IUnknown) ||
         InterfaceId == __uuidof(ILLDBServices))
     {
-        *Interface = (ILLDBServices*)this;
+        *Interface = static_cast<ILLDBServices*>(this);
         AddRef();
         return S_OK;
     }
     else if (InterfaceId == __uuidof(ILLDBServices2))
     {
-        *Interface = (ILLDBServices2*)this;
+        *Interface = static_cast<ILLDBServices2*>(this);
         AddRef();
         return S_OK;
     }
@@ -111,7 +108,7 @@ LLDBServices::GetCoreClrDirectory()
     return g_coreclrDirectory;
 }
 
-DWORD_PTR
+ULONG64
 LLDBServices::GetExpression(
     PCSTR exp)
 {
@@ -126,7 +123,7 @@ LLDBServices::GetExpression(
         return 0;
     }
 
-    DWORD_PTR result = 0;
+    ULONG64 result = 0;
     lldb::SBError error;
     std::string str;
 
@@ -147,13 +144,13 @@ LLDBServices::GetExpression(
 }
 
 // Internal function
-DWORD_PTR 
+ULONG64
 LLDBServices::GetExpression(
     /* const */ lldb::SBFrame& frame,
     lldb::SBError& error,
     PCSTR exp)
 {
-    DWORD_PTR result = 0;
+    ULONG64 result = 0;
 
     lldb::SBValue value = frame.EvaluateExpression(exp, lldb::eNoDynamicValues);
     if (value.IsValid())
@@ -192,6 +189,7 @@ LLDBServices::VirtualUnwind(
     thread = process.GetThreadByID(threadID);
     if (!thread.IsValid())
     {
+        Output(DEBUG_OUTPUT_ERROR, "VirtualUnwind %08x GetThreadById FAILED\n", threadID);
         return E_FAIL;
     }
 
@@ -240,6 +238,7 @@ LLDBServices::VirtualUnwind(
 
     if (!frameFound.IsValid())
     {
+        Output(DEBUG_OUTPUT_ERROR, "VirtualUnwind %08x spToFind %016lx\n", threadID, spToFind);
         return E_FAIL;
     }
 
@@ -257,14 +256,8 @@ ExceptionBreakpointCallback(
 {
     lldb::SBDebugger debugger = process.GetTarget().GetDebugger();
 
-    // Send the normal and error output to stdout/stderr since we
-    // don't have a return object from the command interpreter.
-    lldb::SBCommandReturnObject returnObject;
-    returnObject.SetImmediateOutputFile(stdout);
-    returnObject.SetImmediateErrorFile(stderr);
-
     // Save the process and thread to be used by the current process/thread helper functions.
-    LLDBServices* client = new LLDBServices(debugger, returnObject, &process, &thread);
+    LLDBServices* client = new LLDBServices(debugger, &process, &thread);
     return ((PFN_EXCEPTION_CALLBACK)baton)(client) == S_OK;
 }
 
@@ -673,21 +666,21 @@ exit:
     return hr;
 }
 
-// Internal output string function
 void
 LLDBServices::OutputString(
     ULONG mask,
     PCSTR str)
 {
+    FILE* file;
     if (mask == DEBUG_OUTPUT_ERROR)
     {
-        m_returnObject.SetStatus(lldb::eReturnStatusFailed);
+        file = m_debugger.GetErrorFileHandle();
+    }
+    else 
+    {
+        file = m_debugger.GetOutputFileHandle();
     }
-    // Can not use AppendMessage or AppendWarning because they add a newline. SetError
-    // can not be used for DEBUG_OUTPUT_ERROR mask because it caches the error strings
-    // seperately from the normal output so error/normal texts are not intermixed 
-    // correctly.
-    m_returnObject.Printf("%s", str);
+    fputs(str, file);
 }
 
 //----------------------------------------------------------------------------
@@ -1008,6 +1001,11 @@ LLDBServices::GetModuleByModuleName(
     lldb::SBFileSpec fileSpec;
     fileSpec.SetFilename(name);
 
+    if (startIndex != 0)
+    {
+        return E_INVALIDARG;
+    }
+
     target = m_debugger.GetSelectedTarget();
     if (!target.IsValid())
     {
@@ -1032,8 +1030,9 @@ LLDBServices::GetModuleByModuleName(
 
     if (index)
     {
+        *index = 0;
         int numModules = target.GetNumModules();
-        for (int mi = startIndex; mi < numModules; mi++)
+        for (int mi = 0; mi < numModules; mi++)
         {
             lldb::SBModule mod = target.GetModuleAtIndex(mi);
             if (module == mod)
@@ -1359,10 +1358,10 @@ LLDBServices::GetModuleSize(
 //----------------------------------------------------------------------------
 
 HRESULT 
-LLDBServices::GetCurrentProcessId(
-    PULONG id)
+LLDBServices::GetCurrentProcessSystemId(
+    PULONG sysId)
 {
-    if (id == NULL)  
+    if (sysId == NULL)  
     {
         return E_INVALIDARG;
     }
@@ -1370,11 +1369,11 @@ LLDBServices::GetCurrentProcessId(
     lldb::SBProcess process = GetCurrentProcess();
     if (!process.IsValid())
     {
-        *id = 0;
+        *sysId = 0;
         return E_FAIL;
     }
 
-    *id = process.GetProcessID();
+    *sysId = process.GetProcessID();
     return S_OK;
 }
 
@@ -1498,8 +1497,8 @@ exit:
 }
 
 HRESULT 
-LLDBServices::GetThreadContextById(
-    /* in */ ULONG32 threadID,
+LLDBServices::GetThreadContextBySystemId(
+    /* in */ ULONG32 sysId,
     /* in */ ULONG32 contextFlags,
     /* in */ ULONG32 contextSize,
     /* out */ PBYTE context)
@@ -1524,13 +1523,13 @@ LLDBServices::GetThreadContextById(
 
     // If we have a "fake" thread OS (system) id and a fake thread index,
     // use the fake thread index to get the context.
-    if (g_currentThreadSystemId == threadID && g_currentThreadIndex != (ULONG)-1)
+    if (g_currentThreadSystemId == sysId && g_currentThreadIndex != (ULONG)-1)
     {
         thread = process.GetThreadByIndexID(g_currentThreadIndex);
     }
     else
     {
-        thread = process.GetThreadByID(threadID);
+        thread = process.GetThreadByID(sysId);
     }
     
     if (!thread.IsValid())
@@ -1850,7 +1849,9 @@ LLDBServices::AddModuleSymbol(
 HRESULT LLDBServices::GetModuleInfo(
     ULONG index,
     PULONG64 pBase,
-    PULONG64 pSize)
+    PULONG64 pSize,
+    PULONG pTimestamp,
+    PULONG pChecksum)
 {
     lldb::SBTarget target; 
     lldb::SBModule module;
@@ -1860,13 +1861,11 @@ HRESULT LLDBServices::GetModuleInfo(
     {
         return E_INVALIDARG;
     }
-
     module = target.GetModuleAtIndex(index);
     if (!module.IsValid())
     {
         return E_INVALIDARG;
     }
-
     if (pBase)
     {
         ULONG64 moduleBase = GetModuleBase(target, module);
@@ -1876,12 +1875,18 @@ HRESULT LLDBServices::GetModuleInfo(
         }
         *pBase = moduleBase;
     }
-
     if (pSize)
     {
         *pSize = GetModuleSize(module);
     }
-
+    if (pTimestamp)
+    {
+        *pTimestamp = 0;
+    }
+    if (pChecksum)
+    {
+        *pChecksum = 0;
+    }
     return S_OK;
 }
 
@@ -1993,14 +1998,8 @@ RuntimeLoadedBreakpointCallback(
 {
     lldb::SBDebugger debugger = process.GetTarget().GetDebugger();
 
-    // Send the normal and error output to stdout/stderr since we
-    // don't have a return object from the command interpreter.
-    lldb::SBCommandReturnObject returnObject;
-    returnObject.SetImmediateOutputFile(stdout);
-    returnObject.SetImmediateErrorFile(stderr);
-
     // Save the process and thread to be used by the current process/thread helper functions.
-    LLDBServices* client = new LLDBServices(debugger, returnObject, &process, &thread);
+    LLDBServices* client = new LLDBServices(debugger, &process, &thread);
     bool result = ((PFN_RUNTIME_LOADED_CALLBACK)baton)(client) == S_OK;
 
     // Clear the breakpoint
index 88a54077ce56bf87e4cd2280cf2d3ce8d59a3f96..dd1786bc02228cdcdd33833ecea3984386c87bb4 100644 (file)
@@ -10,9 +10,7 @@ class LLDBServices : public ILLDBServices, public ILLDBServices2
 {
 private:
     LONG m_ref;
-    lldb::SBDebugger &m_debugger;
-    lldb::SBCommandReturnObject &m_returnObject;
-
+    lldb::SBDebugger m_debugger;
     lldb::SBProcess *m_currentProcess;
     lldb::SBThread *m_currentThread;
 
@@ -24,7 +22,7 @@ private:
     void OutputString(ULONG mask, PCSTR str);
     ULONG64 GetModuleBase(lldb::SBTarget& target, lldb::SBModule& module);
     ULONG64 GetModuleSize(lldb::SBModule& module);
-    DWORD_PTR GetExpression(lldb::SBFrame& frame, lldb::SBError& error, PCSTR exp);
+    ULONG64 GetExpression(lldb::SBFrame& frame, lldb::SBError& error, PCSTR exp);
     void GetContextFromFrame(lldb::SBFrame& frame, DT_CONTEXT *dtcontext);
     DWORD_PTR GetRegister(lldb::SBFrame& frame, const char *name);
 
@@ -43,7 +41,7 @@ private:
     lldb::SBFrame GetCurrentFrame();
 
 public:
-    LLDBServices(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject, lldb::SBProcess *process = nullptr, lldb::SBThread *thread = nullptr);
+    LLDBServices(lldb::SBDebugger debugger, lldb::SBProcess *process = nullptr, lldb::SBThread *thread = nullptr);
     ~LLDBServices();
  
     //----------------------------------------------------------------------------
@@ -62,65 +60,65 @@ public:
     // ILLDBServices
     //----------------------------------------------------------------------------
 
-    PCSTR GetCoreClrDirectory();
+    PCSTR STDMETHODCALLTYPE GetCoreClrDirectory();
 
-    DWORD_PTR GetExpression(
+    ULONG64 STDMETHODCALLTYPE GetExpression(
         PCSTR exp);
 
-    HRESULT VirtualUnwind(
-        DWORD threadID,
+    HRESULT STDMETHODCALLTYPE VirtualUnwind(
+        DWORD threadId,
         ULONG32 contextSize,
         PBYTE context);
 
-    HRESULT SetExceptionCallback(
+    HRESULT STDMETHODCALLTYPE SetExceptionCallback(
         PFN_EXCEPTION_CALLBACK callback);
 
-    HRESULT ClearExceptionCallback();
+    HRESULT STDMETHODCALLTYPE ClearExceptionCallback();
 
     //----------------------------------------------------------------------------
     // IDebugControl2
     //----------------------------------------------------------------------------
 
-    HRESULT GetInterrupt();
+    HRESULT STDMETHODCALLTYPE GetInterrupt();
 
-    HRESULT Output(
+    HRESULT STDMETHODCALLTYPE Output(
         ULONG mask,
         PCSTR format,
         ...);
 
-    HRESULT OutputVaList(
+    HRESULT STDMETHODCALLTYPE OutputVaList(
         ULONG mask,
         PCSTR format,
         va_list args);
 
-    HRESULT ControlledOutput(
+    HRESULT STDMETHODCALLTYPE ControlledOutput(
         ULONG outputControl,
         ULONG mask,
         PCSTR format,
         ...);
 
-    HRESULT ControlledOutputVaList(
+    HRESULT STDMETHODCALLTYPE ControlledOutputVaList(
         ULONG outputControl,
         ULONG mask,
         PCSTR format,
         va_list args);
 
-    HRESULT GetDebuggeeType(
+    HRESULT STDMETHODCALLTYPE GetDebuggeeType(
         PULONG debugClass,
         PULONG qualifier);
 
-    HRESULT GetPageSize(
+    HRESULT STDMETHODCALLTYPE GetPageSize(
         PULONG size);
 
-    HRESULT GetExecutingProcessorType(
+    HRESULT STDMETHODCALLTYPE GetExecutingProcessorType(
         PULONG type);
 
-    HRESULT Execute(
+    HRESULT STDMETHODCALLTYPE Execute(
         ULONG outputControl,
         PCSTR command,
         ULONG flags);
 
-    HRESULT GetLastEventInformation(
+    HRESULT STDMETHODCALLTYPE GetLastEventInformation(
         PULONG type,
         PULONG processId,
         PULONG threadId,
@@ -131,7 +129,7 @@ public:
         ULONG descriptionSize,
         PULONG descriptionUsed);
 
-    HRESULT Disassemble(
+    HRESULT STDMETHODCALLTYPE Disassemble(
         ULONG64 offset,
         ULONG flags,
         PSTR buffer,
@@ -143,8 +141,7 @@ public:
     // IDebugControl4
     //----------------------------------------------------------------------------
 
-    HRESULT
-    GetContextStackTrace(
+    HRESULT STDMETHODCALLTYPE GetContextStackTrace(
         PVOID startContext,
         ULONG startContextSize,
         PDEBUG_STACK_FRAME frames,
@@ -158,13 +155,13 @@ public:
     // IDebugDataSpaces
     //----------------------------------------------------------------------------
 
-    HRESULT ReadVirtual(
+    HRESULT STDMETHODCALLTYPE ReadVirtual(
         ULONG64 offset,
         PVOID buffer,
         ULONG bufferSize,
         PULONG bytesRead);
 
-    HRESULT WriteVirtual(
+    HRESULT STDMETHODCALLTYPE WriteVirtual(
         ULONG64 offset,
         PVOID buffer,
         ULONG bufferSize,
@@ -174,37 +171,37 @@ public:
     // IDebugSymbols
     //----------------------------------------------------------------------------
 
-    HRESULT GetSymbolOptions(
+    HRESULT STDMETHODCALLTYPE GetSymbolOptions(
         PULONG options);
 
-    HRESULT GetNameByOffset(
+    HRESULT STDMETHODCALLTYPE GetNameByOffset(
         ULONG64 offset,
         PSTR nameBuffer,
         ULONG nameBufferSize,
         PULONG nameSize,
         PULONG64 displacement);
 
-    HRESULT GetNumberModules(
+    HRESULT STDMETHODCALLTYPE GetNumberModules(
         PULONG loaded,
         PULONG unloaded);
 
-    HRESULT GetModuleByIndex(
+    HRESULT STDMETHODCALLTYPE GetModuleByIndex(
         ULONG index,
         PULONG64 base);
 
-    HRESULT GetModuleByModuleName(
+    HRESULT STDMETHODCALLTYPE GetModuleByModuleName(
         PCSTR name,
         ULONG startIndex,
         PULONG index,
         PULONG64 base);
 
-    HRESULT GetModuleByOffset(
+    HRESULT STDMETHODCALLTYPE GetModuleByOffset(
         ULONG64 offset,
         ULONG startIndex,
         PULONG index,
         PULONG64 base);
 
-    HRESULT GetModuleNames(
+    HRESULT STDMETHODCALLTYPE GetModuleNames(
         ULONG index,
         ULONG64 base,
         PSTR imageNameBuffer,
@@ -217,7 +214,7 @@ public:
         ULONG loadedImageNameBufferSize,
         PULONG loadedImageNameSize);
 
-    HRESULT GetLineByOffset(
+    HRESULT STDMETHODCALLTYPE GetLineByOffset(
         ULONG64 offset,
         PULONG line,
         PSTR fileBuffer,
@@ -225,13 +222,13 @@ public:
         PULONG fileSize,
         PULONG64 displacement);
      
-    HRESULT GetSourceFileLineOffsets(
+    HRESULT STDMETHODCALLTYPE GetSourceFileLineOffsets(
         PCSTR file,
         PULONG64 buffer,
         ULONG bufferLines,
         PULONG fileLines);
 
-    HRESULT FindSourceFile(
+    HRESULT STDMETHODCALLTYPE FindSourceFile(
         ULONG startElement,
         PCSTR file,
         ULONG flags,
@@ -244,24 +241,24 @@ public:
     // IDebugSystemObjects
     //----------------------------------------------------------------------------
 
-    HRESULT GetCurrentProcessId(
-        PULONG id);
+    HRESULT STDMETHODCALLTYPE GetCurrentProcessSystemId(
+        PULONG sysId);
 
-    HRESULT GetCurrentThreadId(
+    HRESULT STDMETHODCALLTYPE GetCurrentThreadId(
         PULONG id);
 
-    HRESULT SetCurrentThreadId(
+    HRESULT STDMETHODCALLTYPE SetCurrentThreadId(
         ULONG id);
 
-    HRESULT GetCurrentThreadSystemId(
+    HRESULT STDMETHODCALLTYPE GetCurrentThreadSystemId(
         PULONG sysId);
 
-    HRESULT GetThreadIdBySystemId(
+    HRESULT STDMETHODCALLTYPE GetThreadIdBySystemId(
         ULONG sysId,
         PULONG threadId);
 
-    HRESULT GetThreadContextById(
-        ULONG32 threadID,
+    HRESULT STDMETHODCALLTYPE GetThreadContextBySystemId(
+        ULONG32 sysId,
         ULONG32 contextFlags,
         ULONG32 contextSize,
         PBYTE context);
@@ -270,37 +267,39 @@ public:
     // IDebugRegisters
     //----------------------------------------------------------------------------
 
-    HRESULT GetValueByName(
+    HRESULT STDMETHODCALLTYPE GetValueByName(
         PCSTR name,
         PDWORD_PTR debugValue);
 
-    HRESULT GetInstructionOffset(
+    HRESULT STDMETHODCALLTYPE GetInstructionOffset(
         PULONG64 offset);
 
-    HRESULT GetStackOffset(
+    HRESULT STDMETHODCALLTYPE GetStackOffset(
         PULONG64 offset);
 
-    HRESULT GetFrameOffset(
+    HRESULT STDMETHODCALLTYPE GetFrameOffset(
         PULONG64 offset);
 
     //----------------------------------------------------------------------------
     // ILLDBServices2
     //----------------------------------------------------------------------------
 
-    HRESULT LoadNativeSymbols(
+    HRESULT STDMETHODCALLTYPE LoadNativeSymbols(
         bool runtimeOnly,
         PFN_MODULE_LOAD_CALLBACK callback);
 
-    HRESULT AddModuleSymbol(
+    HRESULT STDMETHODCALLTYPE AddModuleSymbol(
         void* param, 
         const char* symbolFileName);
 
-    HRESULT GetModuleInfo(
+    HRESULT STDMETHODCALLTYPE GetModuleInfo(
         ULONG index,
-        PULONG64 base,
-        PULONG64 size);
+        PULONG64 pBase,
+        PULONG64 pSize,
+        PULONG pTimestamp,
+        PULONG pChecksum);
 
-    HRESULT GetModuleVersionInformation(
+    HRESULT STDMETHODCALLTYPE GetModuleVersionInformation(
         ULONG index,
         ULONG64 base,
         PCSTR item,
@@ -308,7 +307,7 @@ public:
         ULONG bufferSize,
         PULONG versionInfoSize);
 
-    HRESULT SetRuntimeLoadedCallback(
+    HRESULT STDMETHODCALLTYPE SetRuntimeLoadedCallback(
         PFN_RUNTIME_LOADED_CALLBACK callback);
 
     //----------------------------------------------------------------------------
index 9b40a357c60d28d73fe1b029987b87878d624ec0..b3fce4574b7570a6925bebef2f8f06347512c395 100644 (file)
@@ -21,6 +21,8 @@ public:
         char** arguments,
         lldb::SBCommandReturnObject &result)
     {
+        result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
+
         if (arguments == nullptr || arguments[0] == nullptr)
         {
             if (g_currentThreadSystemId == (ULONG)-1 || g_currentThreadIndex == (ULONG)-1)
index 4e1a19e8850cbb8269261a42eec5d6999a7cefed..791f522f2f922918670eb7dd2c5f519538b12e4f 100644 (file)
@@ -31,8 +31,9 @@ public:
                char** arguments,
                lldb::SBCommandReturnObject &result)
     {
-        LLDBServices* services = new LLDBServices(debugger, result);
-        LoadSos(services);
+        result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
+
+        LoadSos();
 
         if (g_sosHandle != nullptr)
         {
@@ -65,52 +66,53 @@ public:
                     }
                 }
                 const char* sosArgs = str.c_str();
-                HRESULT hr = commandFunc(services, sosArgs);
+                HRESULT hr = commandFunc(g_services, sosArgs);
                 if (hr != S_OK)
                 {
-                    services->Output(DEBUG_OUTPUT_ERROR, "%s %s failed\n", sosCommand, sosArgs);
+                    result.SetStatus(lldb::eReturnStatusFailed);
+                    g_services->Output(DEBUG_OUTPUT_ERROR, "%s %s failed\n", sosCommand, sosArgs);
                 }
             }
             else
             {
-                services->Output(DEBUG_OUTPUT_ERROR, "SOS command '%s' not found %s\n", sosCommand, dlerror());
+                result.SetStatus(lldb::eReturnStatusFailed);
+                g_services->Output(DEBUG_OUTPUT_ERROR, "SOS command '%s' not found %s\n", sosCommand, dlerror());
             }
         }
 
-        services->Release();
         return result.Succeeded();
     }
 
     void
-    LoadSos(LLDBServices *services)
+    LoadSos()
     {
         if (g_sosHandle == nullptr)
         {
             if (g_usePluginDirectory)
             {
-                const char *loadDirectory = services->GetPluginModuleDirectory();
+                const char *loadDirectory = g_services->GetPluginModuleDirectory();
                 if (loadDirectory != nullptr)
                 {
-                    g_sosHandle = LoadModule(services, loadDirectory, MAKEDLLNAME_A("sos"));
+                    g_sosHandle = LoadModule(loadDirectory, MAKEDLLNAME_A("sos"));
                 }
             }
             else
             {
-                const char *loadDirectory = services->GetCoreClrDirectory();
+                const char *loadDirectory = g_services->GetCoreClrDirectory();
                 if (loadDirectory != nullptr)
                 {
                     // Load the DAC module first explicitly because SOS and DBI
                     // have implicit references to the DAC's PAL.
-                    LoadModule(services, loadDirectory, MAKEDLLNAME_A("mscordaccore"));
+                    LoadModule(loadDirectory, MAKEDLLNAME_A("mscordaccore"));
 
-                    g_sosHandle = LoadModule(services, loadDirectory, MAKEDLLNAME_A("sos"));
+                    g_sosHandle = LoadModule(loadDirectory, MAKEDLLNAME_A("sos"));
                 }
             }
         }
     }
 
     void *
-    LoadModule(LLDBServices *services, const char *loadDirectory, const char *moduleName)
+    LoadModule(const char *loadDirectory, const char *moduleName)
     {
         std::string modulePath(loadDirectory);
         modulePath.append(moduleName);
@@ -118,7 +120,7 @@ public:
         void *moduleHandle = dlopen(modulePath.c_str(), RTLD_NOW);
         if (moduleHandle == nullptr)
         {
-            services->Output(DEBUG_OUTPUT_ERROR, "Could not load '%s' - %s\n", modulePath.c_str(), dlerror());
+            g_services->Output(DEBUG_OUTPUT_ERROR, "Could not load '%s' - %s\n", modulePath.c_str(), dlerror());
         }
 
         return moduleHandle;
@@ -174,6 +176,7 @@ sosCommandInitialize(lldb::SBDebugger debugger)
     interpreter.AddCommand("sympath", new sosCommand("SetSymbolServer", "-sympath"), "Add server, cache and directory paths in the Windows symbol path format.");
     interpreter.AddCommand("soshelp", new sosCommand("Help"), "Displays all available commands when no parameter is specified, or displays detailed help information about the specified command. soshelp <command>");
     interpreter.AddCommand("sosstatus", new sosCommand("SOSStatus"), "Displays the global SOS status.");
+    interpreter.AddCommand("runtimes", new sosCommand("runtimes"), "List the runtimes in the target or change the default runtime.");
     interpreter.AddCommand("sosflush", new sosCommand("SOSFlush"), "Flushes the DAC caches.");
     interpreter.AddCommand("threadpool", new sosCommand("ThreadPool"), "Displays info about the runtime thread pool.");
     interpreter.AddCommand("verifyheap", new sosCommand("VerifyHeap"), "Checks the GC heap for signs of corruption.");
index 69994d30dc89b0612e1f70cd3f3d078100b3d245..13e3633820297fc7ce9b829a961a1968f8332a20 100644 (file)
@@ -8,9 +8,11 @@ namespace lldb {
     bool PluginInitialize (lldb::SBDebugger debugger);
 }
 
-bool
-lldb::PluginInitialize (lldb::SBDebugger debugger)
+LLDBServices* g_services = nullptr;
+
+bool lldb::PluginInitialize(lldb::SBDebugger debugger)
 {
+    g_services = new LLDBServices(debugger);
     sosCommandInitialize(debugger);
     setsostidCommandInitialize(debugger);
     return true;
index 556a387b835b46e3f908fceeeb6f274dc01ecd29..60f64caa5de5e69c261dd2e110c83b1dba3f237f 100644 (file)
@@ -2,11 +2,13 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#pragma once
+
 #include <lldb/API/LLDB.h>
 #include "mstypes.h"
 #define DEFINE_EXCEPTION_RECORD
-#include <lldbservices.h>
-#include <dbgtargetcontext.h>
+#include "lldbservices.h"
+#include "dbgtargetcontext.h"
 #include "services.h"
 
 typedef HRESULT (*CommandFunc)(ILLDBServices* services, const char* args);
@@ -14,6 +16,7 @@ typedef HRESULT (*CommandFunc)(ILLDBServices* services, const char* args);
 extern char *g_coreclrDirectory;
 extern ULONG g_currentThreadIndex;
 extern ULONG g_currentThreadSystemId;
+extern LLDBServices* g_services;
 
 bool 
 sosCommandInitialize(lldb::SBDebugger debugger);
diff --git a/src/Tools/dotnet-dump/Commands/RuntimesCommand.cs b/src/Tools/dotnet-dump/Commands/RuntimesCommand.cs
deleted file mode 100644 (file)
index 0cc24fc..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using Microsoft.Diagnostics.DebugServices;
-using System.Linq;
-
-namespace Microsoft.Diagnostics.ExtensionCommands
-{
-    [Command(Name = "runtimes", Help = "List the runtimes in the target or change the default runtime.")]
-    public class RuntimesCommand: CommandBase
-    {
-        public IRuntimeService RuntimeService { get; set; }
-
-        [Option(Name = "-netfx", Help = "Switches to the desktop .NET Framework if exists.")]
-        public bool NetFx { get; set; }
-
-        [Option(Name = "-netcore", Help = "Switches to the .NET Core runtime if exists.")]
-        public bool NetCore { get; set; }
-
-        public override void Invoke()
-        {
-            if (NetFx || NetCore)
-            {
-                string name = NetFx ? "desktop .NET Framework" : ".NET Core";
-                foreach (IRuntime runtime in RuntimeService.Runtimes)
-                {
-                    if (NetFx && runtime.RuntimeType == RuntimeType.Desktop ||
-                        NetCore && runtime.RuntimeType  == RuntimeType.NetCore)
-                    {
-                        RuntimeService.SetCurrentRuntime(runtime.Id);
-                        WriteLine("Switched to {0} runtime successfully", name);
-                        return;
-                    }
-                }
-                WriteLineError("The {0} runtime is not loaded", name);
-            }
-            else
-            {
-                foreach (IRuntime runtime in RuntimeService.Runtimes)
-                {
-                    string current = RuntimeService.Runtimes.Count() > 1 ? runtime == RuntimeService.CurrentRuntime ? "*" : " " : "";
-                    Write(current);
-                    Write(runtime.ToString());
-                }
-            }
-        }
-    }
-}
index e6a0edad99fc5188d6af6673f67042e733cf06f9..39c6d8d8f93d2276c70c23bd6c00a8512900ab50 100644 (file)
@@ -39,6 +39,7 @@ namespace Microsoft.Diagnostics.ExtensionCommands
     [Command(Name = "name2ee",          DefaultOptions = "Name2EE",             Help = "Displays the MethodTable structure and EEClass structure for the specified type or method in the specified module.")]
     [Command(Name = "printexception",   DefaultOptions = "PrintException",      Aliases = new string[] { "pe" }, Help = "Displays and formats fields of any object derived from the Exception class at the specified address.")]
     [Command(Name = "sosstatus",        DefaultOptions = "SOSStatus",           Help = "Displays the global SOS status.")]
+    [Command(Name = "runtimes",         DefaultOptions = "runtimes",            Help = "List the runtimes in the target process or change the default runtime.")]
     [Command(Name = "syncblk",          DefaultOptions = "SyncBlk",             Help = "Displays the SyncBlock holder info.")]
     [Command(Name = "histclear",        DefaultOptions = "HistClear",           Help = "Releases any resources used by the family of Hist commands.")]
     [Command(Name = "histinit",         DefaultOptions = "HistInit",            Help = "Initializes the SOS structures from the stress log saved in the debuggee.")]
diff --git a/src/inc/holder.h b/src/inc/holder.h
deleted file mode 100644 (file)
index 204f807..0000000
+++ /dev/null
@@ -1,1399 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-#ifndef __HOLDER_H_
-#define __HOLDER_H_
-
-#include <wincrypt.h>
-#include "cor.h"
-#include "staticcontract.h"
-#include "volatile.h"
-#include "palclr.h"
-
-#ifdef PAL_STDCPP_COMPAT
-#include <utility>
-#include <type_traits>
-#else
-#include "clr_std/utility"
-#include "clr_std/type_traits"
-#endif
-
-#if defined(FEATURE_COMINTEROP) && !defined(STRIKE)
-#include <Activation.h>
-#include <Inspectable.h>
-#endif
-
-// Note: you can't use CONTRACT's in this file. You can't use dynamic contracts because the impl of dynamic
-// contracts depends on holders. You can't use static contracts because they include the function name as a string,
-// and the template names in this file are just too long, so you get a compiler error.
-//
-// All the functions in this file are pretty basic, so the lack of CONTRACT's isn't a big loss.
-
-#ifdef _MSC_VER
-// Make sure we can recurse deep enough for FORCEINLINE
-#pragma inline_recursion(on)
-#pragma inline_depth(16)
-#pragma warning(disable:4714)
-#endif  // _MSC_VER
-
-//------------------------------------------------------------------------------------------------
-// Declare but do not define methods that would normally be automatically generated by the
-// compiler. This will produce a link-time error if they are used. This is involved in object
-// initialization and operator eliding; see
-// http://groups.google.com/group/comp.lang.c++/msg/3cd673ab749bed83?dmode=source
-// for the intricate details.
-
-#ifdef __GNUC__
-// GCC checks accessibility of the copy ctor before performing elision optimization, so
-// it must be declared as public. VC does not, so we can declare it private to give an
-// earlier error message.
-#define HIDE_GENERATED_METHODS(_NAME)                                                       \
-    public:                                                                                 \
-        _NAME(_NAME const &);                                                               \
-    private:                                                                                \
-        _NAME & operator=(_NAME const &);
-#else
-#define HIDE_GENERATED_METHODS(_NAME)                                                       \
-    private:                                                                                \
-        _NAME(_NAME const &);                                                               \
-        _NAME & operator=(_NAME const &);
-#endif
-
-#ifdef _DEBUG
-
-//------------------------------------------------------------------------------------------------
-// This is used to make Visual Studio autoexp.dat work sensibly with holders again.
-// The problem is that certain codebases (particulary Fusion) implement key data structures
-// using a class but refer to it using a holder to an interface type. This combination prevents
-// autoexp rules from working as desired.
-// 
-// Example: Take this useful autoexp rule for CAssemblyName.
-//
-//   CAssemblyName=<_rProp._rProp[3].asStr>
-//
-// To get the same rule to fire when your assemblyname is wrapped in a ReleaseHolder,
-// add these companion rules.
-//
-//    HolderBase<CAssemblyName *>=<m_value->_rProp._rProp[3].asStr>
-//    HolderBase<IAssemblyName *>=<m_pAutoExpVisibleValue->_asCAssemblyName->_rProp._rProp[3].asStr>
-//
-//------------------------------------------------------------------------------------------------
-struct AutoExpVisibleValue
-{
-  private:
-    union
-    {
-        // Only include a class name here if it is customarily referred to through an abstract interface.
-
-#if defined(FEATURE_APPX)
-        const class AppXBindResultImpl                      *_asAppXBindResultImpl;
-#endif
-
-        const void                                          *_pPreventEmptyUnion;
-    };
-};
-#endif //_DEBUG
-
-//-----------------------------------------------------------------------------
-// Holder is the base class of all holder objects.  Any backout object should derive from it.
-// (Eventually some additional bookeeping and exception handling code will be placed in this 
-// base class.)
-//
-// There are several ways to use this class:
-//  1. Derive from HolderBase, and instantiate a Holder or Wrapper around your base.  This is necessary
-//      if you need to add more state to your holder.
-//  2. Instantiate the Holder template with your type and functions.
-//  3. Instantiate the Wrapper template with your type and functions.  The Wrapper adds some additional
-//      operator overloads to provide "smart pointer" like behavior
-//  4. Use a prebaked Holder.  This is ALWAYS the preferable strategy.  It is expected that
-//      the general design patter is that Holders will be provided as part of a typical data abstraction. 
-//      (See Crst for an example of this.)
-//-----------------------------------------------------------------------------
-
-
-
-//-----------------------------------------------------------------------------
-// HolderBase defines the base holder functionality. You can subtype and plug in 
-// a different base if you need to add more members for access during 
-// acquire & release
-//-----------------------------------------------------------------------------
-template <typename TYPE>
-class HolderBase
-{
-  protected:
-    TYPE    m_value;
-  
-    HolderBase(TYPE value)
-      : m_value(value)
-    {
-#ifdef _DEBUG
-        m_pAutoExpVisibleValue = (const AutoExpVisibleValue *)(&m_value);
-#endif //_DEBUG
-    }
-
-    void DoAcquire()
-    {
-        // Insert any global or thread bookeeping here
-    }
-
-    void DoRelease()
-    {
-        // Insert any global or thread bookeeping here
-    }
-
-#ifdef _DEBUG
- private:
-    // NOT DEAD CODE: This field is not referenced in the source code but it is not a dead field. See comments above "class AutoExpVisibleValue" for why this field exists.
-    // Note: What we really want is for m_value and m_pAutoExpVisibleValue to be members of a union. But the compiler won't let you build that
-    //       since it can't prove that "TYPE" doesn't have a non-trivial constructor.
-    const AutoExpVisibleValue *m_pAutoExpVisibleValue;  // This field is to be referenced from individual autoexp.dat files, NOT from the CLR source code.
-#endif //_DEBUG
-
-};  // class HolderBase<>
-
-#ifndef _PREFAST_ // Work around an ICE error in EspX.dll
-
-template <typename TYPE>
-BOOL CompareDefault(TYPE value, TYPE defaultValue)
-{
-    STATIC_CONTRACT_SUPPORTS_DAC; 
-    return value == defaultValue;
-}
-
-#else
-
-template <typename TYPE>
-BOOL CompareDefault(TYPE value, TYPE defaultValue)
-{
-    return FALSE;
-}
-
-#endif
-
-
-template <typename TYPE>
-BOOL NoNull(TYPE value, TYPE defaultValue)
-{
-    return FALSE;
-}
-
-// Used e.g. for retail version of code:SyncAccessHolder
-template <typename TYPE> 
-class NoOpBaseHolder
-{
-  public:
-    FORCEINLINE NoOpBaseHolder() 
-    {
-    }
-    FORCEINLINE NoOpBaseHolder(TYPE value, BOOL take = TRUE) 
-    {
-    }
-    FORCEINLINE ~NoOpBaseHolder() 
-    {
-    }
-    FORCEINLINE void Assign(TYPE value, BOOL fTake = TRUE)
-    {
-    }
-    FORCEINLINE void Acquire()
-    {
-    }
-    FORCEINLINE void Release()
-    {
-    }
-    FORCEINLINE void Clear()
-    {
-    }
-    FORCEINLINE void SuppressRelease()
-    {
-    }
-    FORCEINLINE TYPE Extract()
-    {
-    }
-    FORCEINLINE TYPE GetValue()
-    {
-    }
-    FORCEINLINE BOOL IsNull() const
-    {
-        return FALSE;
-    }
-
-  private:
-    NoOpBaseHolder& operator=(NoOpBaseHolder const &);
-    NoOpBaseHolder(NoOpBaseHolder const &);
-};  // NoOpBaseHolder<>
-
-
-template
-    <
-        typename TYPE,
-        typename BASE,
-        UINT_PTR DEFAULTVALUE = 0,
-        BOOL IS_NULL(TYPE, TYPE) = CompareDefault<TYPE>
-    >
-class BaseHolder : protected BASE
-{
-  protected:
-    BOOL    m_acquired;      // Have we acquired the resource?
-
-    static_assert(!std::is_pointer<TYPE>::value || DEFAULTVALUE == 0 || DEFAULTVALUE == UINT_PTR(-1 /*INVALID_HANDLE_VALUE*/),
-                  "DEFAULTVALUE must be NULL for pointer holders and wrappers.");
-
-  public:
-    FORCEINLINE BaseHolder() 
-      : BASE(TYPE(DEFAULTVALUE)), 
-        m_acquired(FALSE)
-    {
-    }
-    FORCEINLINE BaseHolder(TYPE value)
-      : BASE(value), 
-        m_acquired(FALSE)
-    {
-        if (!IsNull())
-            Acquire();
-    }
-    FORCEINLINE BaseHolder(TYPE value, BOOL takeOwnership) 
-      : BASE(value), 
-        m_acquired(FALSE)
-    {
-        if (takeOwnership)
-            Acquire();
-    }
-    FORCEINLINE ~BaseHolder() 
-    {
-        Release();
-    }
-    // Sets the value to 'value'. Doesn't call Acquire if value is DEFAULTVALUE.
-    FORCEINLINE void Assign(TYPE value)
-    {
-        Assign(value, !IS_NULL(value, TYPE(DEFAULTVALUE)));
-    }
-    // Sets the value to 'value'. Doesn't call Acquire if fTake is FALSE.
-    FORCEINLINE void Assign(TYPE value, BOOL takeOwnership)
-    {
-        Release();
-        this->m_value = value;
-        if (takeOwnership)
-            Acquire();
-    }
-    FORCEINLINE void Acquire()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        _ASSERTE(!m_acquired);
-
-        if (!IsNull())
-        {
-            this->DoAcquire();
-            m_acquired = TRUE;
-        }
-    }
-    FORCEINLINE void Release()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        if (m_acquired)
-        {
-            _ASSERTE(!IsNull());
-            this->DoRelease();
-            m_acquired = FALSE;
-        }
-    }
-
-    FORCEINLINE void Clear()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        Assign(TYPE(DEFAULTVALUE), FALSE);
-    }
-    FORCEINLINE void SuppressRelease()
-    {
-        STATIC_CONTRACT_LEAF;
-        m_acquired = FALSE;
-    }
-    FORCEINLINE TYPE Extract()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        SuppressRelease();
-        return GetValue();
-    }
-    FORCEINLINE TYPE GetValue()
-    {
-        STATIC_CONTRACT_LEAF;
-        return this->m_value;
-    }
-    FORCEINLINE BOOL IsNull() const
-    {
-        STATIC_CONTRACT_WRAPPER;
-        return IS_NULL(this->m_value, TYPE(DEFAULTVALUE));
-    }
-
-    HIDE_GENERATED_METHODS(BaseHolder)
-};  // BaseHolder<>
-
-template <void (*ACQUIRE)(), void (*RELEASEF)()>
-class StateHolder
-{
-  private:
-    BOOL    m_acquired;      // Have we acquired the state?
-
-  public:
-    FORCEINLINE StateHolder(BOOL take = TRUE) 
-      : m_acquired(FALSE)
-    {
-        STATIC_CONTRACT_WRAPPER;
-        if (take)
-            Acquire();
-    }
-    FORCEINLINE ~StateHolder() 
-    {
-        STATIC_CONTRACT_WRAPPER;
-        Release();
-    }
-    FORCEINLINE void Acquire()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        // Insert any global or thread bookeeping here
-
-        _ASSERTE(!m_acquired);
-
-        ACQUIRE();
-        m_acquired = TRUE;
-    }
-    FORCEINLINE void Release()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        // Insert any global or thread bookeeping here
-
-        if (m_acquired)
-        {
-            RELEASEF();
-            m_acquired = FALSE;
-        }
-    }
-    FORCEINLINE void Clear()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        if (m_acquired)
-        {
-            RELEASEF();
-        }
-
-        m_acquired = FALSE;
-    }
-    FORCEINLINE void SuppressRelease()
-    {
-        STATIC_CONTRACT_LEAF;
-        m_acquired = FALSE;
-    }
-
-    HIDE_GENERATED_METHODS(StateHolder)
-};  // class StateHolder<>
-
-// Holder for the case where the acquire function can fail.
-template <typename VALUE, BOOL (*ACQUIRE)(VALUE value), void (*RELEASEF)(VALUE value)>
-class ConditionalStateHolder
-{
-  private:
-    VALUE   m_value;
-    BOOL    m_acquired;      // Have we acquired the state?
-
-  public:
-    FORCEINLINE ConditionalStateHolder(VALUE value, BOOL take = TRUE) 
-      : m_value(value), m_acquired(FALSE)
-    {
-        STATIC_CONTRACT_WRAPPER;
-        if (take)
-            Acquire();
-    }
-    FORCEINLINE ~ConditionalStateHolder() 
-    {
-        STATIC_CONTRACT_WRAPPER;
-        Release();
-    }
-    FORCEINLINE BOOL Acquire()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        // Insert any global or thread bookeeping here
-
-        _ASSERTE(!m_acquired);
-
-        m_acquired = ACQUIRE(m_value);
-        
-        return m_acquired;
-    }
-    FORCEINLINE void Release()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        // Insert any global or thread bookeeping here
-
-        if (m_acquired)
-        {
-            RELEASEF(m_value);
-            m_acquired = FALSE;
-        }
-    }
-    FORCEINLINE void Clear()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        if (m_acquired)
-        {
-            RELEASEF(m_value);
-        }
-
-        m_acquired = FALSE;
-    }
-    FORCEINLINE void SuppressRelease()
-    {
-        STATIC_CONTRACT_LEAF;
-        m_acquired = FALSE;
-    }
-    FORCEINLINE BOOL Acquired()
-    {
-        STATIC_CONTRACT_LEAF;
-
-        return m_acquired;
-    }
-
-    HIDE_GENERATED_METHODS(ConditionalStateHolder)
-};  // class ConditionalStateHolder<>
-
-
-// Making the copy constructor private produces a warning about "can't generate copy
-// constructor" on all holders (duh, that's the point.)
-#ifdef _MSC_VER
-#pragma warning(disable:4511)
-#endif  // _MSC_VER
-
-//-----------------------------------------------------------------------------
-// BaseWrapper is just Base like a Holder, but it "transparently" proxies the type it contains,
-// using operator overloads.  Use this when you want a holder to expose the functionality of 
-// the value it contains.
-//-----------------------------------------------------------------------------
-template <typename TYPE, typename BASE,
-          UINT_PTR DEFAULTVALUE = 0, BOOL IS_NULL(TYPE, TYPE) = CompareDefault<TYPE>>
-class BaseWrapper : public BaseHolder<TYPE, BASE, DEFAULTVALUE, IS_NULL>
-{
-    typedef BaseHolder<TYPE, BASE, DEFAULTVALUE, IS_NULL> BaseT;
-
-
-#ifdef __GNUC__
-//#pragma GCC visibility push(hidden)
-#endif // __GNUC__
-    // This temporary object takes care of the case where we are initializing 
-    // a holder's contents by passing it as an out parameter.  The object is 
-    // guaranteed to live longer than the call it is passed to, hence we should
-    // properly acquire the object on return
-    friend class AddressInitHolder;
-    class AddressInitHolder
-    {
-      protected:
-        BaseWrapper<TYPE,BASE,DEFAULTVALUE,IS_NULL> &m_holder;
-
-      public:
-        FORCEINLINE AddressInitHolder(BaseWrapper<TYPE,BASE,DEFAULTVALUE,IS_NULL> &holder) 
-          : m_holder(holder) 
-        {
-            //
-            // We must clear the value, to avoid the following scenario:
-            //
-            //      ReleaseHolder<MyType> pMyType;
-            //      hr = MyFunction(&pMyType, ...);
-            //      <do something with pMyType>
-            //      hr = MyFunction(&pMyType, ...); <- calls Release before call and Acquire on return.
-            //
-            // If the second call to MyFunction were to fail and return without updating the
-            // out parameter, then ~AddressInitHolder will all Acquire, which is a no-op on
-            // the underlying pointer but sets m_acquired to TRUE. Thus, when pMyType goes
-            // out of scope, ReleaseHolder will cause a double-release of pMyType.
-            //
-            // By calling Clear, then the call to Acquire in the dtor will not set m_acquired
-            // to true since IsNull(m_holder.m_value) will return true.
-            //
-            m_holder.Clear();
-        }
-        FORCEINLINE ~AddressInitHolder()
-        {
-            m_holder.Acquire();
-        }
-
-        // It's not optimal to have to declare these casting operators.  But if we don't, 
-        // people cannot cast the result of &holder to these values.  (The C++ compiler won't
-        // automatically use the TYPE * cast as an intermediate value.)  So we put them here,
-        // rather than forcing callers to double cast in these common cases.
-
-        FORCEINLINE operator IUnknown **()
-        {
-            IUnknown *unknown;
-            // Typesafe check.  This will fail at compile time if
-            // m_holder.m_value can't be converted to an IUnknown *.
-            unknown = static_cast<IUnknown*>(m_holder.m_value);
-            // do the cast with an unsafe cast
-            return (IUnknown **)(&m_holder.m_value);
-        }
-
-#if defined(FEATURE_COMINTEROP) && !defined(STRIKE)
-        FORCEINLINE operator IInspectable **()
-        {
-            IInspectable *inspectable;
-            // Typesafe check.  This will fail at compile time if
-            // m_holder.m_value can't be converted to an IInspectable *.
-            inspectable = static_cast<IInspectable *>(m_holder.m_value);
-            return (IInspectable **)(&m_holder.m_value);
-
-        }
-#endif // FEATURE_COMINTEROP
-
-        FORCEINLINE operator void **()
-        {
-            return (void **)(&m_holder.m_value);
-        }
-        FORCEINLINE operator void *()
-        {
-            return (void *)(&m_holder.m_value);
-        }
-    };
-    
-    // Separate out method with TYPE * cast operator, since it may clash with IUnknown ** or 
-    // void ** cast operator.
-    friend class TypedAddressInitHolder;
-    class TypedAddressInitHolder : public AddressInitHolder
-    {
-      public:
-        FORCEINLINE TypedAddressInitHolder(BaseWrapper & holder) 
-          : AddressInitHolder(holder)
-        {
-        }
-
-        FORCEINLINE operator TYPE *()
-        {
-            return static_cast<TYPE *>(&this->m_holder.m_value);
-        }
-    };
-#ifdef __GNUC__
-//#pragma GCC visibility pop
-#endif // __GNUC__
-    
-  public:
-    FORCEINLINE BaseWrapper()
-        : BaseT(TYPE(DEFAULTVALUE), FALSE)
-    {
-    }
-    FORCEINLINE BaseWrapper(TYPE value)
-        : BaseT(value)
-    {
-    }
-    FORCEINLINE BaseWrapper(TYPE value, BOOL take)
-        : BaseT(value, take)
-    {
-    }
-    FORCEINLINE BaseWrapper& operator=(TYPE value)
-    {
-        BaseT::Assign(value);
-        return *this;
-    }
-    FORCEINLINE operator TYPE() const
-    {
-        return this->m_value;
-    }
-    FORCEINLINE TypedAddressInitHolder operator&()
-    {
-        return TypedAddressInitHolder(*this);
-    }
-    template <typename T>
-    FORCEINLINE bool operator==(T const & value) const
-    {
-        return !!(this->m_value == TYPE(value));
-    }
-    template <typename T>
-    FORCEINLINE bool operator!=(T const & value) const
-    {
-        return !!(this->m_value != TYPE(value));
-    }
-#ifdef __GNUC__
-    // This handles the NULL value that is an int and clang
-    // doesn't want to convert int to a pointer
-    FORCEINLINE bool operator==(int value) const
-    {
-        return !!(this->m_value == TYPE((void*)(SIZE_T)value));
-    }
-    FORCEINLINE bool operator!=(int value) const
-    {
-        return !!(this->m_value != TYPE((void*)(SIZE_T)value));
-    }
-#endif // __GNUC__
-    FORCEINLINE const TYPE &operator->() const
-    {
-        return this->m_value;
-    }
-    FORCEINLINE int operator!() const
-    {
-        return this->IsNull();
-    }
-
-  private:
-    HIDE_GENERATED_METHODS(BaseWrapper)
-};  // class BaseWrapper<>
-
-//-----------------------------------------------------------------------------
-// Generic templates to use to wrap up acquire/release functionality for Holder
-//----------------------------------------------------------------------------- 
-
-template <typename TYPE>
-FORCEINLINE void DoNothing(TYPE value)
-{
-    // @TODO: Due to prefast template problems, implementations of the DoNothing macro have been changed
-    // Search by prefast, and remove them when prefast is ready
-}
-
-FORCEINLINE void DoNothing()
-{
-}
-
-// Prefast stuff.We should have DoNothing<type*> in the holder declaration, but currently
-// prefast doesnt support, it, so im stuffing all these here so if we need to change the template you can change
-// everything here. When prefast works, remove the following functions
-struct ConnectionCookie;
-FORCEINLINE void ConnectionCookieDoNothing(ConnectionCookie* p)
-{
-}
-
-class ComCallWrapper;
-FORCEINLINE void CCWHolderDoNothing(ComCallWrapper* p)
-{
-}
-
-
-FORCEINLINE void DispParamHolderDoNothing(VARIANT* p)
-{
-}
-
-FORCEINLINE void VariantPtrDoNothing(VARIANT* p)
-{
-}
-
-FORCEINLINE void VariantDoNothing(VARIANT)
-{
-}
-
-FORCEINLINE void ZeroDoNothing(VOID* p)
-{
-}
-
-class CtxEntry;
-FORCEINLINE void CtxEntryDoNothing(CtxEntry* p)
-{
-}
-
-struct RCW;
-FORCEINLINE void NewRCWHolderDoNothing(RCW*)
-{
-}
-
-// Prefast stuff.We should have DoNothing<SafeArray*> in the holder declaration
-FORCEINLINE void SafeArrayDoNothing(SAFEARRAY* p)
-{
-}
-
-
-//-----------------------------------------------------------------------------
-// Holder/Wrapper are the simplest way to define holders - they synthesizes a base class out of 
-// function pointers
-//-----------------------------------------------------------------------------
-
-template <typename TYPE, void (*ACQUIREF)(TYPE), void (*RELEASEF)(TYPE)>
-class FunctionBase : protected HolderBase<TYPE>
-{
-  protected:
-
-    FORCEINLINE FunctionBase(TYPE value)
-      : HolderBase<TYPE>(value)
-    {
-    }
-
-    FORCEINLINE void DoAcquire()
-    {
-        ACQUIREF(this->m_value);
-    }
-
-    void DoRelease()
-    {
-        RELEASEF(this->m_value);
-    }
-};  // class Function<>
-
-template
-    <
-        typename TYPE,
-        void (*ACQUIREF)(TYPE),
-        void (*RELEASEF)(TYPE),
-        UINT_PTR DEFAULTVALUE = 0, 
-        BOOL IS_NULL(TYPE, TYPE) = CompareDefault<TYPE>,
-        // For legacy compat (see EEJitManager::WriterLockHolder), where default ctor
-        // causes ACQUIREF(DEFAULTVALUE), but ACQUIREF ignores the argument and
-        // operates on static or global value instead.
-        bool DEFAULT_CTOR_ACQUIRE = true
-    >
-class Holder : public BaseHolder<TYPE, FunctionBase<TYPE, ACQUIREF, RELEASEF>,
-                                 DEFAULTVALUE, IS_NULL>
-{
-    typedef BaseHolder<TYPE, FunctionBase<TYPE, ACQUIREF, RELEASEF>,
-                                 DEFAULTVALUE, IS_NULL> BaseT;
-
-  public:
-    FORCEINLINE Holder()
-        : BaseT(TYPE(DEFAULTVALUE), DEFAULT_CTOR_ACQUIRE)
-    {
-        STATIC_CONTRACT_WRAPPER;
-    }
-
-    FORCEINLINE Holder(TYPE value)
-        : BaseT(value)
-    {
-        STATIC_CONTRACT_WRAPPER;
-    }
-
-    FORCEINLINE Holder(TYPE value, BOOL takeOwnership) 
-        : BaseT(value, takeOwnership)
-    {
-        STATIC_CONTRACT_WRAPPER;
-    }
-
-    FORCEINLINE Holder& operator=(TYPE p)
-    {
-        STATIC_CONTRACT_WRAPPER;
-        BaseT::operator=(p);
-        return *this;
-    }
-
-    HIDE_GENERATED_METHODS(Holder)
-};
-
-//---------------------------------------------------------------------------------------
-// 
-template
-    <
-        typename TYPE,
-        void (*ACQUIREF)(TYPE),
-        void (*RELEASEF)(TYPE),
-        UINT_PTR DEFAULTVALUE = 0,
-        BOOL IS_NULL(TYPE, TYPE) = CompareDefault<TYPE>,
-        // For legacy compat (see EEJitManager::WriterLockHolder), where default ctor
-        // causes ACQUIREF(DEFAULTVALUE), but ACQUIREF ignores the argument and
-        // operates on static or global value instead.
-        bool DEFAULT_CTOR_ACQUIRE = true
-    >
-class Wrapper : public BaseWrapper<TYPE, FunctionBase<TYPE, ACQUIREF, RELEASEF>,
-                                   DEFAULTVALUE, IS_NULL>
-{
-    typedef BaseWrapper<TYPE, FunctionBase<TYPE, ACQUIREF, RELEASEF>,
-                                   DEFAULTVALUE, IS_NULL> BaseT;
-
-  public:
-    FORCEINLINE Wrapper()
-        : BaseT(TYPE(DEFAULTVALUE), DEFAULT_CTOR_ACQUIRE)
-    {
-        STATIC_CONTRACT_WRAPPER;
-    }
-
-    FORCEINLINE Wrapper(TYPE value)
-        : BaseT(value)
-    {
-        STATIC_CONTRACT_WRAPPER;
-    }
-
-    FORCEINLINE Wrapper(TYPE value, BOOL takeOwnership) 
-        : BaseT(value, takeOwnership)
-    {
-        STATIC_CONTRACT_WRAPPER;
-    }
-
-    FORCEINLINE Wrapper& operator=(TYPE const & value)
-    {
-        STATIC_CONTRACT_WRAPPER;
-        BaseT::operator=(value);
-        return *this;
-    }
-
-    HIDE_GENERATED_METHODS(Wrapper)
-};  // Wrapper<>
-
-//---------------------------------------------------------------------------------------
-// - Cannot use the standard INDEBUG macro: holder.h is used in places where INDEBUG is defined in the nonstandard way
-#if defined(_DEBUG)
-#define INDEBUG_AND_WINDOWS_FOR_HOLDERS(x) x
-#else
-#define INDEBUG_AND_WINDOWS_FOR_HOLDERS(x)
-#endif 
-
-//---------------------------------------------------------------------------------------
-// 
-// New template wrapper type macros.   These save some effort when specializing
-// existing holder templates.  (We would rather use a construct like:
-//
-// template <P1>
-// typedef Holder<...> NewHolder;
-//
-// But this construct doesn't exist in C++.  These macros ease some of the cruft necessary
-// to get similar functionality out of class templates.
-//----------------------------------------------------------------------------- 
-
-// Dev10 VC++ has some of the new C++0x language extensions. Of particular interest here:
-// rvalue references, which enables differentiation between named (lvalue) and
-// temporary (rvalue) object references, enabling move semantics and perfect forwarding.
-// See http://msdn.microsoft.com/en-us/library/dd293668.aspx for more information.
-
-// Enable copy construction and assignment from temporary objects. This permits Wrapper objects
-// to be returned from methods, and for move assignment.
-#define NEW_WRAPPER_TEMPLATE_RVALREF_METHODS(_NAME)                                             \
-      public:                                                                                   \
-        FORCEINLINE _NAME(_NAME && other)                                                       \
-        : BaseT(NULL, FALSE)                                                                    \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)                               \
-            *this = std::move(other);                                                           \
-        }                                                                                       \
-        FORCEINLINE _NAME& operator=(_NAME && other)                                            \
-        {                                                                                       \
-            std::swap(BaseT::m_value, other.BaseT::m_value);                                    \
-            std::swap(BaseT::m_acquired, other.BaseT::m_acquired);                              \
-            return *this;                                                                       \
-        }
-
-#define NEW_WRAPPER_TEMPLATE1(_NAME, _RELEASEF)                                                 \
-    template <typename _TYPE>                                                                   \
-    class _NAME : public Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL>                    \
-    {                                                                                           \
-        typedef Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL> BaseT;                      \
-      public:                                                                                   \
-        FORCEINLINE _NAME() : BaseT(NULL, FALSE)                                                \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)                               \
-        }                                                                                       \
-        FORCEINLINE _NAME(_TYPE* value) : BaseT(value)                                          \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)                               \
-        }                                                                                       \
-        FORCEINLINE _NAME(_TYPE* value, BOOL takeOwnership) : BaseT(value, takeOwnership)       \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)                               \
-        }                                                                                       \
-        FORCEINLINE ~_NAME()                                                                    \
-        {                                                                                       \
-        }                                                                                       \
-        FORCEINLINE _NAME& operator=(_TYPE * value)                                             \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            BaseT::operator=(value);                                                            \
-            return *this;                                                                       \
-        }                                                                                       \
-        /* Since operator& is overloaded we need a way to get a type safe this pointer. */      \
-        FORCEINLINE _NAME* GetAddr()                                                            \
-        {                                                                                       \
-            STATIC_CONTRACT_LEAF;                                                               \
-            return this;                                                                        \
-        }                                                                                       \
-        NEW_WRAPPER_TEMPLATE_RVALREF_METHODS(_NAME)                                             \
-        HIDE_GENERATED_METHODS(_NAME)                                                           \
-      private:                                                                                  \
-        /* m_ppValue: Do not use from source code: Only for convenient use from debugger */     \
-        /*     watch windows - saves five mouseclicks when inspecting holders. */               \
-        INDEBUG_AND_WINDOWS_FOR_HOLDERS(_TYPE ** m_pvalue;)                                     \
-    };
-
-//-----------------------------------------------------------------------------
-// NOTE: THIS IS UNSAFE TO USE IN THE VM for interop COM objects!!
-//  WE DO NOT CORRECTLY CHANGE TO PREEMPTIVE MODE BEFORE CALLING RELEASE!!
-//  USE SafeComHolder
-//
-// ReleaseHolder : COM Interface holder for use outside the VM (or on well known instances
-//                  which do not need preemptive Relesae)
-//
-// Usage example:
-//
-//  {
-//      ReleaseHolder<IFoo> foo;
-//      hr = FunctionToGetRefOfFoo(&foo); 
-//      // Note ComHolder doesn't call AddRef - it assumes you already have a ref (if non-0).
-//  } // foo->Release() on out of scope (WITHOUT RESPECT FOR GC MODE!!)
-//
-//-----------------------------------------------------------------------------
-
-template <typename TYPE> 
-FORCEINLINE void DoTheRelease(TYPE *value)
-{
-    if (value)
-    {
-        value->Release();
-    }
-}
-
-NEW_WRAPPER_TEMPLATE1(DoNothingHolder, DoNothing<_TYPE*>);
-
-NEW_WRAPPER_TEMPLATE1(ReleaseHolder, DoTheRelease<_TYPE>);
-
-NEW_WRAPPER_TEMPLATE1(NonVMComHolder, DoTheRelease<_TYPE>);
-
-
-//-----------------------------------------------------------------------------
-// StubHolder : holder for stubs
-//
-// Usage example:
-//
-//  {
-//      StubHolder<Stub> foo;
-//      foo = new Stub();
-//      foo->AddRef();
-//      // Note StubHolder doesn't call AddRef for you.
-//  } // foo->DecRef() on out of scope
-//
-//-----------------------------------------------------------------------------
-template <typename TYPE>
-FORCEINLINE void StubRelease(TYPE* value)
-{
-    if (value)
-        value->DecRef();
-}
-
-NEW_WRAPPER_TEMPLATE1(StubHolder, StubRelease<_TYPE>);
-
-//-----------------------------------------------------------------------------
-// CoTaskMemHolder : CoTaskMemAlloc allocated memory holder
-//
-//  {
-//      CoTaskMemHolder<Foo> foo = (Foo*) CoTaskMemAlloc(sizeof(Foo));
-//  } // delete foo on out of scope
-//-----------------------------------------------------------------------------
-
-template <typename TYPE> 
-FORCEINLINE void DeleteCoTaskMem(TYPE *value)
-{
-    if (value)
-        CoTaskMemFree(value);
-}
-
-NEW_WRAPPER_TEMPLATE1(CoTaskMemHolder, DeleteCoTaskMem<_TYPE>);
-
-//-----------------------------------------------------------------------------
-// NewHolder : New'ed memory holder
-//
-//  {
-//      NewHolder<Foo> foo = new Foo ();
-//  } // delete foo on out of scope
-//-----------------------------------------------------------------------------
-
-template <typename TYPE> 
-FORCEINLINE void Delete(TYPE *value)
-{
-    STATIC_CONTRACT_LEAF;
-
-    static_assert(!std::is_same<typename std::remove_cv<TYPE>::type, WCHAR>::value,
-                  "Must use NewArrayHolder (not NewHolder) for strings.");
-    static_assert(!std::is_same<typename std::remove_cv<TYPE>::type, CHAR>::value,
-                  "Must use NewArrayHolder (not NewHolder) for strings.");
-    
-    delete value;
-}
-
-NEW_WRAPPER_TEMPLATE1(NewHolder, Delete<_TYPE>);
-
- //-----------------------------------------------------------------------------
-// NewExecutableHolder : New'ed memory holder for executable memory.
-//
-//  {
-//      NewExecutableHolder<Foo> foo = (Foo*) new (executable) Byte[num];
-//  } // delete foo on out of scope
-//-----------------------------------------------------------------------------
-// IJW
-template<class T> void DeleteExecutable(T *p);
-
-NEW_WRAPPER_TEMPLATE1(NewExecutableHolder, DeleteExecutable<_TYPE>);
-//-----------------------------------------------------------------------------
-// NewArrayHolder : New []'ed pointer holder
-//  {
-//      NewArrayHolder<Foo> foo = new Foo [30];
-//  } // delete [] foo on out of scope
-//-----------------------------------------------------------------------------
-
-template <typename TYPE> 
-FORCEINLINE void DeleteArray(TYPE *value)
-{
-    STATIC_CONTRACT_WRAPPER;
-    delete [] value;
-    value = NULL;
-}
-
-NEW_WRAPPER_TEMPLATE1(NewArrayHolder, DeleteArray<_TYPE>);
-typedef NewArrayHolder<CHAR>  AStringHolder;
-typedef NewArrayHolder<WCHAR> WStringHolder;
-
-//-----------------------------------------------------------------------------
-// A special array holder that expects its contents are interface pointers,
-// and will call Release() on them.
-// 
-// NOTE: You may ONLY use this if you've determined that it is SAFE to call
-// Release() on the contained interface pointers (e.g., as opposed to SafeRelease)
-// 
-template <typename INTERFACE>
-class NewInterfaceArrayHolder : public NewArrayHolder<INTERFACE *>
-{
-public:
-    NewInterfaceArrayHolder() :
-        NewArrayHolder<INTERFACE *>(),
-        m_cElements(0) 
-    {
-        STATIC_CONTRACT_WRAPPER;
-    }
-
-    NewInterfaceArrayHolder& operator=(INTERFACE ** value)   
-    {                                             
-        STATIC_CONTRACT_WRAPPER;                  
-        NewArrayHolder<INTERFACE *>::operator=(value);                  
-        return *this;                             
-    }                                             
-
-    void SetElementCount(ULONG32 cElements)
-    {
-        STATIC_CONTRACT_LEAF;
-        m_cElements = cElements;
-    }
-
-    ~NewInterfaceArrayHolder()
-    {
-        STATIC_CONTRACT_LEAF;
-        for (ULONG32 i=0; i < m_cElements; i++)
-        {
-            if (this->m_value[i] != NULL)
-                this->m_value[i]->Release();
-        }
-    }
-
-protected:
-    ULONG32 m_cElements;
-};
-
-
-//-----------------------------------------------------------------------------
-// ResetPointerHolder : pointer which needs to be set to NULL
-//  {
-//      ResetPointerHolder<Foo> holder = &pFoo;
-//  } // "*pFoo=NULL" on out of scope
-//-----------------------------------------------------------------------------
-#ifdef __GNUC__
-// With -fvisibility-inlines-hidden, the Invoke methods below
-// get hidden, which causes warnings when visible classes expose them.
-#define VISIBLE __attribute__ ((visibility("default")))
-#else
-#define VISIBLE
-#endif // __GNUC__
-
-namespace detail
-{
-    template <typename T>
-    struct ZeroMem
-    {
-        static VISIBLE void Invoke(T * pVal)
-        {
-            ZeroMemory(pVal, sizeof(T));
-        }
-    };
-
-    template <typename T>
-    struct ZeroMem<T*>
-    {
-        static VISIBLE void Invoke(T ** pVal)
-        {
-            *pVal = NULL;
-        }
-    };
-
-}
-#undef VISIBLE
-
-NEW_WRAPPER_TEMPLATE1(ResetPointerHolder, detail::ZeroMem<_TYPE>::Invoke);
-NEW_WRAPPER_TEMPLATE1(FieldNuller, detail::ZeroMem<_TYPE>::Invoke);
-
-//-----------------------------------------------------------------------------
-// Wrap win32 functions using HANDLE
-//-----------------------------------------------------------------------------
-
-FORCEINLINE void VoidCloseHandle(HANDLE h) { if (h != NULL) CloseHandle(h); }
-// (UINT_PTR) -1 is INVALID_HANDLE_VALUE
-FORCEINLINE void VoidCloseFileHandle(HANDLE h) { if (h != ((HANDLE)((LONG_PTR) -1))) CloseHandle(h); }
-FORCEINLINE void VoidFindClose(HANDLE h) { FindClose(h); }
-FORCEINLINE void VoidUnmapViewOfFile(void *ptr) { UnmapViewOfFile(ptr); }
-
-template <typename TYPE> 
-FORCEINLINE void TypeUnmapViewOfFile(TYPE *ptr) { UnmapViewOfFile(ptr); }
-
-// (UINT_PTR) -1 is INVALID_HANDLE_VALUE
-//@TODO: Dangerous default value. Some Win32 functions return INVALID_HANDLE_VALUE, some return NULL (such as CreatEvent).
-typedef Wrapper<HANDLE, DoNothing<HANDLE>, VoidCloseHandle, (UINT_PTR) -1> HandleHolder;
-typedef Wrapper<HANDLE, DoNothing<HANDLE>, VoidCloseFileHandle, (UINT_PTR) -1> FileHandleHolder;
-typedef Wrapper<HANDLE, DoNothing<HANDLE>, VoidFindClose, (UINT_PTR) -1> FindHandleHolder;
-
-typedef Wrapper<void *, DoNothing, VoidUnmapViewOfFile> MapViewHolder;
-
-#ifdef WszDeleteFile
-// Deletes a file with the specified path.  Do not use if you care about failures
-// deleting the file, as failures are ignored by VoidDeleteFile.
-FORCEINLINE void VoidDeleteFile(LPCWSTR wszFilePath) { WszDeleteFile(wszFilePath); }
-typedef Wrapper<LPCWSTR, DoNothing<LPCWSTR>, VoidDeleteFile, NULL> DeleteFileHolder;
-#endif // WszDeleteFile
-
-
-//-----------------------------------------------------------------------------
-// Misc holders
-//-----------------------------------------------------------------------------
-
-// A holder for HMODULE.
-FORCEINLINE void HolderFreeLibrary(HMODULE h) { FreeLibrary(h); }
-
-typedef Wrapper<HMODULE, DoNothing<HMODULE>, HolderFreeLibrary, NULL> HModuleHolder;
-
-template <typename T> FORCEINLINE
-void DoLocalFree(T* pMem) { (LocalFree)((HLOCAL)pMem); }
-
-NEW_WRAPPER_TEMPLATE1(LocalAllocHolder, DoLocalFree<_TYPE>);
-
-inline void BoolSet( _Out_ bool * val ) { *val = true; }
-inline void BoolUnset( _Out_ bool * val ) { *val = false; }
-
-typedef Wrapper< bool *, BoolSet, BoolUnset > BoolFlagStateHolder;
-
-//
-// We need the following methods to have volatile arguments, so that they can accept
-// raw pointers in addition to the results of the & operator on Volatile<T>.
-//
-
-FORCEINLINE void CounterIncrease(RAW_KEYWORD(volatile) LONG* p) {InterlockedIncrement(p);};
-FORCEINLINE void CounterDecrease(RAW_KEYWORD(volatile) LONG* p) {InterlockedDecrement(p);};
-
-typedef Wrapper<RAW_KEYWORD(volatile) LONG*, CounterIncrease, CounterDecrease, (UINT_PTR)0, CompareDefault<RAW_KEYWORD(volatile) LONG*>> CounterHolder;
-
-
-#ifndef FEATURE_PAL
-FORCEINLINE void RegKeyRelease(HKEY k) {RegCloseKey(k);};
-typedef Wrapper<HKEY,DoNothing,RegKeyRelease> RegKeyHolder;
-#endif // !FEATURE_PAL
-
-class ErrorModeHolder
-{
-    UINT m_oldMode;
-public:
-    ErrorModeHolder(UINT newMode){m_oldMode=SetErrorMode(newMode);};
-    ~ErrorModeHolder(){SetErrorMode(m_oldMode);};
-    UINT OldMode() {return m_oldMode;};
-};
-
-#ifndef FEATURE_PAL
-//-----------------------------------------------------------------------------
-// HKEYHolder : HKEY holder, Calls RegCloseKey on scope exit.
-//
-//  {
-//      HKEYHolder hFoo = NULL;
-//      WszRegOpenKeyEx(HKEY_CLASSES_ROOT, L"Interface",0, KEY_READ, hFoo);
-//      
-//  } // close key on out of scope via RegCloseKey.
-//-----------------------------------------------------------------------------
-
-class HKEYHolder
-{
-public:
-    HKEYHolder()
-    {
-        STATIC_CONTRACT_LEAF;
-        m_value = 0;
-    }
-
-    ~HKEYHolder()
-    {
-        STATIC_CONTRACT_WRAPPER;
-        if (m_value != NULL)
-            ::RegCloseKey(m_value);
-    }
-
-    FORCEINLINE void operator=(HKEY p)
-    {
-        STATIC_CONTRACT_LEAF;
-        if (p != 0)
-            m_value = p;
-    }
-
-    FORCEINLINE operator HKEY()
-    {
-        STATIC_CONTRACT_LEAF;
-        return m_value;
-    }
-
-    FORCEINLINE operator HKEY*()
-    {
-        STATIC_CONTRACT_LEAF;
-        return &m_value;
-    }
-
-    FORCEINLINE HKEY* operator&()
-    {
-        STATIC_CONTRACT_LEAF;
-        return &m_value;
-    }
-
-private:
-    HKEY m_value;
-};
-#endif // !FEATURE_PAL
-
-//----------------------------------------------------------------------------
-//
-// External data access does not want certain holder implementations
-// to be active as locks should not be taken and so on.  Provide
-// a no-op in that case.
-//
-//----------------------------------------------------------------------------
-
-#ifndef DACCESS_COMPILE
-
-#define DacHolder Holder
-
-#else
-
-template <typename TYPE, void (*ACQUIRE)(TYPE), void (*RELEASEF)(TYPE), UINT_PTR DEFAULTVALUE = 0, BOOL IS_NULL(TYPE, TYPE) = CompareDefault<TYPE>, BOOL VALIDATE_BACKOUT_STACK = TRUE>
-class DacHolder
-{
-  protected:
-    TYPE    m_value;
-
-  private:
-    BOOL    m_acquired;      // Have we acquired the resource?
-
-  public:
-    FORCEINLINE DacHolder() 
-      : m_value(TYPE(DEFAULTVALUE)), 
-        m_acquired(FALSE)
-    {
-        STATIC_CONTRACT_SUPPORTS_DAC;
-    }
-
-    // construct a new instance of DacHolder
-    // Arguments: 
-    //     input:  value - the resource held
-    //             take  - indicates whether the lock should be taken--the default is true. See Notes:
-    // Note: In DAC builds, the Acquire function does not actually take the lock, instead
-    //       it determines whether the lock is held (by the LS). If it is, the locked data
-    //       is assumed to be inconsistent and the Acquire function will throw.
-    FORCEINLINE DacHolder(TYPE value, BOOL take = TRUE) 
-      : m_value(value), 
-        m_acquired(FALSE)
-    {
-        STATIC_CONTRACT_SUPPORTS_DAC;
-        if (take)
-            Acquire();
-
-    }
-    FORCEINLINE ~DacHolder() 
-    {
-        STATIC_CONTRACT_SUPPORTS_DAC;
-    }
-    // Sets the value to 'value'. Doesn't call Acquire/Release if fTake is FALSE.
-    FORCEINLINE void Assign(TYPE value, BOOL fTake = TRUE)
-    {
-        m_value = value;
-    }
-    FORCEINLINE void Acquire()
-    {
-        STATIC_CONTRACT_SUPPORTS_DAC;
-
-        if (!IsNull())
-        {
-            m_acquired = TRUE;
-            // because ACQUIRE is a template argument, if the line m_acquired = TRUE is placed after the call
-            // where it logically belongs, the compiler flags it as "unreachable code." 
-            ACQUIRE(this->m_value);
-        }
-    }
-    FORCEINLINE void Release()
-    {
-        // Insert any global or thread bookeeping here
-
-        if (m_acquired)
-        {
-            m_acquired = FALSE;
-        }
-    }
-    FORCEINLINE void Clear()
-    {
-        m_value = TYPE(DEFAULTVALUE);
-        m_acquired = FALSE;
-    }
-    FORCEINLINE void SuppressRelease()
-    {
-        m_acquired = FALSE;
-    }
-    FORCEINLINE TYPE GetValue()
-    {
-        return m_value;
-    }
-    FORCEINLINE BOOL IsNull() const
-    {
-        return IS_NULL(m_value, TYPE(DEFAULTVALUE));
-    }
-
-  private:
-    FORCEINLINE DacHolder& operator=(const Holder<TYPE, ACQUIRE, RELEASEF> &holder)
-    {
-    }
-
-    FORCEINLINE DacHolder(const Holder<TYPE, ACQUIRE, RELEASEF> &holder)
-    {
-    }
-};
-
-#endif // #ifndef DACCESS_COMPILE
-
-// Holder-specific clr::SafeAddRef and clr::SafeRelease helper functions.
-namespace clr
-{
-    // Copied from utilcode.h. We can't include the header directly because there
-    // is circular reference.
-    // Forward declare the overload which is used by 'SafeAddRef' below.
-    template <typename ItfT>
-    static inline
-    typename std::enable_if< std::is_pointer<ItfT>::value, ItfT >::type
-    SafeAddRef(ItfT pItf);
-
-    template < typename ItfT > __checkReturn
-    ItfT *
-    SafeAddRef(ReleaseHolder<ItfT> & pItf)
-    {
-        STATIC_CONTRACT_LIMITED_METHOD;
-        //@TODO: Would be good to add runtime validation that the return value is used.
-        return SafeAddRef(pItf.GetValue());
-    }
-
-    namespace detail
-    {
-        template <typename T>
-        char IsHolderHelper(HolderBase<T>*);
-        int  IsHolderHelper(...);
-
-        template <typename T>
-        struct IsHolder : public std::conditional<
-            sizeof(IsHolderHelper(reinterpret_cast<T*>(NULL))) == sizeof(char),
-            std::true_type,
-            std::false_type>::type
-        {};
-    }
-
-    template < typename T >
-    typename std::enable_if<detail::IsHolder<T>::value, ULONG>::type
-    SafeRelease(T& arg)
-    {
-        STATIC_CONTRACT_LIMITED_METHOD;
-        return arg.Release();
-    }
-}
-
-#endif  // __HOLDER_H_
diff --git a/src/inc/releaseholder.h b/src/inc/releaseholder.h
new file mode 100644 (file)
index 0000000..1afe2ce
--- /dev/null
@@ -0,0 +1,78 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#pragma once
+
+// This class acts a smart pointer which calls the Release method on any object
+// you place in it when the ReleaseHolder class falls out of scope.  You may use it
+// just like you would a standard pointer to a COM object (including if (foo),
+// if (!foo), if (foo == 0), etc) except for two caveats:
+//     1. This class never calls AddRef and it always calls Release when it
+//        goes out of scope.
+//     2. You should never use & to try to get a pointer to a pointer unless
+//        you call Release first, or you will leak whatever this object contains
+//        prior to updating its internal pointer.
+template<class T>
+class ReleaseHolder
+{
+public:
+    ReleaseHolder()
+        : m_ptr(NULL)
+    {}
+
+    ReleaseHolder(T* ptr)
+        : m_ptr(ptr)
+    {}
+
+    ~ReleaseHolder()
+    {
+        Release();
+    }
+
+    void operator=(T* ptr)
+    {
+        Release();
+
+        m_ptr = ptr;
+    }
+
+    T* operator->()
+    {
+        return m_ptr;
+    }
+
+    operator T*()
+    {
+        return m_ptr;
+    }
+
+    void** operator&()
+    {
+        return (void**)&m_ptr;
+    }
+
+    T* GetPtr() const
+    {
+        return m_ptr;
+    }
+
+    T* Detach()
+    {
+        T* pT = m_ptr;
+        m_ptr = NULL;
+        return pT;
+    }
+
+    void Release()
+    {
+        if (m_ptr != NULL)
+        {
+            m_ptr->Release();
+            m_ptr = NULL;
+        }
+    }
+
+private:
+    T* m_ptr;
+};
+
index 4ced657a736f71abf04435a1a285c447bb12e6ae..698bd61b085fc3cffb0b5ebcaecd1e09e3c5ac2a 100644 (file)
@@ -32,7 +32,8 @@
 #include "log.h"
 
 #if defined(STRESS_LOG) && !defined(FEATURE_NO_STRESSLOG)
-#include "holder.h"
+#include "releaseholder.h"
+#include "volatile.h"
 #include "staticcontract.h"
 #include "mscoree.h"
 #include "clrinternal.h"
@@ -402,19 +403,6 @@ typedef USHORT
     static StressLog theLog;    // We only have one log, and this is it
 };
 
-typedef Holder<CRITSEC_COOKIE, StressLog::Enter, StressLog::Leave, NULL, CompareDefault<CRITSEC_COOKIE>> StressLogLockHolder;
-
-#if defined(DACCESS_COMPILE)
-inline BOOL StressLog::LogOn(unsigned facility, unsigned level)
-{
-    STATIC_CONTRACT_LEAF;
-    STATIC_CONTRACT_SUPPORTS_DAC;
-
-    // StressLog isn't dacized, and besides we don't want to log to it in DAC builds.
-    return FALSE;
-}
-#endif
-
 /*************************************************************************************/
 /* private classes */