Sebastian Lackner : xaudio2: Use assembly wrapper to call OnVoiceProcessingPassStart callback.

Alexandre Julliard julliard at winehq.org
Sun Mar 3 13:21:29 CST 2019


Module: wine
Branch: oldstable
Commit: afb233e448c8f011ed066c8fd4bcd34d87303d71
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=afb233e448c8f011ed066c8fd4bcd34d87303d71

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Thu Nov  1 10:32:38 2018 -0500

xaudio2: Use assembly wrapper to call OnVoiceProcessingPassStart callback.

During a callback function, some games use the wrong function
signature for an xaudio2 function, which changed between xaudio2
versions.  As a result, the EDI and ESI registers are overwritten by
the game.  Apparently Windows's implementation happens not to use
these registers in a way that causes the crash.

This patch pushes EDI and ESI onto the stack before calling the
callback, then pops them back after the callback exits.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42520
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43358
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit c649ec3a02a7574578180e1228dacb6f3a511c55)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/xaudio2_7/xaudio_dll.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/dlls/xaudio2_7/xaudio_dll.c b/dlls/xaudio2_7/xaudio_dll.c
index bc5cf1c..5f126a3 100644
--- a/dlls/xaudio2_7/xaudio_dll.c
+++ b/dlls/xaudio2_7/xaudio_dll.c
@@ -17,6 +17,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
 #include <stdarg.h>
 
 #define NONAMELESSUNION
@@ -50,6 +51,37 @@ static HINSTANCE instance;
 #define COMPAT_E_DEVICE_INVALIDATED XAUDIO2_E_DEVICE_INVALIDATED
 #endif
 
+#if XAUDIO2_VER != 0 && defined(__i386__)
+/* EVE Online uses an OnVoiceProcessingPassStart callback which corrupts %esi. */
+#define IXAudio2VoiceCallback_OnVoiceProcessingPassStart(a, b) call_on_voice_processing_pass_start(a, b)
+extern void call_on_voice_processing_pass_start(IXAudio2VoiceCallback *This, UINT32 BytesRequired);
+__ASM_GLOBAL_FUNC( call_on_voice_processing_pass_start,
+                   "pushl %ebp\n\t"
+                   __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+                   __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+                   "movl %esp,%ebp\n\t"
+                   __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+                   "pushl %esi\n\t"
+                  __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
+                   "pushl %edi\n\t"
+                  __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
+                   "subl $8,%esp\n\t"
+                   "pushl 12(%ebp)\n\t"     /* BytesRequired */
+                   "pushl 8(%ebp)\n\t"      /* This */
+                   "movl 8(%ebp),%eax\n\t"
+                   "movl 0(%eax),%eax\n\t"
+                   "call *0(%eax)\n\t"      /* This->lpVtbl->OnVoiceProcessingPassStart */
+                   "leal -8(%ebp),%esp\n\t"
+                   "popl %edi\n\t"
+                   __ASM_CFI(".cfi_same_value %edi\n\t")
+                   "popl %esi\n\t"
+                   __ASM_CFI(".cfi_same_value %esi\n\t")
+                   "popl %ebp\n\t"
+                   __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+                   __ASM_CFI(".cfi_same_value %ebp\n\t")
+                   "ret" )
+#endif
+
 static void dump_fmt(const WAVEFORMATEX *fmt)
 {
     TRACE("wFormatTag: 0x%x (", fmt->wFormatTag);




More information about the wine-cvs mailing list