Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com
-- v3: xactengine3_7: Return error on invalid notification value. xactengine3_7: Implement callback for supported messages xactengine3_7: Record context for each notications xactengine3_7: Map IXACT3Wave interfaces xactengine3_7: Map IXACT3Cue interfaces xactengine3_7: Map SoundBank interfaces xactengine3_7: Add helper function to add entries
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/xactengine3_7/xact_dll.c | 97 +++++++++++++++++------------------ 1 file changed, 47 insertions(+), 50 deletions(-)
diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c index ee559dd4b07..9c85197f261 100644 --- a/dlls/xactengine3_7/xact_dll.c +++ b/dlls/xactengine3_7/xact_dll.c @@ -71,8 +71,8 @@ typedef struct _XACT3EngineImpl {
void *wb_prepared_context; void *wb_destroyed_context; - struct wine_rb_tree wb_wrapper_lookup; - CRITICAL_SECTION wb_wrapper_lookup_cs; + struct wine_rb_tree wrapper_lookup; + CRITICAL_SECTION wrapper_lookup_cs; } XACT3EngineImpl;
static int wrapper_lookup_compare(const void *key, const struct wine_rb_entry *entry) @@ -94,26 +94,53 @@ static void wrapper_remove_entry(XACT3EngineImpl *engine, void *key) struct wrapper_lookup *lookup; struct wine_rb_entry *entry;
- EnterCriticalSection(&engine->wb_wrapper_lookup_cs); + EnterCriticalSection(&engine->wrapper_lookup_cs);
- entry = wine_rb_get(&engine->wb_wrapper_lookup, key); + entry = wine_rb_get(&engine->wrapper_lookup, key); if (!entry) { - LeaveCriticalSection(&engine->wb_wrapper_lookup_cs); + LeaveCriticalSection(&engine->wrapper_lookup_cs);
WARN("cannot find key in wrapper lookup\n"); } else { - wine_rb_remove(&engine->wb_wrapper_lookup, entry); + wine_rb_remove(&engine->wrapper_lookup, entry);
- LeaveCriticalSection(&engine->wb_wrapper_lookup_cs); + LeaveCriticalSection(&engine->wrapper_lookup_cs);
lookup = WINE_RB_ENTRY_VALUE(entry, struct wrapper_lookup, entry); HeapFree(GetProcessHeap(), 0, lookup); } }
+static HRESULT wrapper_add_entry(XACT3EngineImpl *engine, void *fact, void *xact) +{ + struct wrapper_lookup *lookup; + UINT ret; + + lookup = HeapAlloc(GetProcessHeap(), 0, sizeof(*lookup)); + if (!lookup) + { + ERR("Failed to allocate wrapper_lookup!\n"); + return E_OUTOFMEMORY; + } + lookup->fact = fact; + lookup->xact = xact; + + EnterCriticalSection(&engine->wrapper_lookup_cs); + ret = wine_rb_put(&engine->wrapper_lookup, lookup->fact, &lookup->entry); + LeaveCriticalSection(&engine->wrapper_lookup_cs); + + if (ret) + { + WARN("wrapper_lookup already present in the tree??\n"); + HeapFree(GetProcessHeap(), 0, lookup); + } + + return S_OK; +} + typedef struct _XACT3CueImpl { IXACT3Cue IXACT3Cue_iface; FACTCue *fact_cue; @@ -849,8 +876,8 @@ static ULONG WINAPI IXACT3EngineImpl_Release(IXACT3Engine *iface)
if (!ref) { - DeleteCriticalSection(&This->wb_wrapper_lookup_cs); - wine_rb_destroy(&This->wb_wrapper_lookup, wrapper_lookup_destroy, NULL); + DeleteCriticalSection(&This->wrapper_lookup_cs); + wine_rb_destroy(&This->wrapper_lookup, wrapper_lookup_destroy, NULL); HeapFree(GetProcessHeap(), 0, This); } return ref; @@ -945,8 +972,8 @@ static void FACTCALL fact_notification_cb(const FACTNotification *notification) if (notification->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED || notification->type == XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED) { - EnterCriticalSection(&engine->wb_wrapper_lookup_cs); - entry = wine_rb_get(&engine->wb_wrapper_lookup, notification->waveBank.pWaveBank); + EnterCriticalSection(&engine->wrapper_lookup_cs); + entry = wine_rb_get(&engine->wrapper_lookup, notification->waveBank.pWaveBank); if (!entry) { WARN("cannot find wave bank in wrapper lookup\n"); @@ -957,7 +984,7 @@ static void FACTCALL fact_notification_cb(const FACTNotification *notification) lookup = WINE_RB_ENTRY_VALUE(entry, struct wrapper_lookup, entry); xnotification.waveBank.pWaveBank = lookup->xact; } - LeaveCriticalSection(&engine->wb_wrapper_lookup_cs); + LeaveCriticalSection(&engine->wrapper_lookup_cs); if (notification->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED) xnotification.pvContext = engine->wb_prepared_context; else @@ -1095,9 +1122,9 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine *ifac DWORD dwAllocAttributes, IXACT3WaveBank **ppWaveBank) { XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); - struct wrapper_lookup *lookup; XACT3WaveBankImpl *wb; FACTWaveBank *fwb; + HRESULT hr; UINT ret;
TRACE("(%p)->(%p, %lu, 0x%lx, 0x%lx, %p)\n", This, pvBuffer, dwSize, dwFlags, @@ -1119,28 +1146,13 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine *ifac return E_OUTOFMEMORY; }
- lookup = HeapAlloc(GetProcessHeap(), 0, sizeof(*lookup)); - if (!lookup) + hr = wrapper_add_entry(This, fwb, &wb->IXACT3WaveBank_iface); + if (FAILED(hr)) { FACTWaveBank_Destroy(fwb); HeapFree(GetProcessHeap(), 0, wb); - ERR("Failed to allocate wrapper_lookup!\n"); return E_OUTOFMEMORY; } - lookup->fact = fwb; - lookup->xact = &wb->IXACT3WaveBank_iface; - - EnterCriticalSection(&This->wb_wrapper_lookup_cs); - - ret = wine_rb_put(&This->wb_wrapper_lookup, lookup->fact, &lookup->entry); - - LeaveCriticalSection(&This->wb_wrapper_lookup_cs); - - if (ret) - { - WARN("wrapper_lookup already present in the tree??\n"); - HeapFree(GetProcessHeap(), 0, lookup); - }
wb->IXACT3WaveBank_iface.lpVtbl = &XACT3WaveBank_Vtbl; wb->fact_wavebank = fwb; @@ -1158,11 +1170,11 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine *ifa { XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); FACTStreamingParameters fakeParms; - struct wrapper_lookup *lookup; wrap_readfile_struct *fake; XACT3WaveBankImpl *wb; FACTWaveBank *fwb; UINT ret; + HRESULT hr;
TRACE("(%p)->(%p, %p)\n", This, pParms, ppWaveBank);
@@ -1192,28 +1204,13 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine *ifa return E_OUTOFMEMORY; }
- lookup = HeapAlloc(GetProcessHeap(), 0, sizeof(*lookup)); - if (!lookup) + hr = wrapper_add_entry(This, fwb, &wb->IXACT3WaveBank_iface); + if (FAILED(hr)) { FACTWaveBank_Destroy(fwb); HeapFree(GetProcessHeap(), 0, wb); - ERR("Failed to allocate wrapper_lookup!\n"); return E_OUTOFMEMORY; } - lookup->fact = fwb; - lookup->xact = &wb->IXACT3WaveBank_iface; - - EnterCriticalSection(&This->wb_wrapper_lookup_cs); - - ret = wine_rb_put(&This->wb_wrapper_lookup, lookup->fact, &lookup->entry); - - LeaveCriticalSection(&This->wb_wrapper_lookup_cs); - - if (ret) - { - WARN("wrapper_lookup already present in the tree??\n"); - HeapFree(GetProcessHeap(), 0, lookup); - }
wb->IXACT3WaveBank_iface.lpVtbl = &XACT3WaveBank_Vtbl; wb->fact_wavebank = fwb; @@ -1618,8 +1615,8 @@ static HRESULT WINAPI XACT3CF_CreateInstance(IClassFactory *iface, IUnknown *pOu return hr; }
- wine_rb_init(&object->wb_wrapper_lookup, wrapper_lookup_compare); - InitializeCriticalSection(&object->wb_wrapper_lookup_cs); + wine_rb_init(&object->wrapper_lookup, wrapper_lookup_compare); + InitializeCriticalSection(&object->wrapper_lookup_cs);
return hr; }
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/xactengine3_7/xact_dll.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c index 9c85197f261..1b55f0ebc89 100644 --- a/dlls/xactengine3_7/xact_dll.c +++ b/dlls/xactengine3_7/xact_dll.c @@ -346,6 +346,7 @@ typedef struct _XACT3SoundBankImpl { IXACT3SoundBank IXACT3SoundBank_iface;
FACTSoundBank *fact_soundbank; + XACT3EngineImpl *engine; } XACT3SoundBankImpl;
static inline XACT3SoundBankImpl *impl_from_IXACT3SoundBank(IXACT3SoundBank *iface) @@ -482,6 +483,8 @@ static HRESULT WINAPI IXACT3SoundBankImpl_Destroy(IXACT3SoundBank *iface) TRACE("(%p)\n", This);
hr = FACTSoundBank_Destroy(This->fact_soundbank); + + wrapper_remove_entry(This->engine, This->fact_soundbank); HeapFree(GetProcessHeap(), 0, This); return hr; } @@ -1088,6 +1091,7 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateSoundBank(IXACT3Engine *iface, XACT3SoundBankImpl *sb; FACTSoundBank *fsb; UINT ret; + HRESULT hr;
TRACE("(%p)->(%p, %lu, 0x%lx, 0x%lx, %p): stub!\n", This, pvBuffer, dwSize, dwFlags, dwAllocAttributes, ppSoundBank); @@ -1108,8 +1112,17 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateSoundBank(IXACT3Engine *iface, return E_OUTOFMEMORY; }
+ hr = wrapper_add_entry(This, fsb, &sb->IXACT3SoundBank_iface); + if (FAILED(hr)) + { + FACTSoundBank_Destroy(fsb); + HeapFree(GetProcessHeap(), 0, sb); + return E_OUTOFMEMORY; + } + sb->IXACT3SoundBank_iface.lpVtbl = &XACT3SoundBank_Vtbl; sb->fact_soundbank = fsb; + sb->engine = This; *ppSoundBank = &sb->IXACT3SoundBank_iface;
TRACE("Created SoundBank: %p\n", sb);
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/xactengine3_7/xact_dll.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c index 1b55f0ebc89..d1d0ef6917f 100644 --- a/dlls/xactengine3_7/xact_dll.c +++ b/dlls/xactengine3_7/xact_dll.c @@ -144,6 +144,7 @@ static HRESULT wrapper_add_entry(XACT3EngineImpl *engine, void *fact, void *xact typedef struct _XACT3CueImpl { IXACT3Cue IXACT3Cue_iface; FACTCue *fact_cue; + XACT3EngineImpl *engine; } XACT3CueImpl;
static inline XACT3CueImpl *impl_from_IXACT3Cue(IXACT3Cue *iface) @@ -188,6 +189,7 @@ static HRESULT WINAPI IXACT3CueImpl_Destroy(IXACT3Cue *iface) ret = FACTCue_Destroy(This->fact_cue); if (ret != 0) WARN("FACTCue_Destroy returned %d\n", ret); + wrapper_remove_entry(This->engine, This->fact_cue); HeapFree(GetProcessHeap(), 0, This); return S_OK; } @@ -395,6 +397,7 @@ static HRESULT WINAPI IXACT3SoundBankImpl_Prepare(IXACT3SoundBank *iface, XACT3CueImpl *cue; FACTCue *fcue; UINT ret; + HRESULT hr;
TRACE("(%p)->(%u, 0x%lx, %lu, %p)\n", This, nCueIndex, dwFlags, timeOffset, ppCue); @@ -415,8 +418,17 @@ static HRESULT WINAPI IXACT3SoundBankImpl_Prepare(IXACT3SoundBank *iface, return E_OUTOFMEMORY; }
+ hr = wrapper_add_entry(This->engine, fcue, &cue->IXACT3Cue_iface); + if (FAILED(hr)) + { + FACTCue_Destroy(fcue); + HeapFree(GetProcessHeap(), 0, cue); + return E_OUTOFMEMORY; + } + cue->IXACT3Cue_iface.lpVtbl = &XACT3Cue_Vtbl; cue->fact_cue = fcue; + cue->engine = This->engine; *ppCue = &cue->IXACT3Cue_iface;
TRACE("Created Cue: %p\n", cue); @@ -457,8 +469,17 @@ static HRESULT WINAPI IXACT3SoundBankImpl_Play(IXACT3SoundBank *iface, return E_OUTOFMEMORY; }
+ hr = wrapper_add_entry(This->engine, fcue, &cue->IXACT3Cue_iface); + if (FAILED(hr)) + { + FACTCue_Destroy(fcue); + HeapFree(GetProcessHeap(), 0, cue); + return E_OUTOFMEMORY; + } + cue->IXACT3Cue_iface.lpVtbl = &XACT3Cue_Vtbl; cue->fact_cue = fcue; + cue->engine = This->engine; *ppCue = &cue->IXACT3Cue_iface; }
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/xactengine3_7/xact_dll.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c index d1d0ef6917f..002c8860864 100644 --- a/dlls/xactengine3_7/xact_dll.c +++ b/dlls/xactengine3_7/xact_dll.c @@ -540,6 +540,7 @@ typedef struct _XACT3WaveImpl { IXACT3Wave IXACT3Wave_iface;
FACTWave *fact_wave; + XACT3EngineImpl *engine; } XACT3WaveImpl;
static inline XACT3WaveImpl *impl_from_IXACT3Wave(IXACT3Wave *iface) @@ -555,6 +556,7 @@ static HRESULT WINAPI IXACT3WaveImpl_Destroy(IXACT3Wave *iface) TRACE("(%p)\n", This);
hr = FACTWave_Destroy(This->fact_wave); + wrapper_remove_entry(This->engine, This->fact_wave); HeapFree(GetProcessHeap(), 0, This); return hr; } @@ -720,6 +722,7 @@ static HRESULT WINAPI IXACT3WaveBankImpl_Prepare(IXACT3WaveBank *iface, XACT3WaveImpl *wave; FACTWave *fwave; UINT ret; + HRESULT hr;
TRACE("(%p)->(0x%x, %lu, 0x%lx, %u, %p)\n", This, nWaveIndex, dwFlags, dwPlayOffset, nLoopCount, ppWave); @@ -740,8 +743,17 @@ static HRESULT WINAPI IXACT3WaveBankImpl_Prepare(IXACT3WaveBank *iface, return E_OUTOFMEMORY; }
+ hr = wrapper_add_entry(This->engine, fwave, &wave->IXACT3Wave_iface); + if (FAILED(hr)) + { + FACTWave_Destroy(fwave); + HeapFree(GetProcessHeap(), 0, wave); + return E_OUTOFMEMORY; + } + wave->IXACT3Wave_iface.lpVtbl = &XACT3Wave_Vtbl; wave->fact_wave = fwave; + wave->engine = This->engine; *ppWave = &wave->IXACT3Wave_iface;
TRACE("Created Wave: %p\n", wave); @@ -782,8 +794,17 @@ static HRESULT WINAPI IXACT3WaveBankImpl_Play(IXACT3WaveBank *iface, return E_OUTOFMEMORY; }
+ hr = wrapper_add_entry(This->engine, fwave, &wave->IXACT3Wave_iface); + if (FAILED(hr)) + { + FACTWave_Destroy(fwave); + HeapFree(GetProcessHeap(), 0, wave); + return E_OUTOFMEMORY; + } + wave->IXACT3Wave_iface.lpVtbl = &XACT3Wave_Vtbl; wave->fact_wave = fwave; + wave->engine = This->engine; *ppWave = &wave->IXACT3Wave_iface; }
@@ -1288,6 +1309,7 @@ static HRESULT WINAPI IXACT3EngineImpl_PrepareWave(IXACT3Engine *iface, XACT3WaveImpl *wave; FACTWave *fwave = NULL; UINT ret; + HRESULT hr;
TRACE("(%p)->(0x%08lx, %s, %d, %ld, %ld, %d, %p)\n", This, dwFlags, debugstr_a(szWavePath), wStreamingPacketSize, dwAlignment, dwPlayOffset, nLoopCount, ppWave); @@ -1307,8 +1329,17 @@ static HRESULT WINAPI IXACT3EngineImpl_PrepareWave(IXACT3Engine *iface, return E_OUTOFMEMORY; }
+ hr = wrapper_add_entry(This, fwave, &wave->IXACT3Wave_iface); + if (FAILED(hr)) + { + FACTWave_Destroy(fwave); + HeapFree(GetProcessHeap(), 0, wave); + return E_OUTOFMEMORY; + } + wave->IXACT3Wave_iface.lpVtbl = &XACT3Wave_Vtbl; wave->fact_wave = fwave; + wave->engine = This; *ppWave = &wave->IXACT3Wave_iface;
TRACE("Created Wave: %p\n", wave);
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
This helps the first lockup but starting a game causes another freeze.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49678
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/xactengine3_7/xact_dll.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c index 002c8860864..82c7957c9a3 100644 --- a/dlls/xactengine3_7/xact_dll.c +++ b/dlls/xactengine3_7/xact_dll.c @@ -53,6 +53,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(xact3); #define IXACT3WaveBankVtbl IXACTWaveBankVtbl #endif
+#define XACTNOTIFICATIONTYPE_MAX 18 /* XACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT + 1 */ + struct wrapper_lookup { struct wine_rb_entry entry; @@ -69,8 +71,7 @@ typedef struct _XACT3EngineImpl { XACT_GETOVERLAPPEDRESULT_CALLBACK pGetOverlappedResult; XACT_NOTIFICATION_CALLBACK notification_callback;
- void *wb_prepared_context; - void *wb_destroyed_context; + void *contexts[XACTNOTIFICATIONTYPE_MAX]; struct wine_rb_tree wrapper_lookup; CRITICAL_SECTION wrapper_lookup_cs; } XACT3EngineImpl; @@ -1013,6 +1014,7 @@ static void FACTCALL fact_notification_cb(const FACTNotification *notification)
xnotification.type = xact_notification_type_from_fact(notification->type); xnotification.timeStamp = notification->timeStamp; + xnotification.pvContext = engine->contexts[notification->type];
if (notification->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED || notification->type == XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED) @@ -1030,10 +1032,6 @@ static void FACTCALL fact_notification_cb(const FACTNotification *notification) xnotification.waveBank.pWaveBank = lookup->xact; } LeaveCriticalSection(&engine->wrapper_lookup_cs); - if (notification->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED) - xnotification.pvContext = engine->wb_prepared_context; - else - xnotification.pvContext = engine->wb_destroyed_context; } else { @@ -1482,12 +1480,8 @@ static HRESULT WINAPI IXACT3EngineImpl_RegisterNotification(IXACT3Engine *iface,
TRACE("(%p)->(%p)\n", This, pNotificationDesc);
- if (pNotificationDesc->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED) - This->wb_prepared_context = pNotificationDesc->pvContext; - else if (pNotificationDesc->type == XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED) - This->wb_destroyed_context = pNotificationDesc->pvContext; - unwrap_notificationdesc(&fdesc, pNotificationDesc); + This->contexts[pNotificationDesc->type] = pNotificationDesc->pvContext; fdesc.pvContext = This; return FACTAudioEngine_RegisterNotification(This->fact_engine, &fdesc); }
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- dlls/xactengine3_7/xact_dll.c | 69 +++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 16 deletions(-)
diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c index 82c7957c9a3..fa54409560e 100644 --- a/dlls/xactengine3_7/xact_dll.c +++ b/dlls/xactengine3_7/xact_dll.c @@ -142,6 +142,23 @@ static HRESULT wrapper_add_entry(XACT3EngineImpl *engine, void *fact, void *xact return S_OK; }
+/* Must be protected by engine->wrapper_lookup_cs */ +static void* wrapper_find_entry(XACT3EngineImpl *engine, void *faudio) +{ + struct wrapper_lookup *lookup; + struct wine_rb_entry *entry; + + entry = wine_rb_get(&engine->wrapper_lookup, faudio); + if (entry) + { + lookup = WINE_RB_ENTRY_VALUE(entry, struct wrapper_lookup, entry); + return lookup->xact; + } + + WARN("cannot find interface in wrapper lookup\n"); + return NULL; +} + typedef struct _XACT3CueImpl { IXACT3Cue IXACT3Cue_iface; FACTCue *fact_cue; @@ -1000,10 +1017,8 @@ static void FACTCALL fact_notification_cb(const FACTNotification *notification) { XACT3EngineImpl *engine = (XACT3EngineImpl *)notification->pvContext; XACT_NOTIFICATION xnotification; - struct wrapper_lookup *lookup; - struct wine_rb_entry *entry;
- TRACE("notification %p\n", notification->pvContext); + TRACE("notification %d, context %p\n", notification->type, notification->pvContext);
/* Older versions of FAudio don't pass through the context */ if (!engine) @@ -1016,28 +1031,50 @@ static void FACTCALL fact_notification_cb(const FACTNotification *notification) xnotification.timeStamp = notification->timeStamp; xnotification.pvContext = engine->contexts[notification->type];
+ EnterCriticalSection(&engine->wrapper_lookup_cs); if (notification->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED || notification->type == XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED) { - EnterCriticalSection(&engine->wrapper_lookup_cs); - entry = wine_rb_get(&engine->wrapper_lookup, notification->waveBank.pWaveBank); - if (!entry) - { - WARN("cannot find wave bank in wrapper lookup\n"); - xnotification.waveBank.pWaveBank = NULL; - } - else - { - lookup = WINE_RB_ENTRY_VALUE(entry, struct wrapper_lookup, entry); - xnotification.waveBank.pWaveBank = lookup->xact; - } - LeaveCriticalSection(&engine->wrapper_lookup_cs); + xnotification.waveBank.pWaveBank = wrapper_find_entry(engine, notification->waveBank.pWaveBank); + } + else if(notification->type == XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED) + { + xnotification.soundBank.pSoundBank = wrapper_find_entry(engine, notification->soundBank.pSoundBank); + } + else if (notification->type == XACTNOTIFICATIONTYPE_WAVESTOP +#if XACT3_VER >= 0x0205 + || notification->type == XACTNOTIFICATIONTYPE_WAVEDESTROYED + || notification->type == XACTNOTIFICATIONTYPE_WAVELOOPED + || notification->type == XACTNOTIFICATIONTYPE_WAVEPLAY + || notification->type == XACTNOTIFICATIONTYPE_WAVEPREPARED) +#else + ) +#endif + { + xnotification.wave.cueIndex = notification->wave.cueIndex; + xnotification.wave.pCue = wrapper_find_entry(engine, notification->wave.pCue); + xnotification.wave.pSoundBank = wrapper_find_entry(engine, notification->wave.pSoundBank); +#if XACT3_VER >= 0x0205 + xnotification.wave.pWave = wrapper_find_entry(engine, notification->wave.pWave); +#endif + xnotification.wave.pWaveBank = wrapper_find_entry(engine, notification->wave.pWaveBank); + } + else if (notification->type == XACTNOTIFICATIONTYPE_CUEPLAY || + notification->type == XACTNOTIFICATIONTYPE_CUEPREPARED || + notification->type == XACTNOTIFICATIONTYPE_CUESTOP || + notification->type == XACTNOTIFICATIONTYPE_CUEDESTROYED) + { + xnotification.cue.pCue = wrapper_find_entry(engine, notification->cue.pCue); + xnotification.cue.cueIndex = notification->cue.cueIndex; + xnotification.cue.pSoundBank = wrapper_find_entry(engine, notification->cue.pSoundBank); } else { + LeaveCriticalSection(&engine->wrapper_lookup_cs); FIXME("Unsupported callback type %d\n", notification->type); return; } + LeaveCriticalSection(&engine->wrapper_lookup_cs);
engine->notification_callback(&xnotification); }
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/xactengine3_7/tests/xact3.c | 18 ++++++++++++++++++ dlls/xactengine3_7/xact_dll.c | 8 ++++++++ 2 files changed, 26 insertions(+)
diff --git a/dlls/xactengine3_7/tests/xact3.c b/dlls/xactengine3_7/tests/xact3.c index 6b66af59ff0..3d268fcc33c 100644 --- a/dlls/xactengine3_7/tests/xact3.c +++ b/dlls/xactengine3_7/tests/xact3.c @@ -208,6 +208,24 @@ static void test_notifications(void) hr = IXACT3Engine_Initialize(engine, ¶ms); ok(hr == S_OK, "Cannot initialize engine, hr %#lx\n", hr);
+ notification_desc.type = 0; + notification_desc.flags = 0; + notification_desc.pvContext = &prepared_data; + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + + notification_desc.type = 0; + notification_desc.flags = 0; + notification_desc.pvContext = &prepared_data; + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + prepared_data.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED; prepared_data.thread_id = GetCurrentThreadId(); notification_desc.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED; diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c index fa54409560e..07c58d76a5a 100644 --- a/dlls/xactengine3_7/xact_dll.c +++ b/dlls/xactengine3_7/xact_dll.c @@ -1517,6 +1517,10 @@ static HRESULT WINAPI IXACT3EngineImpl_RegisterNotification(IXACT3Engine *iface,
TRACE("(%p)->(%p)\n", This, pNotificationDesc);
+ if (pNotificationDesc->type < XACTNOTIFICATIONTYPE_CUEPREPARED || + pNotificationDesc->type > XACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT) + return E_INVALIDARG; + unwrap_notificationdesc(&fdesc, pNotificationDesc); This->contexts[pNotificationDesc->type] = pNotificationDesc->pvContext; fdesc.pvContext = This; @@ -1531,6 +1535,10 @@ static HRESULT WINAPI IXACT3EngineImpl_UnRegisterNotification(IXACT3Engine *ifac
TRACE("(%p)->(%p)\n", This, pNotificationDesc);
+ if (pNotificationDesc->type < XACTNOTIFICATIONTYPE_CUEPREPARED || + pNotificationDesc->type > XACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT) + return E_INVALIDARG; + unwrap_notificationdesc(&fdesc, pNotificationDesc); fdesc.pvContext = This; return FACTAudioEngine_UnRegisterNotification(This->fact_engine, &fdesc);
Giovanni Mascellani (@giomasce) commented about dlls/xactengine3_7/xact_dll.c:
return E_OUTOFMEMORY; }
- lookup = HeapAlloc(GetProcessHeap(), 0, sizeof(*lookup));
- if (!lookup)
- hr = wrapper_add_entry(This, fwb, &wb->IXACT3WaveBank_iface);
- if (FAILED(hr)) { FACTWaveBank_Destroy(fwb); HeapFree(GetProcessHeap(), 0, wb);
ERR("Failed to allocate wrapper_lookup!\n"); return E_OUTOFMEMORY;
It makes sense to return hr here, maybe?
Giovanni Mascellani (@giomasce) commented about dlls/xactengine3_7/xact_dll.c:
return E_OUTOFMEMORY; }
- lookup = HeapAlloc(GetProcessHeap(), 0, sizeof(*lookup));
- if (!lookup)
- hr = wrapper_add_entry(This, fwb, &wb->IXACT3WaveBank_iface);
- if (FAILED(hr)) { FACTWaveBank_Destroy(fwb); HeapFree(GetProcessHeap(), 0, wb);
ERR("Failed to allocate wrapper_lookup!\n"); return E_OUTOFMEMORY;
It makes sense to return hr here, maybe?
On Tue Aug 2 09:58:36 2022 +0000, Giovanni Mascellani wrote:
It makes sense to return hr here, maybe?
(the same gadget also appear in later patches)
Giovanni Mascellani (@giomasce) commented about dlls/xactengine3_7/tests/xact3.c:
- notification_desc.flags = 0;
- notification_desc.pvContext = &prepared_data;
- hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc);
- ok(hr == E_INVALIDARG, "got hr %#lx\n", hr);
- hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc);
- ok(hr == E_INVALIDARG, "got hr %#lx\n", hr);
- notification_desc.type = 0;
- notification_desc.flags = 0;
- notification_desc.pvContext = &prepared_data;
- hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc);
- ok(hr == E_INVALIDARG, "got hr %#lx\n", hr);
- hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc);
- ok(hr == E_INVALIDARG, "got hr %#lx\n", hr);
Isn't this the same call just repeated four times? I don't get what it is useful for (beside the first time).
As I said, it would be nice to have more extensive testing for the various event types, but this MR is definitely an improvement over what is currently in Wine.