如何使用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_GET_TEXT_COMPLETIONS_IN

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.

  1. 部分输入是通配符,因此您需要在输入后跟一个星号,例如“.db*”
  2. out 需要两次迭代,一次是为了获得 S_FALSE 的大小和可用的完成大小
    第二个在 OUT 之后分配内存作为 IN
  3. 的类型定义结构

下面的代码在 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: