[Bug 42520] Multiple Wargaming.net games crash on startup in Win7+ mode ( XAudio 2.7 'IXAudio2SourceVoice::GetState' called with 'Flags' parameter, causing register corruption) (World of {Tanks, Warships})
wine-bugs at winehq.org
wine-bugs at winehq.org
Fri Oct 12 06:45:29 CDT 2018
https://bugs.winehq.org/show_bug.cgi?id=42520
Anastasius Focht <focht at gmx.net> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |focht at gmx.net
Summary|World of Tanks: crash on |Multiple Wargaming.net
|startup in win7 mode (works |games crash on startup in
|in winxp) |Win7+ mode (XAudio 2.7
| |'IXAudio2SourceVoice::GetSt
| |ate' called with 'Flags'
| |parameter, causing register
| |corruption) (World of
| |{Tanks, Warships})
--- Comment #17 from Anastasius Focht <focht at gmx.net> ---
Hello folks,
refining summary to collect more dupes here.
Trace with some additional diagnostics added:
--- snip ---
$ pwd
/home/focht/wine-games/wineprefix64-wargaming/drive_c/Games/World_of_Warships
$ WINEDEBUG=+seh,+loaddll,+xaudio2 wine ./WorldOfWarships.exe >>log.txt 2>&1
...
0074:trace:loaddll:load_builtin_dll Loaded
L"C:\\windows\\system32\\xaudio2_7.dll" at 0xf59e0000: builtin
0074:trace:xaudio2:DllMain (0xf59e0000, 8, (nil))
0074:trace:xaudio2:DllMain (0xf59e0000, 1, (nil))
0074:trace:xaudio2:DllGetClassObject ({5a508685-a254-4fba-9b82-9a24b00306af},
{00000001-0000-0000-c000-000000000046}, 0x214ff23c)
0074:trace:xaudio2:XAudio2CF_AddRef (0x22797418)->(): Refcount now 1
0074:trace:xaudio2:XAudio2CF_CreateInstance
(0x22797418)->((nil),{8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb},0x214ff238)
0074:trace:xaudio2:IXAudio2Impl_QueryInterface
(0x3c42f2a8)->({8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb}, 0x214ff238)
0074:trace:xaudio2:IXAudio2Impl_AddRef (0x3c42f2a8)->(): Refcount now 1
0074:trace:xaudio2:IXAudio2Impl_StartEngine (0x3c42f2a8)->()
0074:trace:xaudio2:XAudio2CF_CreateInstance Created XAudio version 27:
0x3c42f2a8
0074:trace:xaudio2:XAudio2CF_Release (0x22797418)->(): Refcount now 0
0074:trace:xaudio2:XA27_Initialize (0x3c42f2a8)->(0x0, 0x1)
0074:trace:xaudio2:XA27_CreateMasteringVoice (0x3c42f2a8)->(0x1f9e2d44, 0,
48000, 0x0, 0, (nil))
0074:trace:xaudio2:IXAudio2Impl_CreateMasteringVoice (0x3c42f2a8)->(0x1f9e2d44,
0, 48000, 0x0, L"{0.0.0.00000000}.{FD47D9CC-4218-4135-9CE2-0C195C87405B}",
(nil), 0x6)
0074:trace:xaudio2:XA27_GetDeviceDetails 0x3c42f2a8, 0, 0x214feed4
0074:trace:xaudio2:IXAudio2Impl_CreateSourceVoice (0x3c42f2a8)->(0x1f9e2d48,
0x214ffb18, 0x0, 1.000000, 0x1f9e2d30, (nil), (nil))
0074:trace:xaudio2:dump_fmt wFormatTag: 0xfffe (WAVE_FORMAT_EXTENSIBLE)
0074:trace:xaudio2:dump_fmt nChannels: 2
0074:trace:xaudio2:dump_fmt nSamplesPerSec: 48000
0074:trace:xaudio2:dump_fmt nAvgBytesPerSec: 384000
0074:trace:xaudio2:dump_fmt nBlockAlign: 8
0074:trace:xaudio2:dump_fmt wBitsPerSample: 32
0074:trace:xaudio2:dump_fmt cbSize: 22
0074:trace:xaudio2:dump_fmt dwChannelMask: 00000003
0074:trace:xaudio2:dump_fmt Samples: 0020
0074:trace:xaudio2:dump_fmt SubFormat: {00000003-0000-0010-8000-00aa00389b71}
0074:trace:xaudio2:XA2SRC_SetOutputVoices 0x3c432b60, (nil)
0074:trace:xaudio2:XA2SRC_SetOutputVoices Outputting to: 0x0, 0x3c42f2ac
0074:trace:xaudio2:IXAudio2Impl_CreateSourceVoice Created source voice:
0x3c432b60
0074:trace:xaudio2:XA2SRC_SetVolume 0x3c432b60, 1.000000, 0x0
0074:trace:xaudio2:IXAudio2Impl_RegisterForCallbacks (0x3c42f2a8)->(0x1f9e2d2c)
0074:trace:xaudio2:XA2SRC_Start 0x3c432b60, 0x0, 0x0
...
007c:trace:xaudio2:do_engine_tick frames available: 1440
007c:trace:xaudio2:do_engine_tick *** (1) src=0x3c432b60, src->cb=0x1f9e2d30,
src->al_src=0x1
007c:trace:xaudio2:do_engine_tick Calling OnVoiceProcessingPassStart with
BytesRequired: 19200
007c:trace:xaudio2:XA2SRC_GetState 0x3c432b60, 0x595efe48, 0x0
007c:trace:xaudio2:XA2SRC_GetState returning 0, queued: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer 0x3c432b60, 0x595efe24, (nil)
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer Flags: 0x0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer AudioBytes: 8192
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer pAudioData: 0x1f9e4da0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer PlayBegin: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer PlayLength: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopBegin: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopLength: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopCount: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer pContext: (nil)
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer 0x3c432b60: queued buffer 0 (8192
bytes), now 1 buffers held
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer 0x3c432b60, 0x595efe24, (nil)
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer Flags: 0x0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer AudioBytes: 8192
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer pAudioData: 0x1f9e6da0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer PlayBegin: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer PlayLength: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopBegin: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopLength: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopCount: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer pContext: (nil)
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer 0x3c432b60: queued buffer 1 (8192
bytes), now 2 buffers held
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer 0x3c432b60, 0x595efe24, (nil)
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer Flags: 0x0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer AudioBytes: 8192
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer pAudioData: 0x1f9e8da0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer PlayBegin: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer PlayLength: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopBegin: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopLength: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopCount: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer pContext: (nil)
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer 0x3c432b60: queued buffer 2 (8192
bytes), now 3 buffers held
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer 0x3c432b60, 0x595efe24, (nil)
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer Flags: 0x0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer AudioBytes: 8192
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer pAudioData: 0x1f9eada0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer PlayBegin: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer PlayLength: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopBegin: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopLength: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer LoopCount: 0
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer pContext: (nil)
007c:trace:xaudio2:XA2SRC_SubmitSourceBuffer 0x3c432b60: queued buffer 3 (8192
bytes), now 4 buffers held
007c:trace:xaudio2:do_engine_tick *** (2) src=(nil)
007c:trace:seh:raise_exception code=c0000005 flags=0 addr=0xf59ef795
ip=f59ef795 tid=007c
007c:trace:seh:raise_exception info[0]=00000000
007c:trace:seh:raise_exception info[1]=00000f70
007c:trace:seh:raise_exception eax=595efd48 ebx=f59ff000 ecx=00000000
edx=595f2b38 esi=f59ff000 edi=00000000
007c:trace:seh:raise_exception ebp=595efe68 esp=595efd14 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00010202
007c:trace:seh:call_stack_handlers calling handler at 0x7bca5470 code=c0000005
flags=0
--- snip ---
Wargaming client 'IXAudio2VoiceCallback::OnVoiceProcessingPassStart' callback
calls at one point 'IXAudio2SourceVoice::GetState' method but with the Flags(!)
parameter passed -> XAudio 2.8+ ABI! Wine implements the old-style XAudio 2.7
ABI and uses binary compatibility interface/method wrappers.
The client's incorrect XAudio 2.7 ABI usage causes one of the callee saved regs
getting corrupted. It's not causing a stack imbalance on return due to the way
the function prolog code is setting up the stack but it causes NULL pointer
exception in the caller (local var -> register).
Disassembly of World of Warships 0.7.x client
'XAudio2VoiceCallback::OnVoiceProcessingPassStart' callback:
--- snip ---
00A32DF0 55 PUSH EBP
00A32DF1 8BEC MOV EBP,ESP
00A32DF3 83EC 34 SUB ESP,34
00A32DF6 53 PUSH EBX
00A32DF7 56 PUSH ESI
00A32DF8 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
00A32DFB 8D55 F0 LEA EDX,DWORD PTR SS:[EBP-10]
00A32DFE 57 PUSH EDI ; caller local 'src' reg val
00A32DFF 6A 00 PUSH 0 ; flags -> problem!
00A32E01 52 PUSH EDX ; pVoiceState
00A32E02 8B46 18 MOV EAX,DWORD PTR DS:[ESI+18]
00A32E05 50 PUSH EAX ; iface
00A32E06 8B08 MOV ECX,DWORD PTR DS:[EAX]
; xaudio2_.XA27SRC_GetState -> compat wrapper!
00A32E08 FF51 64 CALL DWORD PTR DS:[ECX+64]
00A32E0B 0FB74E 48 MOVZX ECX,WORD PTR DS:[ESI+48]
00A32E0F 33D2 XOR EDX,EDX
00A32E11 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]
00A32E14 33FF XOR EDI,EDI
00A32E16 F7F1 DIV ECX
00A32E18 8B4E 44 MOV ECX,DWORD PTR DS:[ESI+44]
00A32E1B 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
00A32E1E 8BD8 MOV EBX,EAX
00A32E20 2BCA SUB ECX,EDX
00A32E22 74 66 JE SHORT WorldOfW.00A32E8A
00A32E24 0FB74E 48 MOVZX ECX,WORD PTR DS:[ESI+48]
00A32E28 33C0 XOR EAX,EAX
00A32E2A 8945 D4 MOV DWORD PTR SS:[EBP-2C],EAX
00A32E2D 8945 CC MOV DWORD PTR SS:[EBP-34],EAX
00A32E30 8945 D8 MOV DWORD PTR SS:[EBP-28],EAX
00A32E33 8945 DC MOV DWORD PTR SS:[EBP-24],EAX
00A32E36 8945 E0 MOV DWORD PTR SS:[EBP-20],EAX
00A32E39 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
00A32E3C 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
00A32E3F 8945 EC MOV DWORD PTR SS:[EBP-14],EAX
00A32E42 0FB705 24165D01 MOVZX EAX,WORD PTR DS:[15D1624]
00A32E49 0FAFC8 IMUL ECX,EAX
00A32E4C 894D D0 MOV DWORD PTR SS:[EBP-30],ECX
00A32E4F 0FB74E 22 MOVZX ECX,WORD PTR DS:[ESI+22]
00A32E53 8B448E 24 MOV EAX,DWORD PTR DS:[ESI+ECX*4+24]
00A32E57 8945 D4 MOV DWORD PTR SS:[EBP-2C],EAX
00A32E5A 8D41 01 LEA EAX,DWORD PTR DS:[ECX+1]
00A32E5D 66:8946 22 MOV WORD PTR DS:[ESI+22],AX
00A32E61 66:83F8 08 CMP AX,8
00A32E65 75 06 JNZ SHORT WorldOfW.00A32E6D
00A32E67 33C0 XOR EAX,EAX
00A32E69 66:8946 22 MOV WORD PTR DS:[ESI+22],AX
00A32E6D 8B46 18 MOV EAX,DWORD PTR DS:[ESI+18]
00A32E70 8D55 CC LEA EDX,DWORD PTR SS:[EBP-34]
00A32E73 6A 00 PUSH 0
00A32E75 52 PUSH EDX
00A32E76 50 PUSH EAX
00A32E77 8B08 MOV ECX,DWORD PTR DS:[EAX]
; xaudio2_.XA27SRC_SubmitSourceBuffer
00A32E79 FF51 54 CALL DWORD PTR DS:[ECX+54]
00A32E7C FF45 F4 INC DWORD PTR SS:[EBP-C]
00A32E7F 47 INC EDI
00A32E80 8B46 44 MOV EAX,DWORD PTR DS:[ESI+44]
00A32E83 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
00A32E86 2BC2 SUB EAX,EDX
00A32E88 75 9A JNZ SHORT WorldOfW.00A32E24
00A32E8A 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00A32E8D 0B45 FC OR EAX,DWORD PTR SS:[EBP-4]
00A32E90 74 12 JE SHORT WorldOfW.00A32EA4
00A32E92 0FB705 24165D01 MOVZX EAX,WORD PTR DS:[15D1624]
00A32E99 0FAFC7 IMUL EAX,EDI
00A32E9C 3BC3 CMP EAX,EBX
00A32E9E 73 04 JNB SHORT WorldOfW.00A32EA4
00A32EA0 C646 4A 01 MOV BYTE PTR DS:[ESI+4A],1
00A32EA4 0FB705 90146B01 MOVZX EAX,WORD PTR DS:[16B1490]
00A32EAB 5F POP EDI ; caller EDI -> NULL
00A32EAC 5E POP ESI
00A32EAD 5B POP EBX
00A32EAE 3BD0 CMP EDX,EAX
00A32EB0 73 0E JNB SHORT WorldOfW.00A32EC0
00A32EB2 8B0D 64126B01 MOV ECX,DWORD PTR DS:[16B1264]
00A32EB8 8D49 4C LEA ECX,DWORD PTR DS:[ECX+4C]
00A32EBB E8 1049F8FF CALL WorldOfW.009B77D0
00A32EC0 8BE5 MOV ESP,EBP
00A32EC2 5D POP EBP
00A32EC3 C2 0800 RETN 8
--- snip ---
The Wargaming clients load the XAudio2 variant depending on the Windows
version:
--- snip ---
00A32C30 PUSH EBP
00A32C31 MOV EBP,ESP
00A32C33 SUB ESP,11C
00A32C39 PUSH ESI
00A32C3A PUSH 100
00A32C3F LEA EAX,DWORD PTR SS:[EBP-108]
00A32C45 MOV DWORD PTR SS:[EBP-11C],11C
00A32C4F PUSH 0
00A32C51 PUSH EAX
00A32C52 MOV DWORD PTR SS:[EBP-118],0
00A32C5C MOV DWORD PTR SS:[EBP-114],0
00A32C66 MOV DWORD PTR SS:[EBP-110],0
00A32C70 MOV DWORD PTR SS:[EBP-10C],0
00A32C7A CALL <JMP.&VCRUNTIME140.memset>
00A32C7F MOV ESI,DWORD PTR DS:[<&KERNEL32.VerSetConditionMask>]
00A32C85 ADD ESP,0C
00A32C88 XOR EAX,EAX
00A32C8A MOV DWORD PTR SS:[EBP-8],EAX
00A32C8D MOV DWORD PTR SS:[EBP-4],EAX
00A32C90 PUSH 3
00A32C92 PUSH 20
00A32C94 PUSH 3
00A32C96 PUSH 1
00A32C98 PUSH 3
00A32C9A PUSH 2
00A32C9C PUSH EAX
00A32C9D PUSH EAX
00A32C9E CALL ESI
00A32CA0 PUSH EDX
00A32CA1 PUSH EAX
00A32CA2 CALL ESI
00A32CA4 PUSH EDX
00A32CA5 PUSH EAX
00A32CA6 CALL ESI
00A32CA8 MOVZX ECX,WORD PTR SS:[EBP+8]
00A32CAC PUSH EDX
00A32CAD MOV DWORD PTR SS:[EBP-118],ECX
00A32CB3 MOVZX ECX,WORD PTR SS:[EBP+C]
00A32CB7 PUSH EAX
00A32CB8 MOV DWORD PTR SS:[EBP-114],ECX
00A32CBE LEA EAX,DWORD PTR SS:[EBP-11C]
00A32CC4 MOV CX,WORD PTR SS:[EBP+10]
00A32CC8 PUSH 23
00A32CCA PUSH EAX
00A32CCB MOV WORD PTR SS:[EBP-8],CX
00A32CCF CALL DWORD PTR DS:[<&KERNEL32.VerifyVersionInfoW>]
00A32CD5 NEG EAX
00A32CD7 POP ESI
00A32CD8 SBB EAX,EAX
00A32CDA NEG EAX
00A32CDC MOV ESP,EBP
00A32CDE POP EBP
00A32CDF RETN
00A32CE0 PUSH EBP
00A32CE1 MOV EBP,ESP
00A32CE3 PUSH ECX
00A32CE4 PUSH ESI
00A32CE5 PUSH 0
00A32CE7 PUSH 0
00A32CE9 PUSH 0A
00A32CEB MOV DWORD PTR SS:[EBP-4],0
00A32CF2 MOV DWORD PTR DS:[16B275C],0
00A32CFC CALL WorldOfW.00A32C30
00A32D01 MOV ESI,DWORD PTR DS:[<&KERNEL32.LoadLibraryA>]
00A32D07 ADD ESP,0C
00A32D0A TEST AL,AL
00A32D0C JE SHORT WorldOfW.00A32D24
00A32D0E PUSH WorldOfW.011CDF30 ; ASCII "XAudio2_9.dll"
00A32D13 CALL ESI
00A32D15 MOV DWORD PTR SS:[EBP-4],EAX
00A32D18 MOV DWORD PTR DS:[16B275C],3
00A32D22 JMP SHORT WorldOfW.00A32D27
00A32D24 MOV EAX,DWORD PTR SS:[EBP-4]
00A32D27 TEST EAX,EAX
00A32D29 JNZ SHORT WorldOfW.00A32DA5
00A32D2B PUSH EAX
00A32D2C PUSH 2
00A32D2E PUSH 6
00A32D30 CALL WorldOfW.00A32C30
00A32D35 ADD ESP,0C
00A32D38 TEST AL,AL
00A32D3A JE SHORT WorldOfW.00A32D52
00A32D3C PUSH WorldOfW.011CDF40 ; ASCII "XAudio2_8.dll"
00A32D41 CALL ESI
00A32D43 MOV DWORD PTR SS:[EBP-4],EAX
00A32D46 MOV DWORD PTR DS:[16B275C],2
00A32D50 JMP SHORT WorldOfW.00A32D55
00A32D52 MOV EAX,DWORD PTR SS:[EBP-4]
00A32D55 TEST EAX,EAX
00A32D57 JNZ SHORT WorldOfW.00A32DA5
00A32D59 PUSH EAX
00A32D5A PUSH 1
00A32D5C PUSH 6
00A32D5E CALL WorldOfW.00A32C30
00A32D63 ADD ESP,0C
00A32D66 TEST AL,AL
00A32D68 JE SHORT WorldOfW.00A32DA2
00A32D6A PUSH WorldOfW.011CDF50 ; ASCII "XAudio2_7.dll"
00A32D6F CALL ESI
00A32D71 CMP BYTE PTR DS:[16B276C],0
00A32D78 MOV DWORD PTR SS:[EBP-4],EAX
00A32D7B MOV DWORD PTR DS:[16B275C],1
00A32D85 JNZ SHORT WorldOfW.00A32DA5
00A32D87 LEA EAX,DWORD PTR SS:[EBP-4]
00A32D8A PUSH EAX
00A32D8B PUSH WorldOfW.011CDF50 ; ASCII "XAudio2_7.dll"
00A32D90 PUSH 1
00A32D92 CALL DWORD PTR DS:[<&KERNEL32.GetModuleHandleExA>]
00A32D98 CMP EAX,1
00A32D9B SETE BYTE PTR DS:[16B276C]
00A32DA2 MOV EAX,DWORD PTR SS:[EBP-4]
00A32DA5 POP ESI
00A32DA6 MOV ESP,EBP
00A32DA8 POP EBP
00A32DA9 RETN
--- snip---
Wine source:
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/xaudio2_7/xaudio_dll.c#l2400
--- snip ---
2400 static void do_engine_tick(IXAudio2Impl *This)
2401 {
2402 BYTE *buf;
2403 XA2SourceImpl *src;
2404 HRESULT hr;
2405 UINT32 nframes, i, pad;
2406
2407 /* maintain up to 3 periods in mmdevapi */
2408 hr = IAudioClient_GetCurrentPadding(This->aclient, &pad);
2409 if(FAILED(hr)){
2410 WARN("GetCurrentPadding failed: 0x%x\n", hr);
2411 return;
2412 }
2413
2414 nframes = This->period_frames * 3 - pad;
2415
2416 TRACE("frames available: %u\n", nframes);
2417
2418 if(nframes < This->period_frames)
2419 return;
2420
2421 if(!nframes)
2422 return;
2423
2424 for(i = 0; i < This->ncbs && This->cbs[i]; ++i)
2425 IXAudio2EngineCallback_OnProcessingPassStart(This->cbs[i]);
2426
2427 LIST_FOR_EACH_ENTRY(src, &This->source_voices, XA2SourceImpl, entry){
2428 ALint st = 0;
2429
2430 EnterCriticalSection(&src->lock);
2431
2432 if(!src->in_use){
2433 LeaveCriticalSection(&src->lock);
2434 continue;
2435 }
2436
2437 if(src->cb && This->running){
2438 #if XAUDIO2_VER == 0
2439
IXAudio20VoiceCallback_OnVoiceProcessingPassStart((IXAudio20VoiceCallback*)src->cb);
2440 #else
2441 UINT32 underrun;
2442 underrun = get_underrun_warning(src);
2443 if(underrun > 0)
2444 TRACE("Calling OnVoiceProcessingPassStart with
BytesRequired: %u\n", underrun);
2445 IXAudio2VoiceCallback_OnVoiceProcessingPassStart(src->cb,
underrun);
2446 #endif
2447 }
2448
2449 update_source_state(src);
--- snip ---
'src' is held in EDI register within loop and gets wrong value (NULL) restored
from client provided 'OnVoiceProcessingPassStart' callback due to ABI/compat
mismatch -> line 2449 -> src == NULL.
The compat wrapper (called by callback):
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/xaudio2_7/compat.c#l839
--- snip ---
839 static void WINAPI XA27SRC_GetState(IXAudio27SourceVoice *iface,
840 XAUDIO2_VOICE_STATE *pVoiceState)
841 {
842 XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface);
843 return IXAudio2SourceVoice_GetState(&This->IXAudio2SourceVoice_iface,
pVoiceState, 0);
844 }
--- snip ---
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/xaudio2_7/xaudio_dll.c#l743
--- snip ---
743 static void WINAPI XA2SRC_GetState(IXAudio2SourceVoice *iface,
744 XAUDIO2_VOICE_STATE *pVoiceState, UINT32 Flags)
745 {
746 XA2SourceImpl *This = impl_from_IXAudio2SourceVoice(iface);
747
748 TRACE("%p, %p, 0x%x\n", This, pVoiceState, Flags);
749
750 EnterCriticalSection(&This->lock);
751
752 if(!(Flags & XAUDIO2_VOICE_NOSAMPLESPLAYED))
753 pVoiceState->SamplesPlayed = This->played_frames;
754 else
755 pVoiceState->SamplesPlayed = 0;
756
757 if(This->nbufs)
758 pVoiceState->pCurrentBufferContext =
This->buffers[This->first_buf].xa2buffer.pContext;
759 else
760 pVoiceState->pCurrentBufferContext = NULL;
761
762 pVoiceState->BuffersQueued = This->nbufs;
763
764 LeaveCriticalSection(&This->lock);
765
766 TRACE("returning %s, queued: %u\n",
wine_dbgstr_longlong(pVoiceState->SamplesPlayed), This->nbufs);
767 }
--- snip ---
Microsoft docs:
https://docs.microsoft.com/en-us/windows/desktop/api/xaudio2/nf-xaudio2-ixaudio2sourcevoice-getstate
--- quote ---
IXAudio2SourceVoice::GetState method
Returns the voice's current cursor position data.
Syntax
void GetState(
XAUDIO2_VOICE_STATE *pVoiceState,
UINT32 Flags X2DEFAULT
);
Parameters
pVoiceState
Pointer to an XAUDIO2_VOICE_STATE structure containing the state of the voice.
X2DEFAULT
TBD
Return Value
This method does not return a value.
Remarks
If a client needs to get the correlated positions of several voices (for
example, to know exactly which sample of a given voice is playing when a given
sample of another voice is playing), it must make GetState calls in an XAudio2
engine callback. This ensures that none of the voices advance while the calls
are being made. See the XAudio2 Callbacks overview for information about using
XAudio2 callbacks.
Note that the DirectX SDK versions of XAUDIO2 do not take the Flags parameter
for GetState.
Platform Requirements
Windows 10 (XAudio2.9); Windows 8, Windows Phone 8 (XAudio 2.8); DirectX SDK
(XAudio 2.7)
--- quote ---
https://docs.microsoft.com/en-us/windows/desktop/xaudio2/xaudio2-versions
--- snip ---
XAudio 2.7 and earlier (Windows 7)
All previous versions of XAudio2 for use in apps have been provided as
redistributable DLLs in the DirectX SDK. The first version of XAudio2, XAudio2
2.0, shipped in the March 2008 release of the DirectX SDK. The last version to
ship in the DirectX SDK was XAudio2 2.7, available in the last release of the
DirectX SDK in June 2010.
For access to historical versions of XAudio2, download the DirectX SDK from the
Microsoft Download Center. The June 2010 release of the DirectX SDK is
available at:
http://www.microsoft.com/download/en/details.aspx?id=6812
Previous versions of XAudio2 cannot be used to build Windows Store apps for
Windows 8.
--- snip ---
The vendor Wargaming messed this up, calling the DirectX SDK XAudio 2.7 version
of 'IXAudio2SourceVoice::GetState' with the Flags parameter included from the
callback. I havent seen different callback implementations, depending on the
XAudio 2.x version .. but I didn't look very hard.
It just works by chance with native (SDK) XAudio 2.7 because EDI isn't used by
caller(s), corrupting it in callback has no effect.
IMHO 'INVALID' or 'WONTFIX' unless you want to write an assembly wrapper for
invoking the callbacks to fix these broken apps/games.
$ wine --version
wine-3.17-162-gb0c5a77e26
Regards
--
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.
More information about the wine-bugs
mailing list