Commit 1b3d67aa authored by Sebastian Lackner's avatar Sebastian Lackner Committed by Alexandre Julliard

kernel32: Raise DBG_PRINTEXCEPTION_C exception in OutputDebugStringA.

parent e9fbcc83
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "wine/server.h" #include "wine/server.h"
#include "kernel_private.h" #include "kernel_private.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(debugstr); WINE_DEFAULT_DEBUG_CHANNEL(debugstr);
...@@ -227,6 +228,11 @@ BOOL WINAPI DebugActiveProcessStop( DWORD pid ) ...@@ -227,6 +228,11 @@ BOOL WINAPI DebugActiveProcessStop( DWORD pid )
return ret; return ret;
} }
static LONG WINAPI debug_exception_handler( EXCEPTION_POINTERS *eptr )
{
EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
return (rec->ExceptionCode == DBG_PRINTEXCEPTION_C) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
}
/*********************************************************************** /***********************************************************************
* OutputDebugStringA (KERNEL32.@) * OutputDebugStringA (KERNEL32.@)
...@@ -248,7 +254,22 @@ void WINAPI OutputDebugStringA( LPCSTR str ) ...@@ -248,7 +254,22 @@ void WINAPI OutputDebugStringA( LPCSTR str )
if (!str) str = ""; if (!str) str = "";
/* raise fake exception to make copy protections happy */
__TRY
{
ULONG_PTR args[2];
args[0] = strlen(str) + 1;
args[1] = (ULONG_PTR)str;
RaiseException( DBG_PRINTEXCEPTION_C, 0, 2, args );
}
__EXCEPT(debug_exception_handler)
{
}
__ENDTRY
/* send string to attached debugger */ /* send string to attached debugger */
/* FIXME should only send to debugger if exception is not caught by user-mode application */
SERVER_START_REQ( output_debug_string ) SERVER_START_REQ( output_debug_string )
{ {
req->string = wine_server_client_ptr( str ); req->string = wine_server_client_ptr( str );
......
...@@ -1572,6 +1572,45 @@ static void test_dynamic_unwind(void) ...@@ -1572,6 +1572,45 @@ static void test_dynamic_unwind(void)
#endif /* __x86_64__ */ #endif /* __x86_64__ */
static DWORD outputdebugstring_exceptions;
static LONG CALLBACK outputdebugstring_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo)
{
PEXCEPTION_RECORD rec = ExceptionInfo->ExceptionRecord;
trace("vect. handler %08x addr:%p\n", rec->ExceptionCode, rec->ExceptionAddress);
ok(rec->ExceptionCode == DBG_PRINTEXCEPTION_C, "ExceptionCode is %08x instead of %08x\n",
rec->ExceptionCode, DBG_PRINTEXCEPTION_C);
ok(rec->NumberParameters == 2, "ExceptionParameters is %d instead of 2\n", rec->NumberParameters);
ok(rec->ExceptionInformation[0] == 12, "ExceptionInformation[0] = %d instead of 12\n", (DWORD)rec->ExceptionInformation[0]);
ok(!strcmp((char *)rec->ExceptionInformation[1], "Hello World"),
"ExceptionInformation[1] = '%s' instead of 'Hello World'\n", (char *)rec->ExceptionInformation[1]);
outputdebugstring_exceptions++;
return EXCEPTION_CONTINUE_SEARCH;
}
static void test_outputdebugstring(void)
{
PVOID vectored_handler;
if (!pRtlAddVectoredExceptionHandler || !pRtlRemoveVectoredExceptionHandler)
{
skip("RtlAddVectoredExceptionHandler or RtlRemoveVectoredExceptionHandler not found\n");
return;
}
vectored_handler = pRtlAddVectoredExceptionHandler(TRUE, &outputdebugstring_vectored_handler);
ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n");
outputdebugstring_exceptions = 0;
OutputDebugStringA("Hello World");
ok(outputdebugstring_exceptions == 1, "OutputDebugStringA generated %d exceptions, expected one\n",
outputdebugstring_exceptions);
pRtlRemoveVectoredExceptionHandler(vectored_handler);
}
START_TEST(exception) START_TEST(exception)
{ {
HMODULE hntdll = GetModuleHandleA("ntdll.dll"); HMODULE hntdll = GetModuleHandleA("ntdll.dll");
...@@ -1675,5 +1714,7 @@ START_TEST(exception) ...@@ -1675,5 +1714,7 @@ START_TEST(exception)
#endif #endif
test_outputdebugstring();
VirtualFree(code_mem, 0, MEM_FREE); VirtualFree(code_mem, 0, MEM_FREE);
} }
...@@ -1211,6 +1211,7 @@ ...@@ -1211,6 +1211,7 @@
#define DBG_TERMINATE_THREAD ((NTSTATUS) 0x40010003) #define DBG_TERMINATE_THREAD ((NTSTATUS) 0x40010003)
#define DBG_TERMINATE_PROCESS ((NTSTATUS) 0x40010004) #define DBG_TERMINATE_PROCESS ((NTSTATUS) 0x40010004)
#define DBG_CONTROL_C ((NTSTATUS) 0x40010005) #define DBG_CONTROL_C ((NTSTATUS) 0x40010005)
#define DBG_PRINTEXCEPTION_C ((NTSTATUS) 0x40010006)
#define DBG_CONTROL_BREAK ((NTSTATUS) 0x40010008) #define DBG_CONTROL_BREAK ((NTSTATUS) 0x40010008)
#define DBG_COMMAND_EXCEPTION ((NTSTATUS) 0x40010009) #define DBG_COMMAND_EXCEPTION ((NTSTATUS) 0x40010009)
#define DBG_EXCEPTION_NOT_HANDLED ((NTSTATUS) 0x80010001) #define DBG_EXCEPTION_NOT_HANDLED ((NTSTATUS) 0x80010001)
......
...@@ -622,6 +622,7 @@ typedef DWORD FLONG; ...@@ -622,6 +622,7 @@ typedef DWORD FLONG;
#define DBG_TERMINATE_THREAD ((DWORD) 0x40010003) #define DBG_TERMINATE_THREAD ((DWORD) 0x40010003)
#define DBG_TERMINATE_PROCESS ((DWORD) 0x40010004) #define DBG_TERMINATE_PROCESS ((DWORD) 0x40010004)
#define DBG_CONTROL_C ((DWORD) 0x40010005) #define DBG_CONTROL_C ((DWORD) 0x40010005)
#define DBG_PRINTEXCEPTION_C ((DWORD) 0x40010006)
#define DBG_CONTROL_BREAK ((DWORD) 0x40010008) #define DBG_CONTROL_BREAK ((DWORD) 0x40010008)
#define DBG_COMMAND_EXCEPTION ((DWORD) 0x40010009) #define DBG_COMMAND_EXCEPTION ((DWORD) 0x40010009)
#define DBG_EXCEPTION_NOT_HANDLED ((DWORD) 0x80010001) #define DBG_EXCEPTION_NOT_HANDLED ((DWORD) 0x80010001)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment