[PATCH 1/3] dsound: Prevent reopening device from leaving dsound object in invalid state
Andrew Eikum
aeikum at codeweavers.com
Tue May 17 13:40:33 CDT 2016
From: Maarten Lankhorst <wine at mblankhorst.nl>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
dlls/dsound/dsound.c | 49 +++----
dlls/dsound/dsound_private.h | 3 -
dlls/dsound/primary.c | 333 ++++++++++++++++++++-----------------------
3 files changed, 175 insertions(+), 210 deletions(-)
diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c
index 0b5c3b4..195da0b 100644
--- a/dlls/dsound/dsound.c
+++ b/dlls/dsound/dsound.c
@@ -161,24 +161,20 @@ static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice)
device->guid = GUID_NULL;
/* Set default wave format (may need it for waveOutOpen) */
- device->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEXTENSIBLE));
device->primary_pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEXTENSIBLE));
- if (!device->pwfx || !device->primary_pwfx) {
+ if (!device->primary_pwfx) {
WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,device->primary_pwfx);
- HeapFree(GetProcessHeap(),0,device->pwfx);
HeapFree(GetProcessHeap(),0,device);
return DSERR_OUTOFMEMORY;
}
- device->pwfx->wFormatTag = WAVE_FORMAT_PCM;
- device->pwfx->nSamplesPerSec = 22050;
- device->pwfx->wBitsPerSample = 8;
- device->pwfx->nChannels = 2;
- device->pwfx->nBlockAlign = device->pwfx->wBitsPerSample * device->pwfx->nChannels / 8;
- device->pwfx->nAvgBytesPerSec = device->pwfx->nSamplesPerSec * device->pwfx->nBlockAlign;
- device->pwfx->cbSize = 0;
- memcpy(device->primary_pwfx, device->pwfx, sizeof(*device->pwfx));
+ device->primary_pwfx->wFormatTag = WAVE_FORMAT_PCM;
+ device->primary_pwfx->nSamplesPerSec = 22050;
+ device->primary_pwfx->wBitsPerSample = 8;
+ device->primary_pwfx->nChannels = 2;
+ device->primary_pwfx->nBlockAlign = device->primary_pwfx->wBitsPerSample * device->primary_pwfx->nChannels / 8;
+ device->primary_pwfx->nAvgBytesPerSec = device->primary_pwfx->nSamplesPerSec * device->primary_pwfx->nBlockAlign;
+ device->primary_pwfx->cbSize = 0;
InitializeCriticalSection(&(device->mixlock));
device->mixlock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DirectSoundDevice.mixlock");
@@ -228,12 +224,12 @@ static ULONG DirectSoundDevice_Release(DirectSoundDevice * device)
if (hr != DS_OK)
WARN("DSOUND_PrimaryDestroy failed\n");
- if(device->client)
+ if(device->client) {
+ IAudioClient_Stop(device->client);
IAudioClient_Release(device->client);
+ }
if(device->render)
IAudioRenderClient_Release(device->render);
- if(device->clock)
- IAudioClock_Release(device->clock);
if(device->volume)
IAudioStreamVolume_Release(device->volume);
@@ -323,6 +319,7 @@ static HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGU
device->mmdevice = mmdevice;
device->guid = devGUID;
device->sleepev = CreateEventW(0, 0, 0, 0);
+ device->buflen = ds_hel_buflen;
hr = DSOUND_ReopenDevice(device, FALSE);
if (FAILED(hr))
@@ -381,13 +378,9 @@ static HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGU
ZeroMemory(&device->volpan, sizeof(device->volpan));
- hr = DSOUND_PrimaryCreate(device);
- if (hr == DS_OK) {
- device->thread_finished = CreateEventW(0, 0, 0, 0);
- device->thread = CreateThread(0, 0, DSOUND_mixthread, device, 0, 0);
- SetThreadPriority(device->thread, THREAD_PRIORITY_TIME_CRITICAL);
- } else
- WARN("DSOUND_PrimaryCreate failed: %08x\n", hr);
+ device->thread_finished = CreateEventW(0, 0, 0, 0);
+ device->thread = CreateThread(0, 0, DSOUND_mixthread, device, 0, 0);
+ SetThreadPriority(device->thread, THREAD_PRIORITY_TIME_CRITICAL);
*ppDevice = device;
list_add_tail(&DSOUND_renderers, &device->entry);
@@ -851,7 +844,6 @@ static HRESULT WINAPI IDirectSound8Impl_SetCooperativeLevel(IDirectSound8 *iface
{
IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
DirectSoundDevice *device = This->device;
- DWORD oldlevel;
HRESULT hr = S_OK;
TRACE("(%p,%p,%s)\n", This, hwnd, dumpCooperativeLevel(level));
@@ -868,15 +860,10 @@ static HRESULT WINAPI IDirectSound8Impl_SetCooperativeLevel(IDirectSound8 *iface
RtlAcquireResourceExclusive(&device->buffer_list_lock, TRUE);
EnterCriticalSection(&device->mixlock);
- oldlevel = device->priolevel;
- device->priolevel = level;
- if ((level == DSSCL_WRITEPRIMARY) != (oldlevel == DSSCL_WRITEPRIMARY)) {
+ if ((level == DSSCL_WRITEPRIMARY) != (device->priolevel == DSSCL_WRITEPRIMARY))
hr = DSOUND_ReopenDevice(device, level == DSSCL_WRITEPRIMARY);
- if (FAILED(hr))
- device->priolevel = oldlevel;
- else
- DSOUND_PrimaryOpen(device);
- }
+ if (SUCCEEDED(hr))
+ device->priolevel = level;
LeaveCriticalSection(&device->mixlock);
RtlReleaseResource(&device->buffer_list_lock);
return hr;
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index 8bf9c9d..3da0c19 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -100,7 +100,6 @@ struct DirectSoundDevice
IMMDevice *mmdevice;
IAudioClient *client;
- IAudioClock *clock;
IAudioStreamVolume *volume;
IAudioRenderClient *render;
@@ -204,13 +203,11 @@ void DSOUND_ParseSpeakerConfig(DirectSoundDevice *device) DECLSPEC_HIDDEN;
/* primary.c */
-HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device) DECLSPEC_HIDDEN;
LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) DECLSPEC_HIDDEN;
-HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb,
const DSBUFFERDESC *dsbd) DECLSPEC_HIDDEN;
void primarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c
index a5fe039..72c9475 100644
--- a/dlls/dsound/primary.c
+++ b/dlls/dsound/primary.c
@@ -197,16 +197,8 @@ static HRESULT DSOUND_WaveFormat(DirectSoundDevice *device, IAudioClient *client
return S_OK;
}
-HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
+static void DSOUND_ReleaseDevice(DirectSoundDevice *device)
{
- WAVEFORMATEX *wfx = NULL;
- HRESULT hres;
- REFERENCE_TIME period, buflen = 800000;
- UINT32 frames;
- DWORD period_ms;
-
- TRACE("(%p, %d)\n", device, forcewave);
-
if(device->client){
IAudioClient_Release(device->client);
device->client = NULL;
@@ -215,10 +207,6 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
IAudioRenderClient_Release(device->render);
device->render = NULL;
}
- if(device->clock){
- IAudioClock_Release(device->clock);
- device->clock = NULL;
- }
if(device->volume){
IAudioStreamVolume_Release(device->volume);
device->volume = NULL;
@@ -229,145 +217,75 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
device->playpos %= device->buflen;
device->pad = 0;
}
-
- hres = IMMDevice_Activate(device->mmdevice, &IID_IAudioClient,
- CLSCTX_INPROC_SERVER, NULL, (void **)&device->client);
- if(FAILED(hres)) {
- WARN("Activate failed: %08x\n", hres);
- return hres;
- }
-
- device->speaker_config = DSOUND_FindSpeakerConfig(device->mmdevice, 0);
-
- DSOUND_ParseSpeakerConfig(device);
-
- hres = DSOUND_WaveFormat(device, device->client, forcewave, &wfx);
- if (FAILED(hres)) {
- IAudioClient_Release(device->client);
- device->client = NULL;
- return hres;
- }
- HeapFree(GetProcessHeap(), 0, device->pwfx);
- device->pwfx = wfx;
-
- hres = IAudioClient_Initialize(device->client,
- AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST |
- AUDCLNT_STREAMFLAGS_EVENTCALLBACK, buflen, 0, device->pwfx, NULL);
- if(FAILED(hres)){
- IAudioClient_Release(device->client);
- device->client = NULL;
- WARN("Initialize failed: %08x\n", hres);
- return hres;
- }
- IAudioClient_SetEventHandle(device->client, device->sleepev);
-
- hres = IAudioClient_GetService(device->client, &IID_IAudioRenderClient,
- (void**)&device->render);
- if(FAILED(hres)){
- IAudioClient_Release(device->client);
- device->client = NULL;
- WARN("GetService failed: %08x\n", hres);
- return hres;
- }
-
- hres = IAudioClient_GetService(device->client, &IID_IAudioClock,
- (void**)&device->clock);
- if(FAILED(hres)){
- IAudioClient_Release(device->client);
- IAudioRenderClient_Release(device->render);
- device->client = NULL;
- device->render = NULL;
- WARN("GetService failed: %08x\n", hres);
- return hres;
- }
-
- hres = IAudioClient_GetService(device->client, &IID_IAudioStreamVolume,
- (void**)&device->volume);
- if(FAILED(hres)){
- IAudioClient_Release(device->client);
- IAudioRenderClient_Release(device->render);
- IAudioClock_Release(device->clock);
- device->client = NULL;
- device->render = NULL;
- device->clock = NULL;
- WARN("GetService failed: %08x\n", hres);
- return hres;
- }
-
- /* Now kick off the timer so the event fires periodically */
- hres = IAudioClient_Start(device->client);
- if (FAILED(hres))
- WARN("starting failed with %08x\n", hres);
-
- hres = IAudioClient_GetStreamLatency(device->client, &period);
- if (FAILED(hres)) {
- WARN("GetStreamLatency failed with %08x\n", hres);
- period = 100000;
- }
- period_ms = (period + 9999) / 10000;
-
- hres = IAudioClient_GetBufferSize(device->client, &frames);
- if (FAILED(hres)) {
- WARN("GetBufferSize failed with %08x\n", hres);
- frames = (UINT64)device->pwfx->nSamplesPerSec * buflen / 10000000;
- }
-
- device->fraglen = MulDiv(device->pwfx->nSamplesPerSec, period, 10000000) * device->pwfx->nBlockAlign;
- device->aclen = frames * device->pwfx->nBlockAlign;
- TRACE("period %u ms fraglen %u buflen %u\n", period_ms, device->fraglen, device->aclen);
-
- if (period_ms < 3)
- device->sleeptime = 5;
- else
- device->sleeptime = period_ms * 5 / 2;
-
- return S_OK;
}
-HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
+static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device, WAVEFORMATEX *wfx, DWORD frames, BOOL forcewave)
{
- IDirectSoundBufferImpl** dsb = device->buffers;
- LPBYTE newbuf;
- int i;
+ IDirectSoundBufferImpl** dsb = device->buffers;
+ LPBYTE newbuf;
+ DWORD new_buflen;
+ BOOL mixfloat = FALSE;
+ int i;
- TRACE("(%p)\n", device);
+ TRACE("(%p)\n", device);
- /* on original windows, the buffer it set to a fixed size, no matter what the settings are.
- on windows this size is always fixed (tested on win-xp) */
- if (!device->buflen)
- device->buflen = ds_hel_buflen;
- device->buflen -= device->buflen % device->pwfx->nBlockAlign;
+ new_buflen = device->buflen;
+ new_buflen -= new_buflen % wfx->nBlockAlign;
- if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
- else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;
+ if (wfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
+ (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)wfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
+ mixfloat = TRUE;
/* reallocate emulated primary buffer */
- if (device->buffer)
- newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer, device->buflen);
- else
- newbuf = HeapAlloc(GetProcessHeap(),0, device->buflen);
+ if (forcewave) {
+ if (device->buffer)
+ newbuf = HeapReAlloc(GetProcessHeap(), 0, device->buffer, new_buflen);
+ else
+ newbuf = HeapAlloc(GetProcessHeap(), 0, new_buflen);
- if (!newbuf) {
- ERR("failed to allocate primary buffer\n");
- return DSERR_OUTOFMEMORY;
- /* but the old buffer might still exist and must be re-prepared */
+ if (!newbuf) {
+ ERR("failed to allocate primary buffer\n");
+ return DSERR_OUTOFMEMORY;
+ }
+ FillMemory(newbuf, new_buflen, (wfx->wBitsPerSample == 8) ? 128 : 0);
+ } else if (!mixfloat) {
+ DWORD alloc_len = frames * sizeof(float);
+
+ if (device->buffer)
+ newbuf = HeapReAlloc(GetProcessHeap(), 0, device->buffer, alloc_len);
+ else
+ newbuf = HeapAlloc(GetProcessHeap(), 0, alloc_len);
+
+ if (!newbuf) {
+ ERR("failed to allocate primary buffer\n");
+ return DSERR_OUTOFMEMORY;
+ }
+ FillMemory(newbuf, alloc_len, (wfx->wBitsPerSample == 8) ? 128 : 0);
+ } else {
+ HeapFree(GetProcessHeap(), 0, device->buffer);
+ newbuf = NULL;
}
- device->writelead = (device->pwfx->nSamplesPerSec / 100) * device->pwfx->nBlockAlign;
-
device->buffer = newbuf;
+ device->buflen = new_buflen;
+ HeapFree(GetProcessHeap(), 0, device->pwfx);
+ device->pwfx = wfx;
+
+ if (device->state == STATE_PLAYING)
+ device->state = STATE_STARTING;
+ else if (device->state == STATE_STOPPING)
+ device->state = STATE_STOPPED;
+
+ device->writelead = (wfx->nSamplesPerSec / 100) * wfx->nBlockAlign;
TRACE("buflen: %u, fraglen: %u\n", device->buflen, device->fraglen);
- if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
- (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
- IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat,
- &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
+ if (!mixfloat)
+ device->normfunction = normfunctions[wfx->wBitsPerSample/8 - 1];
+ else
device->normfunction = NULL;
- else
- device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
- FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
device->playpos = 0;
for (i = 0; i < device->nrofbuffers; i++) {
@@ -379,35 +297,105 @@ HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
return DS_OK;
}
-
-static void DSOUND_PrimaryClose(DirectSoundDevice *device)
+HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
{
- HRESULT hr;
+ HRESULT hres;
+ REFERENCE_TIME period;
+ UINT32 frames;
+ DWORD period_ms;
+ IAudioClient *client = NULL;
+ IAudioRenderClient *render = NULL;
+ IAudioStreamVolume *volume = NULL;
+ DWORD fraglen;
+ WAVEFORMATEX *wfx = NULL;
+ DWORD oldspeakerconfig = device->speaker_config;
- TRACE("(%p)\n", device);
+ TRACE("(%p, %d)\n", device, forcewave);
- if(device->client){
- hr = IAudioClient_Stop(device->client);
- if(FAILED(hr))
- WARN("Stop failed: %08x\n", hr);
+ hres = IMMDevice_Activate(device->mmdevice, &IID_IAudioClient,
+ CLSCTX_INPROC_SERVER, NULL, (void **)&client);
+ if(FAILED(hres)){
+ WARN("Activate failed: %08x\n", hres);
+ return hres;
}
-}
-HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
-{
- HRESULT err = DS_OK;
- TRACE("(%p)\n", device);
+ hres = DSOUND_WaveFormat(device, client, forcewave, &wfx);
+ if (FAILED(hres)) {
+ IAudioClient_Release(client);
+ return hres;
+ }
+
+ hres = IAudioClient_Initialize(client,
+ AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST |
+ AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 800000, 0, wfx, NULL);
+ if(FAILED(hres)){
+ IAudioClient_Release(client);
+ ERR("Initialize failed: %08x\n", hres);
+ return hres;
+ }
+
+ IAudioClient_SetEventHandle(client, device->sleepev);
+
+ hres = IAudioClient_GetService(client, &IID_IAudioRenderClient, (void**)&render);
+ if(FAILED(hres))
+ goto err_service;
+
+ hres = IAudioClient_GetService(client, &IID_IAudioStreamVolume, (void**)&volume);
+ if(FAILED(hres))
+ goto err_service;
+
+ /* Now kick off the timer so the event fires periodically */
+ hres = IAudioClient_Start(client);
+ if (FAILED(hres)) {
+ WARN("Start failed with %08x\n", hres);
+ goto err;
+ }
+ hres = IAudioClient_GetStreamLatency(client, &period);
+ if (FAILED(hres)) {
+ WARN("GetStreamLatency failed with %08x\n", hres);
+ goto err;
+ }
+ hres = IAudioClient_GetBufferSize(client, &frames);
+ if (FAILED(hres)) {
+ WARN("GetBufferSize failed with %08x\n", hres);
+ goto err;
+ }
+
+ period_ms = (period + 9999) / 10000;
+ fraglen = MulDiv(wfx->nSamplesPerSec, period, 10000000) * wfx->nBlockAlign;
+ TRACE("period %u ms fraglen %u buflen %u\n", period_ms, fraglen, frames * wfx->nBlockAlign);
+
+ hres = DSOUND_PrimaryOpen(device, wfx, frames, forcewave);
+ if(FAILED(hres))
+ goto err;
+
+ DSOUND_ReleaseDevice(device);
+ device->client = client;
+ device->render = render;
+ device->volume = volume;
+ device->fraglen = fraglen;
+ device->aclen = frames * wfx->nBlockAlign;
- device->buflen = ds_hel_buflen;
- err = DSOUND_PrimaryOpen(device);
+ if (period_ms < 3)
+ device->sleeptime = 5;
+ else
+ device->sleeptime = period_ms * 5 / 2;
- if (err != DS_OK) {
- WARN("DSOUND_PrimaryOpen failed\n");
- return err;
- }
+ return S_OK;
- device->state = STATE_STOPPED;
- return DS_OK;
+err_service:
+ ERR("GetService failed: %08x\n", hres);
+err:
+ device->speaker_config = oldspeakerconfig;
+ DSOUND_ParseSpeakerConfig(device);
+ if (volume)
+ IAudioStreamVolume_Release(volume);
+ if (render)
+ IAudioRenderClient_Release(render);
+ if (client)
+ IAudioClient_Release(client);
+ HeapFree(GetProcessHeap(), 0, wfx);
+ return hres;
}
HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
@@ -417,8 +405,6 @@ HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
/* **** */
EnterCriticalSection(&(device->mixlock));
- DSOUND_PrimaryClose(device);
-
if(device->primary && (device->primary->ref || device->primary->numIfaces))
WARN("Destroying primary buffer while references held (%u %u)\n", device->primary->ref, device->primary->numIfaces);
@@ -470,10 +456,14 @@ WAVEFORMATEX *DSOUND_CopyFormat(const WAVEFORMATEX *wfex)
WAVEFORMATEX *pwfx;
if(wfex->wFormatTag == WAVE_FORMAT_PCM){
pwfx = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEFORMATEX));
+ if (!pwfx)
+ return NULL;
CopyMemory(pwfx, wfex, sizeof(PCMWAVEFORMAT));
pwfx->cbSize = 0;
}else{
pwfx = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEFORMATEX) + wfex->cbSize);
+ if (!pwfx)
+ return NULL;
CopyMemory(pwfx, wfex, sizeof(WAVEFORMATEX) + wfex->cbSize);
}
@@ -490,7 +480,6 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
HRESULT err = S_OK;
WAVEFORMATEX *old_fmt;
WAVEFORMATEXTENSIBLE *fmtex, *passed_fmtex = (WAVEFORMATEXTENSIBLE*)passed_fmt;
- BOOL forced = (device->priolevel == DSSCL_WRITEPRIMARY);
TRACE("(%p,%p)\n", device, passed_fmt);
@@ -540,28 +529,20 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
fmtex->Samples.wValidBitsPerSample = fmtex->Format.wBitsPerSample;
}
- DSOUND_PrimaryClose(device);
-
- err = DSOUND_ReopenDevice(device, forced);
+ err = DSOUND_ReopenDevice(device, TRUE);
if (FAILED(err)) {
ERR("No formats could be opened\n");
- goto done;
- }
-
- err = DSOUND_PrimaryOpen(device);
- if (err != DS_OK) {
- ERR("DSOUND_PrimaryOpen failed\n");
- goto done;
- }
-
-done:
- if (err != DS_OK)
+ HeapFree(GetProcessHeap(), 0, device->primary_pwfx);
device->primary_pwfx = old_fmt;
- else
+ } else
HeapFree(GetProcessHeap(), 0, old_fmt);
} else {
- HeapFree(GetProcessHeap(), 0, device->primary_pwfx);
- device->primary_pwfx = DSOUND_CopyFormat(passed_fmt);
+ WAVEFORMATEX *wfx = DSOUND_CopyFormat(passed_fmt);
+ if (wfx) {
+ HeapFree(GetProcessHeap(), 0, device->primary_pwfx);
+ device->primary_pwfx = wfx;
+ } else
+ err = DSERR_OUTOFMEMORY;
}
out:
--
2.8.2
More information about the wine-patches
mailing list