diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index ca4fea84209..11dbc63a3b3 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -39,6 +39,7 @@ #include "ddk/ntddk.h" WINE_DEFAULT_DEBUG_CHANNEL(ntdll); +WINE_DECLARE_DEBUG_CHANNEL(debugstr); /* CRC polynomial 0xedb88320 */ static const DWORD CRC_table[256] = @@ -297,21 +298,24 @@ void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl) * misc functions */ +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; +} + /****************************************************************************** * DbgPrint [NTDLL.@] */ NTSTATUS WINAPIV DbgPrint(LPCSTR fmt, ...) { - char buf[512]; - __ms_va_list args; + NTSTATUS ret; + __ms_va_list args; - __ms_va_start(args, fmt); - _vsnprintf(buf, sizeof(buf), fmt, args); - __ms_va_end(args); - - MESSAGE("DbgPrint says: %s",buf); - /* hmm, raise exception? */ - return STATUS_SUCCESS; + __ms_va_start(args, fmt); + ret = vDbgPrintEx(0, DPFLTR_ERROR_LEVEL, fmt, args); + __ms_va_end(args); + return ret; } @@ -342,18 +346,36 @@ NTSTATUS WINAPI vDbgPrintEx( ULONG id, ULONG level, LPCSTR fmt, __ms_va_list arg */ NTSTATUS WINAPI vDbgPrintExWithPrefix( LPCSTR prefix, ULONG id, ULONG level, LPCSTR fmt, __ms_va_list args ) { - char buf[1024]; + ULONG level_mask = level <= 31 ? (1 << level) : level; + SIZE_T len = strlen( prefix ); + char buf[1024], *end; - _vsnprintf(buf, sizeof(buf), fmt, args); + strcpy( buf, prefix ); + len += _vsnprintf( buf + len, sizeof(buf) - len, fmt, args ); + end = buf + len - 1; - switch (level & DPFLTR_MASK) + WARN_(debugstr)(*end == '\n' ? "%08x:%08x: %s" : "%08x:%08x: %s\n", id, level_mask, buf); + + if (level_mask & (1 << DPFLTR_ERROR_LEVEL) && NtCurrentTeb()->Peb->BeingDebugged) { - case DPFLTR_ERROR_LEVEL: ERR("%s%x: %s", prefix, id, buf); break; - case DPFLTR_WARNING_LEVEL: WARN("%s%x: %s", prefix, id, buf); break; - case DPFLTR_TRACE_LEVEL: - case DPFLTR_INFO_LEVEL: - default: TRACE("%s%x: %s", prefix, id, buf); break; + __TRY + { + EXCEPTION_RECORD record; + record.ExceptionCode = DBG_PRINTEXCEPTION_C; + record.ExceptionFlags = 0; + record.ExceptionRecord = NULL; + record.ExceptionAddress = RtlRaiseException; + record.NumberParameters = 2; + record.ExceptionInformation[1] = (ULONG_PTR)buf; + record.ExceptionInformation[0] = strlen( buf ) + 1; + RtlRaiseException( &record ); + } + __EXCEPT(debug_exception_handler) + { + } + __ENDTRY } + return STATUS_SUCCESS; } diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 6121dc9f9d0..ae8170f41fe 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -3541,19 +3541,19 @@ static void test_DbgPrint(void) test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER; status = DbgPrint( "test_DbgPrint: %s", "Hello World" ); ok( !status, "DbgPrint returned %x\n", status ); - todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); + ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); test_dbg_print_except = FALSE; test_dbg_print_except_ret = (LONG)EXCEPTION_CONTINUE_EXECUTION; status = DbgPrint( "test_DbgPrint: %s", "Hello World" ); ok( !status, "DbgPrint returned %x\n", status ); - todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); + ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); test_dbg_print_except = FALSE; test_dbg_print_except_ret = (LONG)EXCEPTION_CONTINUE_SEARCH; status = DbgPrint( "test_DbgPrint: %s", "Hello World" ); ok( !status, "DbgPrint returned %x\n", status ); - todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); + ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); /* FIXME: NtSetDebugFilterState / DbgSetDebugFilterState are probably what's controlling these */ @@ -3562,7 +3562,7 @@ static void test_DbgPrint(void) test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER; status = DbgPrintEx( 0, DPFLTR_ERROR_LEVEL, "test_DbgPrint: %s", "Hello World" ); ok( !status, "DbgPrintEx returned %x\n", status ); - todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); + ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); test_dbg_print_except = FALSE; test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER; @@ -3574,7 +3574,7 @@ static void test_DbgPrint(void) test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER; status = DbgPrintEx( 0, DPFLTR_MASK|(1 << DPFLTR_ERROR_LEVEL), "test_DbgPrint: %s", "Hello World" ); ok( !status, "DbgPrintEx returned %x\n", status ); - todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); + ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); test_dbg_print_except = FALSE; test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER; @@ -3587,13 +3587,13 @@ static void test_DbgPrint(void) test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER; status = test_vDbgPrintEx( 0, 0xFFFFFFFF, "test_DbgPrint: %s", "Hello World" ); ok( !status, "vDbgPrintEx returned %x\n", status ); - todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); + ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); test_dbg_print_except = FALSE; test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER; status = test_vDbgPrintExWithPrefix( "test_", 0, 0xFFFFFFFF, "DbgPrint: %s", "Hello World" ); ok( !status, "vDbgPrintExWithPrefix returned %x\n", status ); - todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); + ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" ); Peb->BeingDebugged = debugged; RtlRemoveVectoredExceptionHandler( handler );