diff --git a/README.md b/README.md index ee2757a1..f1cdfe78 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Current patches include: * Implement an Arial replacement font (http://bugs.winehq.org/show_bug.cgi?id=32323) * Workaround for TransactNamedPipe not being supported (http://bugs.winehq.org/show_bug.cgi?id=17273) * Avoid unloading modules while hook is still active (http://bugs.winehq.org/show_bug.cgi?id=22091) +* Add missing DBG_PRINTEXCEPTION_C exception in OutputDebugStringA (http://bugs.winehq.org/show_bug.cgi?id=35646) * XEMBED support for embedding Wine windows inside Linux applications * Reduced SetTimer minimum value from 15 ms to 5 ms (improves Silverlight framerates) * Lockfree algorithm for filedescriptor cache (improves file access speed) diff --git a/patches/14-OutputDebugStringA/0001-kernel32-Raise-DBG_PRINTEXCEPTION_C-exception-in-Out.patch b/patches/14-OutputDebugStringA/0001-kernel32-Raise-DBG_PRINTEXCEPTION_C-exception-in-Out.patch new file mode 100644 index 00000000..254708e5 --- /dev/null +++ b/patches/14-OutputDebugStringA/0001-kernel32-Raise-DBG_PRINTEXCEPTION_C-exception-in-Out.patch @@ -0,0 +1,146 @@ +From 3ca3809fc3df18f7e8fb6911f8b0b552f28b2ddb Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 14 Jun 2014 09:39:24 +0200 +Subject: kernel32: Raise DBG_PRINTEXCEPTION_C exception in + OutputDebugStringA. + +--- + dlls/kernel32/debugger.c | 21 +++++++++++++++++++++ + dlls/ntdll/tests/exception.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + include/ntstatus.h | 1 + + include/winnt.h | 1 + + 4 files changed, 65 insertions(+) + +diff --git a/dlls/kernel32/debugger.c b/dlls/kernel32/debugger.c +index 5300fb5..d2edfaa 100644 +--- a/dlls/kernel32/debugger.c ++++ b/dlls/kernel32/debugger.c +@@ -28,6 +28,7 @@ + #include "wine/server.h" + #include "kernel_private.h" + #include "wine/debug.h" ++#include "wine/exception.h" + + WINE_DEFAULT_DEBUG_CHANNEL(debugstr); + +@@ -227,6 +228,11 @@ BOOL WINAPI DebugActiveProcessStop( DWORD pid ) + 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.@) +@@ -248,7 +254,22 @@ void WINAPI OutputDebugStringA( LPCSTR str ) + + if (!str) str = ""; + ++ /* raise fake exception to make copy protections happy */ ++ __TRY ++ { ++ ULONG_PTR args[2]; ++ args[0] = (ULONG_PTR)(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 */ ++ /* FIXME should only send to debugger if exception is not catched by user-mode application */ ++ + SERVER_START_REQ( output_debug_string ) + { + req->string = wine_server_client_ptr( str ); +diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c +index 8a80928..2009363 100644 +--- a/dlls/ntdll/tests/exception.c ++++ b/dlls/ntdll/tests/exception.c +@@ -1572,6 +1572,46 @@ static void test_dynamic_unwind(void) + + #endif /* __x86_64__ */ + ++static DWORD outputdebugstring_exceptions; ++ ++static LONG CALLBACK outputdebugstring_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo) ++{ ++ PCONTEXT context = ExceptionInfo->ContextRecord; ++ 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) + { + HMODULE hntdll = GetModuleHandleA("ntdll.dll"); +@@ -1675,5 +1715,7 @@ START_TEST(exception) + + #endif + ++ test_outputdebugstring(); ++ + VirtualFree(code_mem, 0, MEM_FREE); + } +diff --git a/include/ntstatus.h b/include/ntstatus.h +index 1eaae2d..9a7ca7a 100644 +--- a/include/ntstatus.h ++++ b/include/ntstatus.h +@@ -1211,6 +1211,7 @@ + #define DBG_TERMINATE_THREAD ((NTSTATUS) 0x40010003) + #define DBG_TERMINATE_PROCESS ((NTSTATUS) 0x40010004) + #define DBG_CONTROL_C ((NTSTATUS) 0x40010005) ++#define DBG_PRINTEXCEPTION_C ((NTSTATUS) 0x40010006) + #define DBG_CONTROL_BREAK ((NTSTATUS) 0x40010008) + #define DBG_COMMAND_EXCEPTION ((NTSTATUS) 0x40010009) + #define DBG_EXCEPTION_NOT_HANDLED ((NTSTATUS) 0x80010001) +diff --git a/include/winnt.h b/include/winnt.h +index 280cba0..e9e330d 100644 +--- a/include/winnt.h ++++ b/include/winnt.h +@@ -622,6 +622,7 @@ typedef DWORD FLONG; + #define DBG_TERMINATE_THREAD ((DWORD) 0x40010003) + #define DBG_TERMINATE_PROCESS ((DWORD) 0x40010004) + #define DBG_CONTROL_C ((DWORD) 0x40010005) ++#define DBG_PRINTEXCEPTION_C ((DWORD) 0x40010006) + #define DBG_CONTROL_BREAK ((DWORD) 0x40010008) + #define DBG_COMMAND_EXCEPTION ((DWORD) 0x40010009) + #define DBG_EXCEPTION_NOT_HANDLED ((DWORD) 0x80010001) +-- +1.7.9.5 + diff --git a/patches/14-OutputDebugStringA/d85bf5ee-3578-4edd-be3e-35cacd53e5cc.def b/patches/14-OutputDebugStringA/d85bf5ee-3578-4edd-be3e-35cacd53e5cc.def new file mode 100644 index 00000000..8baf456a --- /dev/null +++ b/patches/14-OutputDebugStringA/d85bf5ee-3578-4edd-be3e-35cacd53e5cc.def @@ -0,0 +1,3 @@ +Revision: 1 +Author: Sebastian Lackner +Title: Raise DBG_PRINTEXCEPTION_C exception in OutputDebugStringA. diff --git a/patches/patch-list.patch b/patches/patch-list.patch index 088d0383..fd607e30 100644 --- a/patches/patch-list.patch +++ b/patches/patch-list.patch @@ -6,7 +6,7 @@ diff --git a/libs/wine/config.c b/libs/wine/config.c index a273502..5fa0cd5 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c -@@ -478,6 +478,44 @@ const char *wine_get_version(void) +@@ -478,6 +478,45 @@ const char *wine_get_version(void) return PACKAGE_VERSION; } @@ -29,6 +29,7 @@ index a273502..5fa0cd5 100644 + { "3d7c4774-9e7f-11e3-9cfc-0090f5c75ad5:1", "Erich E. Hoover", "Implement missing fonts expected by Silverlight." }, + { "e7581ed7-12b3-4ed3-835b-5a62afbf9c85:4", "Sebastian Lackner", "Use lockfree implementation for get_cached_fd." }, + { "3405aa34-f341-11e3-83ce-0090f5c75ad5:1", "Erich E. Hoover", "Add default security descriptor ownership and DACLs for processes." }, ++ { "d85bf5ee-3578-4edd-be3e-35cacd53e5cc:1", "Sebastian Lackner", "Raise DBG_PRINTEXCEPTION_C exception in OutputDebugStringA." }, + { "0b21d7ac-0387-4493-aa38-fbafe3e749f5:2", "Michael Müller", "Decrease minimum SetTimer interval to 5 ms." }, + { "2394843e-2bc4-4fa4-8368-1ef32093b89e:1", "Michael Müller", "Allow changing strict draw ordering through an exported function." }, + { "255473fa-4e0a-4f51-952b-4deecc1a2181:1", "Michael Müller", "Indicate direct rendering through OpenGL extension." },