regarding DebugClient::Request ( DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE )

probably a c 101 question

i am trying to use the function

DebugClient::Request with DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE

whose inbuffer and outbuffer needs to be a struct

// InBuffer - DEBUG_GET_TEXT_COMPLETIONS_IN.
// OutBuffer - DEBUG_GET_TEXT_COMPLETIONS_OUT.
#define DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE 14

and the struct is defined like this

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;

how do i make the input text string to follow ? is this api exposed to use ?

as a hack i redefined the struct to have a wchar_t buffer at end
typedef struct _MYDGTCIN
{
ULONG Flags;
ULONG MatchCountLimit;
ULONG64 Reserved[3];
wchar_t InputText[0x28];
} DGTCIN, *PDGTCIN;

declare
DGTCIN dbgcompin;
and fill it with swprintf_s() like

swprintf_s(dbgcompin.InputText,25,L"!du");

and call the request

if( ( status = g_Advanced2->Request(
DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE,
&dbgcompin,
0x28,

and it seems i am able to successfully get past dbgeng!GetTextCompletions

also how is __in ULONG InBufferSize, defined ?

it seems this plays a role in some error conditions posted below

GetDbgPrint.exe !ca
total completions available 4
first completion can_write_kdump

GetDbgPrint.exe !ba <---------- should say no command available or keep mumb
some error go check g_Advanced2->Request(

GetDbgPrint.exe !be <---------- should say no command available or keep mumb
some error go check g_Advanced2->Request(

GetDbgPrint.exe !ad
total completions available 3
first completion addrbias

GetDbgPrint.exe !du
total completions available 3
first completion dumpfa

GetDbgPrint.exe !b <--------------------------- should work but fails
some error go check g_Advanced2->Request(

GetDbgPrint.exe !bf
total completions available 1
first completion bft

GetDbgPrint.exe !bi
total completions available 2
first completion bitcount

raj_r wrote:

probably a c 101 question

i am trying to use the function

DebugClient::Request with DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE

whose inbuffer and outbuffer needs to be a struct

// InBuffer - DEBUG_GET_TEXT_COMPLETIONS_IN.
// OutBuffer - DEBUG_GET_TEXT_COMPLETIONS_OUT.
#define DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE 14

and the struct is defined like this

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;

how do i make the input text string to follow ? is this api exposed to use ?

You allocate enough space for both and cast the pointer. Example:

DEBUG_GET_TEXT_COMPLETIONS_IN * dgtci =
malloc( sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + 40 *
sizeof(wchar_t));

Now you can get a pointer to the string region like this:

wchar_t * InputText = (wchar_t) (dgtci + 1);

and fill it with swprintf_s() like

swprintf_s(dbgcompin.InputText,25,L"!du");

Why would you use swprintf for this instead of wcscpy?

It is dangerous to hard-code the length in swprintf_s. You say 25, but
you allocated the region as 40. If you happen to reduce the size of the
string and forget to update the swprintf_s, disaster ensues. It’s much
better to say something like _countof(dbgcompin.InputText)

and call the request

if( ( status = g_Advanced2->Request(
DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE,
&dbgcompin,
0x28,

Again, you have a hard-coded constant for the length, and again it is
wrong. You allocated 0x28 (40 decimal) Unicode characters in your
string, which means 80 bytes, PLUS the size of the rest of the
structure. In this case, a better choice is probably something like:
sizeof(DEBUG_REQUEST_GET_COMPLETIONS_IN) + (wcslen(InputText)+1) *
sizeof(wchar_t)

and it seems i am able to successfully get past dbgeng!GetTextCompletions

also how is __in ULONG InBufferSize, defined ?

We don’t know. The option is not documented.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

tim thanks for replying back

all those hardcoded stuff are hacks just to verify if something is
working or not
coded in 10 20 lines of copy paste on a standalone snippet especially
done to post a question here on thought process so that i have
something that is compiling and can answer further queries if any i
will remove them or will rewrite them properly

so if the string is a variablesize i substitute it with something like
(len(intext) X sizeof(wchar_t) ) instead of 40 while doing malloc
fine i will try that and provide the same to IN ULONG BUFFERSIZE as
well and see

from a glance it seems it is failing at dbgeng!AppendChar ( str , " * ")

DEBUG_GET_TEXT_COMPLETIONS_IN * dgtci =
malloc( sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + 40 *
sizeof(wchar_t));

thanks once again

On 10/10/12, Tim Roberts wrote:
> raj_r wrote:
>> probably a c 101 question
>>
>> i am trying to use the function
>>
>> DebugClient::Request with DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE
>>
>> whose inbuffer and outbuffer needs to be a struct
>>
>> // InBuffer - DEBUG_GET_TEXT_COMPLETIONS_IN.
>> // OutBuffer - DEBUG_GET_TEXT_COMPLETIONS_OUT.
>> #define DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE 14
>>
>> and the struct is defined like this
>>
>> 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;
>>
>> how do i make the input text string to follow ? is this api exposed to use
>> ?
>
> You allocate enough space for both and cast the pointer. Example:
>
> DEBUG_GET_TEXT_COMPLETIONS_IN * dgtci =
> malloc( sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + 40 *
> sizeof(wchar_t));
>
> Now you can get a pointer to the string region like this:
>
> wchar_t * InputText = (wchar_t) (dgtci + 1);
>
>
>
>> and fill it with swprintf_s() like
>>
>> swprintf_s(dbgcompin.InputText,25,L"!du");
>
> Why would you use swprintf for this instead of wcscpy?
>
> It is dangerous to hard-code the length in swprintf_s. You say 25, but
> you allocated the region as 40. If you happen to reduce the size of the
> string and forget to update the swprintf_s, disaster ensues. It’s much
> better to say something like _countof(dbgcompin.InputText)
>
>
>> and call the request
>>
>> if( ( status = g_Advanced2->Request(
>> DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE,
>> &dbgcompin,
>> 0x28,
>
> Again, you have a hard-coded constant for the length, and again it is
> wrong. You allocated 0x28 (40 decimal) Unicode characters in your
> string, which means 80 bytes, PLUS the size of the rest of the
> structure. In this case, a better choice is probably something like:
> sizeof(DEBUG_REQUEST_GET_COMPLETIONS_IN) + (wcslen(InputText)+1) *
> sizeof(wchar_t)
>
>
>> and it seems i am able to successfully get past
>> dbgeng!GetTextCompletions
>>
>> also how is __in ULONG InBufferSize, defined ?
>
> We don’t know. The option is not documented.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> WINDBG is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

thanks tim seems to work fine

char failedfunc[0x200] = {0};
DEBUG_GET_TEXT_COMPLETIONS_IN *dgtci;
DEBUG_GET_TEXT_COMPLETIONS_OUT *dgtco;
int __cdecl GetDbgPrint(LPCWSTR intext)
{

HRESULT status;
dgtci = (DEBUG_GET_TEXT_COMPLETIONS_IN * ) malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + ((wcslen( intext)+1) *
sizeof(wchar_t)) );
if(NULL == dgtci)
{
sprintf_s(failedfunc,0x100,“malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + ((wcslen( intext)+1) *
sizeof(wchar_t)) )”);
return FALSE;
}
dgtco = ( DEBUG_GET_TEXT_COMPLETIONS_OUT * ) malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + OUTBUFFLENGTH );
if(NULL == dgtco)
{
sprintf_s(failedfunc,0x100,“malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + OUTBUFFLENGTH )”);
return FALSE;
}
memset( dgtci, 0, ( sizeof( DEBUG_GET_TEXT_COMPLETIONS_IN ) + ( (
wcslen( intext )+1 ) * sizeof( wchar_t ) ) ) );
memset( dgtco, 0, ( sizeof( DEBUG_GET_TEXT_COMPLETIONS_OUT ) +
OUTBUFFLENGTH ) );
wchar_t * InputText = (wchar_t *) (dgtci + 1);
wchar_t * OutputText = (wchar_t *) (dgtco + 1);
ULONG outsize;
dgtci->Flags = 0;
dgtci->MatchCountLimit = 0;
wcscpy_s(InputText,( ( wcslen( intext )+1 ) * sizeof( wchar_t ) ),intext);

if( ( status = g_Advanced2->Request(
DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE,
dgtci,
(sizeof( DEBUG_GET_TEXT_COMPLETIONS_IN ) + ( ( wcslen( intext )+1 )
* sizeof( wchar_t ) ) ),
dgtco,
OUTBUFFLENGTH,
&outsize
) ) !=S_OK )
{
sprintf_s(failedfunc,0x100,“g_Advanced2->Request(”);
return FALSE;
}

printf(“total completions available %d\n”,dgtco->MatchCount);
wchar_t *CompletionText = OutputText;
for (ULONG i= 1; i <= dgtco->MatchCount; i++)
{

printf(“completion no %4d is %S\n”,i,CompletionText);
CompletionText = CompletionText + (wcslen(CompletionText)+1);

}

DbgPrint.exe !d
total completions available 35
completion no 1 is dh
completion no 2 is dml_proc
completion no 3 is dumpfa
completion no 4 is dumptype
completion no 5 is dlls
completion no 6 is dlltree
completion no 7 is db
completion no 8 is dc
completion no 9 is dcs
completion no 10 is dd
completion no 11 is diskspace
completion no 12 is dp
completion no 13 is dq
completion no 14 is du
completion no 15 is dw
completion no 16 is dbgprint
completion no 17 is dblink
completion no 18 is dcr
completion no 19 is deadlock
completion no 20 is defwrites
completion no 21 is devext
completion no 22 is devhandles
completion no 23 is devinst
completion no 24 is devnode
completion no 25 is devobj
completion no 26 is devstack
completion no 27 is dflink
completion no 28 is diskrespin
completion no 29 is dma
completion no 30 is dpa
completion no 31 is dpcs
completion no 32 is driveinfo
completion no 33 is drivers
completion no 34 is drvobj
completion no 35 is dskheap

On 10/11/12, raj_r wrote:
> tim thanks for replying back
>
> all those hardcoded stuff are hacks just to verify if something is
> working or not
> coded in 10 20 lines of copy paste on a standalone snippet especially
> done to post a question here on thought process so that i have
> something that is compiling and can answer further queries if any i
> will remove them or will rewrite them properly
>
> so if the string is a variablesize i substitute it with something like
> (len(intext) X sizeof(wchar_t) ) instead of 40 while doing malloc
> fine i will try that and provide the same to IN ULONG BUFFERSIZE as
> well and see
>
> from a glance it seems it is failing at dbgeng!AppendChar ( str , " * “)
>
> DEBUG_GET_TEXT_COMPLETIONS_IN * dgtci =
> malloc( sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + 40 *
> sizeof(wchar_t));
>
>
> thanks once again
>
> On 10/10/12, Tim Roberts wrote:
>> raj_r wrote:
>>> probably a c 101 question
>>>
>>> i am trying to use the function
>>>
>>> DebugClient::Request with DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE
>>>
>>> whose inbuffer and outbuffer needs to be a struct
>>>
>>> // InBuffer - DEBUG_GET_TEXT_COMPLETIONS_IN.
>>> // OutBuffer - DEBUG_GET_TEXT_COMPLETIONS_OUT.
>>> #define DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE 14
>>>
>>> and the struct is defined like this
>>>
>>> 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;
>>>
>>> how do i make the input text string to follow ? is this api exposed to
>>> use
>>> ?
>>
>> You allocate enough space for both and cast the pointer. Example:
>>
>> DEBUG_GET_TEXT_COMPLETIONS_IN * dgtci =
>> malloc( sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + 40 *
>> sizeof(wchar_t));
>>
>> Now you can get a pointer to the string region like this:
>>
>> wchar_t * InputText = (wchar_t) (dgtci + 1);
>>
>>
>>
>>> and fill it with swprintf_s() like
>>>
>>> swprintf_s(dbgcompin.InputText,25,L”!du");
>>
>> Why would you use swprintf for this instead of wcscpy?
>>
>> It is dangerous to hard-code the length in swprintf_s. You say 25, but
>> you allocated the region as 40. If you happen to reduce the size of the
>> string and forget to update the swprintf_s, disaster ensues. It’s much
>> better to say something like _countof(dbgcompin.InputText)
>>
>>
>>> and call the request
>>>
>>> if( ( status = g_Advanced2->Request(
>>> DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE,
>>> &dbgcompin,
>>> 0x28,
>>
>> Again, you have a hard-coded constant for the length, and again it is
>> wrong. You allocated 0x28 (40 decimal) Unicode characters in your
>> string, which means 80 bytes, PLUS the size of the rest of the
>> structure. In this case, a better choice is probably something like:
>> sizeof(DEBUG_REQUEST_GET_COMPLETIONS_IN) + (wcslen(InputText)+1) *
>> sizeof(wchar_t)
>>
>>
>>> and it seems i am able to successfully get past
>>> dbgeng!GetTextCompletions
>>>
>>> also how is __in ULONG InBufferSize, defined ?
>>
>> We don’t know. The option is not documented.
>>
>> –
>> Tim Roberts, xxxxx@probo.com
>> Providenza & Boekelheide, Inc.
>>
>>
>> —
>> WINDBG is sponsored by OSR
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>

raj_r wrote:

thanks tim seems to work fine

char failedfunc[0x200] = {0};
DEBUG_GET_TEXT_COMPLETIONS_IN *dgtci;
DEBUG_GET_TEXT_COMPLETIONS_OUT *dgtco;
int __cdecl GetDbgPrint(LPCWSTR intext)
{

HRESULT status;
dgtci = (DEBUG_GET_TEXT_COMPLETIONS_IN * ) malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + ((wcslen( intext)+1) *
sizeof(wchar_t)) );

Remember to free these mallocs later. I don’t see that in your code.

dgtco = ( DEBUG_GET_TEXT_COMPLETIONS_OUT * ) malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + OUTBUFFLENGTH );
if(NULL == dgtco)
{
sprintf_s(failedfunc,0x100,“malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + OUTBUFFLENGTH )”);
return FALSE;
}

Even here, you need to free(dgtci).


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

yes i do free them infact i free dgtco and again malloc dgtco on
S_FALSE Result from Request increasing the size of default
outbuffsize to returned value

wchar_t commandbuff[0x100]={0};
int __cdecl main( int argc, LPCTSTR argv )
{
UNREFERENCED_PARAMETER(argc);
MultiByteToWideChar(CP_ACP, 0, argv[1], -1, commandbuff,
sizeof(commandbuff-10));
if ((GetDbgPrint(commandbuff)) == FALSE)
{
printf(“some error go check %s\n”,failedfunc);
}
if(g_Control)
g_Control->Release();
if(g_Client)
g_Client->Release();
if(dgtci)
free(dgtci);
if(dgtco)
free(dgtco);
return 0;
}

and by adding a check to S_FALSE and increasing the outbuffsize

i can get all the 10000 odd completions and i think if i do a execute
(“.reload /f”) these completions can go far higher though i havent
tested it yet

total completions available 10075
out size is 485702
completion no 1 is SharedUserData!SystemCallStub

completion no 10074 is nt!__unnamed
completion no 10075 is nt!__unnamed

same result from lkd session

lkd> .shell -ci “x *!*” wc -l
9448
.shell: Process exited
lkd> .shell -ci “dt *!*” wc -l
627
.shell: Process exited
lkd> ? 0n9448+0n627
Evaluate expression: 10075 = 0000275b

check for S_FALSE and reexecuting Request

status = g_Advanced2->Request(
DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE,
dgtci,
(sizeof( DEBUG_GET_TEXT_COMPLETIONS_IN ) + ( ( wcslen( intext )+1 )
* sizeof( wchar_t ) ) ),
dgtco,
OUTBUFFLENGTH,
&outsize
);
if (status == S_FALSE)
{
free(dgtco);
dgtco = NULL;
dgtco = ( DEBUG_GET_TEXT_COMPLETIONS_OUT * ) malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + outsize+10 );
if(NULL == dgtco)
{
sprintf_s(failedfunc,0x100,“malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + outsize+10 )”);
return FALSE;
}
memset( dgtco, 0, ( sizeof( DEBUG_GET_TEXT_COMPLETIONS_OUT ) + outsize+10 ) );
OutputText = (wchar_t *) (dgtco + 1);
if (( status = g_Advanced2->Request(
DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE,
dgtci,
(sizeof( DEBUG_GET_TEXT_COMPLETIONS_IN ) + ( ( wcslen( intext )+1 )
* sizeof( wchar_t ) ) ),
dgtco,
( sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + outsize+10 ),
&outsize
) ) != S_OK)
{
sprintf_s(failedfunc,0x100,“g_Advanced2->Request( second time with
big outbuff”);
return FALSE;
}
}

printf(“total completions available %d\n”,dgtco->MatchCount);
printf(“out size is %d\n”,outsize);
wchar_t *CompletionText = OutputText;
for (ULONG i= 1; i <= dgtco->MatchCount; i++)
{

printf(“completion no %4d is %S\n”,i,CompletionText);
CompletionText = CompletionText + (wcslen(CompletionText)+1);

}

return TRUE;
}

On 10/11/12, Tim Roberts wrote:
> raj_r wrote:
>> thanks tim seems to work fine
>>
>> char failedfunc[0x200] = {0};
>> DEBUG_GET_TEXT_COMPLETIONS_IN *dgtci;
>> DEBUG_GET_TEXT_COMPLETIONS_OUT *dgtco;
>> int __cdecl GetDbgPrint(LPCWSTR intext)
>> {
>>
>> HRESULT status;
>> dgtci = (DEBUG_GET_TEXT_COMPLETIONS_IN * ) malloc(
>> sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + ((wcslen( intext)+1) *
>> sizeof(wchar_t)) );
>
> Remember to free these mallocs later. I don’t see that in your code.
>
>
>> dgtco = ( DEBUG_GET_TEXT_COMPLETIONS_OUT * ) malloc(
>> sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + OUTBUFFLENGTH );
>> if(NULL == dgtco)
>> {
>> sprintf_s(failedfunc,0x100,“malloc(
>> sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + OUTBUFFLENGTH )”);
>> return FALSE;
>> }
>
> Even here, you need to free(dgtci).
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> WINDBG is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

raj_r wrote:

yes i do free them infact i free dgtco and again malloc dgtco on
S_FALSE Result from Request increasing the size of default
outbuffsize to returned value

OK, I’m about to dive deeply into programming style and best practices
here, which means this is very far afield from the original request.
Feel free to move along if you want.

You have defined all 4 of those things as global variables (g_Control,
g_Client, dgtci, dgtco). You allocate them in GetDbgPrint and you free
them in main. That’s just not good practice. If those things are only
needed within GetDbgPrint, then they should be declared, allocated, and
freed within GetDbgPrint. If you are using C++, you can use CComPtr to
manage the COM objects, and something like std::auto_ptr to manage the
structures. Then, they all clean THEMSELVES up.

The problem is that, at some point, you might need to call that function
twice, or you might change the design in some subtle way, and then
you’ll have a memory leak.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

ok my app and lkd both clock 0.2 million completions

hopefully i am now bug free or as clean as dbgeng :slight_smile:

MyApp
completion no 202122 is ntdll!__unnamed

lkd> .shell -ci “dt *!*” wc -l
2623
lkd> .shell -ci “x *!*” wc -l
213759
lkd> ? 0n2623+0n213759
Evaluate expression: 216382 = 00034d3e

On 10/11/12, raj_r wrote:
> yes i do free them infact i free dgtco and again malloc dgtco on
> S_FALSE Result from Request increasing the size of default
> outbuffsize to returned value
>
> wchar_t commandbuff[0x100]={0};
> int __cdecl main( int argc, LPCTSTR argv )
> {
> UNREFERENCED_PARAMETER(argc);
> MultiByteToWideChar(CP_ACP, 0, argv[1], -1, commandbuff,
> sizeof(commandbuff-10));
> if ((GetDbgPrint(commandbuff)) == FALSE)
> {
> printf(“some error go check %s\n”,failedfunc);
> }
> if(g_Control)
> g_Control->Release();
> if(g_Client)
> g_Client->Release();
> if(dgtci)
> free(dgtci);
> if(dgtco)
> free(dgtco);
> return 0;
> }
>
> and by adding a check to S_FALSE and increasing the outbuffsize
>
> i can get all the 10000 odd completions and i think if i do a execute
> (“.reload /f”) these completions can go far higher though i havent
> tested it yet
>
> total completions available 10075
> out size is 485702
> completion no 1 is SharedUserData!SystemCallStub
>
>
> completion no 10074 is nt!__unnamed
> completion no 10075 is nt!__unnamed
>
>
> same result from lkd session
>
> lkd> .shell -ci “x !” wc -l
> 9448
> .shell: Process exited
> lkd> .shell -ci “dt !” wc -l
> 627
> .shell: Process exited
> lkd> ? 0n9448+0n627
> Evaluate expression: 10075 = 0000275b
>
>
> check for S_FALSE and reexecuting Request
>
> status = g_Advanced2->Request(
> DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE,
> dgtci,
> (sizeof( DEBUG_GET_TEXT_COMPLETIONS_IN ) + ( ( wcslen( intext )+1 )
> * sizeof( wchar_t ) ) ),
> dgtco,
> OUTBUFFLENGTH,
> &outsize
> );
> if (status == S_FALSE)
> {
> free(dgtco);
> dgtco = NULL;
> dgtco = ( DEBUG_GET_TEXT_COMPLETIONS_OUT * ) malloc(
> sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + outsize+10 );
> if(NULL == dgtco)
> {
> sprintf_s(failedfunc,0x100,“malloc(
> sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + outsize+10 )”);
> return FALSE;
> }
> memset( dgtco, 0, ( sizeof( DEBUG_GET_TEXT_COMPLETIONS_OUT ) + outsize+10
> ) );
> OutputText = (wchar_t *) (dgtco + 1);
> if (( status = g_Advanced2->Request(
> DEBUG_REQUEST_GET_TEXT_COMPLETIONS_WIDE,
> dgtci,
> (sizeof( DEBUG_GET_TEXT_COMPLETIONS_IN ) + ( ( wcslen( intext )+1 )
> * sizeof( wchar_t ) ) ),
> dgtco,
> ( sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + outsize+10 ),
> &outsize
> ) ) != S_OK)
> {
> sprintf_s(failedfunc,0x100,“g_Advanced2->Request( second time with
> big outbuff”);
> return FALSE;
> }
> }
>
> printf(“total completions available %d\n”,dgtco->MatchCount);
> printf(“out size is %d\n”,outsize);
> wchar_t *CompletionText = OutputText;
> for (ULONG i= 1; i <= dgtco->MatchCount; i++)
> {
>
> printf(“completion no %4d is %S\n”,i,CompletionText);
> CompletionText = CompletionText + (wcslen(CompletionText)+1);
>
> }
>
>
> return TRUE;
> }
>
>
>
>
> On 10/11/12, Tim Roberts wrote:
>> raj_r wrote:
>>> thanks tim seems to work fine
>>>
>>> char failedfunc[0x200] = {0};
>>> DEBUG_GET_TEXT_COMPLETIONS_IN *dgtci;
>>> DEBUG_GET_TEXT_COMPLETIONS_OUT *dgtco;
>>> int__cdecl GetDbgPrint(LPCWSTR intext)
>>> {
>>>
>>> HRESULT status;
>>> dgtci = (DEBUG_GET_TEXT_COMPLETIONS_IN * ) malloc(
>>> sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + ((wcslen( intext)+1) *
>>> sizeof(wchar_t)) );
>>
>> Remember to free these mallocs later. I don’t see that in your code.
>>
>>
>>> dgtco = ( DEBUG_GET_TEXT_COMPLETIONS_OUT * ) malloc(
>>> sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + OUTBUFFLENGTH );
>>> if(NULL == dgtco)
>>> {
>>> sprintf_s(failedfunc,0x100,“malloc(
>>> sizeof(DEBUG_GET_TEXT_COMPLETIONS_OUT) + OUTBUFFLENGTH )”);
>>> return FALSE;
>>> }
>>
>> Even here, you need to free(dgtci).
>>
>> –
>> Tim Roberts, xxxxx@probo.com
>> Providenza & Boekelheide, Inc.
>>
>>
>> —
>> WINDBG is sponsored by OSR
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>

On 10/12/12, Tim Roberts wrote:

> OK, I’m about to dive deeply into programming style and best practices
> here, which means this is very far afield from the original request.
> Feel free to move along if you want.

Thanks For the Pointers Tim
yes i keep reminding myself to code like i code for a living
rather than code like coding for hobby but the debugger spoils me all the time

btw without having to alter much i redid it with a goto
(arrrrrrrgghhhhhhh) cleanup ; though i have to disable a warning with
/w4 /wx



#pragma warning (push)
#pragma warning( disable : 4701 )
int __cdecl GetDbgPrint(LPCWSTR intext,PCHAR failedfunc)
{
IDebugClient* g_Client;
IDebugControl* g_Control;
IDebugAdvanced2* g_Advanced2;
DEBUG_GET_TEXT_COMPLETIONS_IN *dgtci;
DEBUG_GET_TEXT_COMPLETIONS_OUT *dgtco;
HRESULT status;

dgtci = (DEBUG_GET_TEXT_COMPLETIONS_IN * ) malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + ((wcslen( intext)+1) *
sizeof(wchar_t)) );
if(NULL == dgtci)
{
sprintf_s(failedfunc,0x100,“malloc(
sizeof(DEBUG_GET_TEXT_COMPLETIONS_IN) + ((wcslen( intext)+1) *
sizeof(wchar_t)) )”);
goto cleanup;
}

------------------------------------------

if(status == S_OK)
{

printf(“total completions available %d\n”,dgtco->MatchCount);
printf(“out size is %d\n”,outsize);
wchar_t *CompletionText = OutputText;
for (ULONG i= 1; i <= dgtco->MatchCount; i++)
{
printf(“completion no %4d is %S\n”,i,CompletionText);
CompletionText = CompletionText + (wcslen(CompletionText)+1);
}
return TRUE;
}

cleanup:
if(dgtci)
free(dgtci);
if(dgtco) <--------------- compiler warns potentially
uninitialized local on this and 3 below
free(dgtco);
if(g_Client)
g_Client->Release();
if(g_Control)
g_Control->Release();
if(g_Advanced2)
g_Advanced2->Release();
return FALSE;
#pragma warning( pop )

}

int__cdecl main( int argc, LPCTSTR argv )
{
UNREFERENCED_PARAMETER(argc);
wchar_t commandbuff[0x100]={0};
char failedfunc[0x200] = {0};
MultiByteToWideChar(CP_ACP, 0, argv[1], -1, commandbuff,
((sizeof(commandbuff)-10)/2) );
if ((GetDbgPrint(commandbuff,failedfunc)) == FALSE)
{
printf(“some error go check %s\n”,failedfunc);
}
return 0;
}