如何使用dbgeng.h实现命令的文本自动补全?
How to implement text auto-completion of commands using dbgeng.h?
我正在为 windbg 开发一个前端,它使用了非常有据可查的 dbgeng.h
API。但是有一些我不知道如何实现的功能,例如选项卡自动完成。我相信我需要的是以下 APIs:
IDebugAdvanced3::Request
DEBUG_GET_TEXT_COMPLETIONS_OUT
DEBUG_REQUEST_GET_TEXT_COMPLETIONS_ANSI(未记录)
dbgeng.h
里面也有一些注释定义了这些结构:
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;
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;
我不明白我应该如何使用它 API。
编辑:我按照评论中的建议尝试了以下操作:
struct in_wrap
{
DEBUG_GET_TEXT_COMPLETIONS_IN in;
char src[4];
};
in_wrap wrp;
DEBUG_GET_TEXT_COMPLETIONS_IN in;
in.Flags = DEBUG_GET_TEXT_COMPLETIONS_NO_SYMBOLS;
in.MatchCountLimit = 5;
wrp.in = in;
strcpy(wrp.src, ".ec"); // I'm expecting to receive ".echo" back.
DEBUG_GET_TEXT_COMPLETIONS_OUT out = {};
ULONG outsize = 0;
hr = advanced->Request(DEBUG_REQUEST_GET_TEXT_COMPLETIONS_ANSI,
(void *)&wrp, sizeof(in_wrap),
(void *)&out, sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT), &outsize);
其中 returns E_INVALIDARGS
.
- 部分输入是通配符,因此您需要在输入后跟一个星号,例如“.db*”
- out 需要两次迭代,一次是为了获得 S_FALSE 的大小和可用的完成大小
第二个在 OUT 之后分配内存作为 IN 的类型定义结构
下面的代码在 OUT 中有一个固定大小的缓冲区作为 poc
如果你只是在没有缓冲区的情况下通过 OUT 你应该接收一个 S_FALSE(01) 作为 HRESULT
opsize 必须指示完成字符所需的内存大小
代码如下
#include <engextcpp.cpp>
typedef struct _AUTOCOMPIN {
DEBUG_GET_TEXT_COMPLETIONS_IN auin;
char instr[8];
} Autocompin, *PAutocompin;
typedef struct _AUTOCOMPOUT {
DEBUG_GET_TEXT_COMPLETIONS_OUT auout;
char ostr[0x1000];
} Autocompout, *Pautocompout;
class EXT_CLASS : public ExtExtension {
public:
EXT_COMMAND_METHOD(autocomp);
};
EXT_DECLARE_GLOBALS();
EXT_COMMAND(autocomp, "", "") {
Autocompin ibuff = {0};
Autocompout obuff = {0};
ULONG opsize = 0;
HRESULT hr = E_FAIL;
strcpy_s(ibuff.instr, ".d*");
hr = m_Advanced2->Request(
DEBUG_REQUEST_GET_TEXT_COMPLETIONS_ANSI,
&ibuff,
sizeof(ibuff),
&obuff,
sizeof(obuff),
&opsize);
Out("hr = %x opsize = %x IDebugAdvancedCheckPointer = %p\n", hr, opsize, m_Advanced2);
for (ULONG i = 0; i < opsize; i++) {
Out("%c ", obuff.ostr[i]);
}
}
编译并链接
:\>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27045 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
:\>type complink.bat (must be in one line )
cl /LD /nologo /W4 /Od /Zi /EHsc /I"C:\Program Files (x86)\Windows Kits\Debuggers\inc" %1.cpp
/link /EXPORT:DebugExtensionInitialize /Export:%1 /Export:help /RELEASE
:\>
编译执行
:\>complink.bat autocomp
:\>cl /LD /nologo /W4 /Od /Zi /EHsc /I"C:\Program Files (x86)\Windows Kits\Debuggers\inc" autocomp.cpp /link /EXPORT:DebugExtensionInitialize /Export:autocomp /Export:help /RELEASE
autocomp.cpp
C:\Program Files (x86)\Windows Kits\Debuggers\inc\engextcpp.cpp(1849): warning C4245: 'argument': conversion from 'int' to 'ULONG64', signed/unsigned mismatch
Creating library autocomp.lib and object autocomp.exp
:\>cdb -c ".load .\autocomp;!autocomp;q" cdb
Microsoft (R) Windows Debugger Version 10.0.17763.132 AMD64
0:000> cdb: Reading initial command '.load .\autocomp;!autocomp;q'
hr = 0 opsize = 8c IDebugAdvancedCheckPointer = 00000057edfface0
d b g d b g
d e b u g _ s w _ w o w
d e t a c h
d m l _ f i l e
d m l _ f l o w
d m l _ s t a r t
d o d r i v e r s
d u m p
d v a l l o c
d v f r e e
d i s a b l e p a c k a g e d e b u g
quit:
我正在为 windbg 开发一个前端,它使用了非常有据可查的 dbgeng.h
API。但是有一些我不知道如何实现的功能,例如选项卡自动完成。我相信我需要的是以下 APIs:
IDebugAdvanced3::Request
DEBUG_GET_TEXT_COMPLETIONS_OUT
DEBUG_REQUEST_GET_TEXT_COMPLETIONS_ANSI(未记录)
dbgeng.h
里面也有一些注释定义了这些结构:
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;
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;
我不明白我应该如何使用它 API。
编辑:我按照评论中的建议尝试了以下操作:
struct in_wrap
{
DEBUG_GET_TEXT_COMPLETIONS_IN in;
char src[4];
};
in_wrap wrp;
DEBUG_GET_TEXT_COMPLETIONS_IN in;
in.Flags = DEBUG_GET_TEXT_COMPLETIONS_NO_SYMBOLS;
in.MatchCountLimit = 5;
wrp.in = in;
strcpy(wrp.src, ".ec"); // I'm expecting to receive ".echo" back.
DEBUG_GET_TEXT_COMPLETIONS_OUT out = {};
ULONG outsize = 0;
hr = advanced->Request(DEBUG_REQUEST_GET_TEXT_COMPLETIONS_ANSI,
(void *)&wrp, sizeof(in_wrap),
(void *)&out, sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT), &outsize);
其中 returns E_INVALIDARGS
.
- 部分输入是通配符,因此您需要在输入后跟一个星号,例如“.db*”
- out 需要两次迭代,一次是为了获得 S_FALSE 的大小和可用的完成大小
第二个在 OUT 之后分配内存作为 IN 的类型定义结构
下面的代码在 OUT 中有一个固定大小的缓冲区作为 poc
如果你只是在没有缓冲区的情况下通过 OUT 你应该接收一个 S_FALSE(01) 作为 HRESULT
opsize 必须指示完成字符所需的内存大小
代码如下
#include <engextcpp.cpp>
typedef struct _AUTOCOMPIN {
DEBUG_GET_TEXT_COMPLETIONS_IN auin;
char instr[8];
} Autocompin, *PAutocompin;
typedef struct _AUTOCOMPOUT {
DEBUG_GET_TEXT_COMPLETIONS_OUT auout;
char ostr[0x1000];
} Autocompout, *Pautocompout;
class EXT_CLASS : public ExtExtension {
public:
EXT_COMMAND_METHOD(autocomp);
};
EXT_DECLARE_GLOBALS();
EXT_COMMAND(autocomp, "", "") {
Autocompin ibuff = {0};
Autocompout obuff = {0};
ULONG opsize = 0;
HRESULT hr = E_FAIL;
strcpy_s(ibuff.instr, ".d*");
hr = m_Advanced2->Request(
DEBUG_REQUEST_GET_TEXT_COMPLETIONS_ANSI,
&ibuff,
sizeof(ibuff),
&obuff,
sizeof(obuff),
&opsize);
Out("hr = %x opsize = %x IDebugAdvancedCheckPointer = %p\n", hr, opsize, m_Advanced2);
for (ULONG i = 0; i < opsize; i++) {
Out("%c ", obuff.ostr[i]);
}
}
编译并链接
:\>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27045 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
:\>type complink.bat (must be in one line )
cl /LD /nologo /W4 /Od /Zi /EHsc /I"C:\Program Files (x86)\Windows Kits\Debuggers\inc" %1.cpp
/link /EXPORT:DebugExtensionInitialize /Export:%1 /Export:help /RELEASE
:\>
编译执行
:\>complink.bat autocomp
:\>cl /LD /nologo /W4 /Od /Zi /EHsc /I"C:\Program Files (x86)\Windows Kits\Debuggers\inc" autocomp.cpp /link /EXPORT:DebugExtensionInitialize /Export:autocomp /Export:help /RELEASE
autocomp.cpp
C:\Program Files (x86)\Windows Kits\Debuggers\inc\engextcpp.cpp(1849): warning C4245: 'argument': conversion from 'int' to 'ULONG64', signed/unsigned mismatch
Creating library autocomp.lib and object autocomp.exp
:\>cdb -c ".load .\autocomp;!autocomp;q" cdb
Microsoft (R) Windows Debugger Version 10.0.17763.132 AMD64
0:000> cdb: Reading initial command '.load .\autocomp;!autocomp;q'
hr = 0 opsize = 8c IDebugAdvancedCheckPointer = 00000057edfface0
d b g d b g
d e b u g _ s w _ w o w
d e t a c h
d m l _ f i l e
d m l _ f l o w
d m l _ s t a r t
d o d r i v e r s
d u m p
d v a l l o c
d v f r e e
d i s a b l e p a c k a g e d e b u g
quit: