diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2016-11-23 19:09:09 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2016-11-23 19:09:09 +0900 |
commit | 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (patch) | |
tree | 98110734c91668dfdbb126fcc0e15ddbd93738ca /src/ToolBox/SOS/Strike/inc | |
parent | fa45f57ed55137c75ac870356a1b8f76c84b229c (diff) | |
download | coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.gz coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.bz2 coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.zip |
Imported Upstream version 1.1.0upstream/1.1.0
Diffstat (limited to 'src/ToolBox/SOS/Strike/inc')
-rw-r--r-- | src/ToolBox/SOS/Strike/inc/.gitmirror | 1 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/inc/dbgeng.h | 16122 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/inc/dbghelp.h | 4540 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/inc/wdbgexts.h | 2807 |
4 files changed, 23470 insertions, 0 deletions
diff --git a/src/ToolBox/SOS/Strike/inc/.gitmirror b/src/ToolBox/SOS/Strike/inc/.gitmirror new file mode 100644 index 0000000000..f507630f94 --- /dev/null +++ b/src/ToolBox/SOS/Strike/inc/.gitmirror @@ -0,0 +1 @@ +Only contents of this folder, excluding subfolders, will be mirrored by the Git-TFS Mirror.
\ No newline at end of file diff --git a/src/ToolBox/SOS/Strike/inc/dbgeng.h b/src/ToolBox/SOS/Strike/inc/dbgeng.h new file mode 100644 index 0000000000..73e4d19f99 --- /dev/null +++ b/src/ToolBox/SOS/Strike/inc/dbgeng.h @@ -0,0 +1,16122 @@ +// 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 +#define __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 __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 __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 __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 __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 __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 __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/ToolBox/SOS/Strike/inc/dbghelp.h b/src/ToolBox/SOS/Strike/inc/dbghelp.h new file mode 100644 index 0000000000..8075929bf0 --- /dev/null +++ b/src/ToolBox/SOS/Strike/inc/dbghelp.h @@ -0,0 +1,4540 @@ +// 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/ToolBox/SOS/Strike/inc/wdbgexts.h b/src/ToolBox/SOS/Strike/inc/wdbgexts.h new file mode 100644 index 0000000000..5e0e8c3adf --- /dev/null +++ b/src/ToolBox/SOS/Strike/inc/wdbgexts.h @@ -0,0 +1,2807 @@ +// 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_ |