kernelbase: Emit DBG_PRINTEXCEPTION_WIDE_C from OutputDebugStringW.

Also modifying WaitForDebugEvent() to force resending the ansi
DBG_PRINTEXCEPTION_C exception instead.

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
Eric Pouech 2023-08-17 15:49:51 +02:00 committed by Alexandre Julliard
parent 514f63f3b5
commit 090fb2cc19
3 changed files with 62 additions and 18 deletions

View file

@ -264,6 +264,11 @@ void WINAPI DECLSPEC_HOTPATCH OutputDebugStringA( LPCSTR str )
}
}
static LONG WINAPI debug_exception_handler_wide( EXCEPTION_POINTERS *eptr )
{
EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
return (rec->ExceptionCode == DBG_PRINTEXCEPTION_WIDE_C) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
}
/***********************************************************************
* OutputDebugStringW (kernelbase.@)
@ -273,10 +278,32 @@ void WINAPI DECLSPEC_HOTPATCH OutputDebugStringW( LPCWSTR str )
UNICODE_STRING strW;
STRING strA;
WARN( "%s\n", debugstr_w(str) );
RtlInitUnicodeString( &strW, str );
if (!RtlUnicodeStringToAnsiString( &strA, &strW, TRUE ))
{
OutputDebugStringA( strA.Buffer );
BOOL exc_handled;
__TRY
{
ULONG_PTR args[4];
args[0] = wcslen(str) + 1;
args[1] = (ULONG_PTR)str;
args[2] = strlen(strA.Buffer) + 1;
args[3] = (ULONG_PTR)strA.Buffer;
RaiseException( DBG_PRINTEXCEPTION_WIDE_C, 0, 4, args );
exc_handled = TRUE;
}
__EXCEPT(debug_exception_handler_wide)
{
exc_handled = FALSE;
}
__ENDTRY
if (!exc_handled)
OutputDebugStringA( strA.Buffer );
RtlFreeAnsiString( &strA );
}
}

View file

@ -404,6 +404,17 @@ BOOL WINAPI DECLSPEC_HOTPATCH WaitForDebugEvent( DEBUG_EVENT *event, DWORD timeo
switch (status)
{
case STATUS_SUCCESS:
/* continue on wide print exceptions to force resending an ANSI one. */
if (state.NewState == DbgExceptionStateChange)
{
DBGKM_EXCEPTION *info = &state.StateInfo.Exception;
DWORD code = info->ExceptionRecord.ExceptionCode;
if (code == DBG_PRINTEXCEPTION_WIDE_C && info->ExceptionRecord.NumberParameters >= 2)
{
DbgUiContinue( &state.AppClientId, DBG_EXCEPTION_NOT_HANDLED );
break;
}
}
DbgUiConvertStateChangeStructure( &state, event );
return TRUE;
case STATUS_USER_APC:

View file

@ -8715,7 +8715,8 @@ static LONG CALLBACK outputdebugstring_vectored_handler(EXCEPTION_POINTERS *Exce
return EXCEPTION_CONTINUE_SEARCH;
}
static void test_outputdebugstring(BOOL unicode, DWORD numexc_ansi, BOOL todo_ansi, DWORD numexc_unicode)
static void test_outputdebugstring(BOOL unicode, DWORD numexc_ansi, BOOL todo_ansi,
DWORD numexc_unicode_low, DWORD numexc_unicode_high)
{
PVOID vectored_handler;
@ -8739,10 +8740,11 @@ static void test_outputdebugstring(BOOL unicode, DWORD numexc_ansi, BOOL todo_an
ok(outputdebugstring_exceptions_ansi == numexc_ansi,
"OutputDebugString%c generated %ld ansi exceptions, expected %ld\n",
unicode ? 'W' : 'A', outputdebugstring_exceptions_ansi, numexc_ansi);
todo_wine_if(unicode && numexc_unicode)
ok(outputdebugstring_exceptions_unicode == numexc_unicode,
"OutputDebugString%c generated %lu unicode exceptions, expected %ld\n",
unicode ? 'W' : 'A', outputdebugstring_exceptions_unicode, numexc_unicode);
todo_wine_if(unicode && numexc_unicode_low)
ok(outputdebugstring_exceptions_unicode >= numexc_unicode_low &&
outputdebugstring_exceptions_unicode <= numexc_unicode_high,
"OutputDebugString%c generated %lu unicode exceptions, expected %ld-%ld\n",
unicode ? 'W' : 'A', outputdebugstring_exceptions_unicode, numexc_unicode_low, numexc_unicode_high);
pRtlRemoveVectoredExceptionHandler(vectored_handler);
}
@ -8804,11 +8806,6 @@ static void test_outputdebugstring_newmodel(void)
};
int i;
if (!pWaitForDebugEventEx)
{
skip("Unsupported new unicode debug string model\n");
return;
}
if (!pRtlAddVectoredExceptionHandler || !pRtlRemoveVectoredExceptionHandler)
{
skip("RtlAddVectoredExceptionHandler or RtlRemoveVectoredExceptionHandler not found\n");
@ -11326,13 +11323,16 @@ START_TEST(exception)
#endif
test_stage = STAGE_OUTPUTDEBUGSTRINGA_CONTINUE;
test_outputdebugstring(FALSE, 0, FALSE, 0);
test_outputdebugstring(FALSE, 0, FALSE, 0, 0);
test_stage = STAGE_OUTPUTDEBUGSTRINGA_NOT_HANDLED;
test_outputdebugstring(FALSE, 2, TRUE, 0); /* is 2 a Windows bug? */
test_outputdebugstring(FALSE, 2, TRUE, 0, 0); /* is 2 a Windows bug? */
test_stage = STAGE_OUTPUTDEBUGSTRINGW_CONTINUE;
test_outputdebugstring(TRUE, 0, FALSE, 0);
/* depending on value passed DebugContinue we can get the unicode exception or not */
test_outputdebugstring(TRUE, 0, FALSE, 0, 1);
test_stage = STAGE_OUTPUTDEBUGSTRINGW_NOT_HANDLED;
test_outputdebugstring(TRUE, 2, TRUE, 1); /* is 2 a Windows bug? */
/* depending on value passed DebugContinue we can get the unicode exception or not */
test_outputdebugstring(TRUE, 2, TRUE, 0, 1); /* is 2 a Windows bug? */
test_stage = STAGE_RIPEVENT_CONTINUE;
test_ripevent(0);
test_stage = STAGE_RIPEVENT_NOT_HANDLED;
@ -11449,9 +11449,15 @@ START_TEST(exception)
test_debugger(DBG_EXCEPTION_HANDLED, TRUE);
test_debugger(DBG_CONTINUE, TRUE);
test_thread_context();
test_outputdebugstring(FALSE, 1, FALSE, 0);
test_outputdebugstring(TRUE, 1, FALSE, 1);
test_outputdebugstring_newmodel();
test_outputdebugstring(FALSE, 1, FALSE, 0, 0);
if (pWaitForDebugEventEx)
{
test_outputdebugstring(TRUE, 1, FALSE, 1, 1);
test_outputdebugstring_newmodel();
}
else
skip("Unsupported new unicode debug string model\n");
test_ripevent(1);
test_fastfail();
test_breakpoint(1);