Module: wine Branch: master Commit: 552433cf9e195109bbd520bf4eea47ad9afa6d8e URL: http://source.winehq.org/git/wine.git/?a=commit;h=552433cf9e195109bbd520bf4e...
Author: Andrew Eikum aeikum@codeweavers.com Date: Mon Apr 2 09:41:06 2012 -0500
dsound: Validate and correct wValidBitsPerSample in primary buffer SetFormat.
---
dlls/dsound/primary.c | 28 +++++++++++++++++++++++++++- dlls/dsound/tests/dsound.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletions(-)
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index 5c74353..4851ac2 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -353,7 +353,7 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe HRESULT err = DSERR_BUFFERLOST; int i; WAVEFORMATEX *old_fmt; - WAVEFORMATEXTENSIBLE *fmtex; + WAVEFORMATEXTENSIBLE *fmtex, *passed_fmtex = (WAVEFORMATEXTENSIBLE*)passed_fmt; BOOL forced = (device->priolevel == DSSCL_WRITEPRIMARY);
TRACE("(%p,%p)\n", device, passed_fmt); @@ -380,6 +380,11 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe passed_fmt->nBlockAlign != passed_fmt->nChannels * passed_fmt->wBitsPerSample / 8) return DSERR_INVALIDPARAM;
+ if(passed_fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE){ + if(passed_fmtex->Samples.wValidBitsPerSample > passed_fmtex->Format.wBitsPerSample) + return DSERR_INVALIDPARAM; + } + /* **** */ RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE); EnterCriticalSection(&(device->mixlock)); @@ -394,6 +399,13 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe goto done; }
+ if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE){ + if(fmtex->Samples.wValidBitsPerSample == 0){ + TRACE("Correcting 0 valid bits per sample\n"); + fmtex->Samples.wValidBitsPerSample = fmtex->Format.wBitsPerSample; + } + } + DSOUND_PrimaryClose(device);
err = DSOUND_ReopenDevice(device, FALSE); @@ -427,6 +439,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe device->pwfx->wBitsPerSample = 32; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); + if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample; err = DSOUND_ReopenDevice(device, FALSE); if(SUCCEEDED(err)) goto opened; @@ -434,6 +448,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe device->pwfx->wBitsPerSample = 16; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); + if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample; err = DSOUND_ReopenDevice(device, FALSE); if(SUCCEEDED(err)) goto opened; @@ -441,6 +457,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe device->pwfx->wBitsPerSample = 8; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); + if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample; err = DSOUND_ReopenDevice(device, FALSE); if(SUCCEEDED(err)) goto opened; @@ -449,6 +467,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe device->pwfx->wBitsPerSample = passed_fmt->wBitsPerSample; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); + if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample; err = DSOUND_ReopenDevice(device, FALSE); if(SUCCEEDED(err)) goto opened; @@ -456,6 +476,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe device->pwfx->wBitsPerSample = 32; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); + if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample; err = DSOUND_ReopenDevice(device, FALSE); if(SUCCEEDED(err)) goto opened; @@ -463,6 +485,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe device->pwfx->wBitsPerSample = 16; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); + if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample; err = DSOUND_ReopenDevice(device, FALSE); if(SUCCEEDED(err)) goto opened; @@ -470,6 +494,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe device->pwfx->wBitsPerSample = 8; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); + if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample; err = DSOUND_ReopenDevice(device, FALSE); if(SUCCEEDED(err)) goto opened; diff --git a/dlls/dsound/tests/dsound.c b/dlls/dsound/tests/dsound.c index 45dd00a..c68a5de 100644 --- a/dlls/dsound/tests/dsound.c +++ b/dlls/dsound/tests/dsound.c @@ -1253,6 +1253,7 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid)
if (rc==DS_OK && primary!=NULL) { WAVEFORMATEX wfx; + WAVEFORMATEXTENSIBLE fmtex;
wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 0; @@ -1351,6 +1352,45 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid) rc = IDirectSoundBuffer_SetFormat(primary, &wfx); ok(rc == S_OK, "SetFormat: %08x\n", rc);
+ fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + fmtex.Format.nChannels = 2; + fmtex.Format.nSamplesPerSec = 44100; + fmtex.Format.wBitsPerSample = 16; + fmtex.Format.nBlockAlign = fmtex.Format.nChannels * fmtex.Format.wBitsPerSample / 8; + fmtex.Format.nAvgBytesPerSec = fmtex.Format.nSamplesPerSec * fmtex.Format.nBlockAlign; + fmtex.Samples.wValidBitsPerSample = 0; + fmtex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; + fmtex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + rc = IDirectSoundBuffer_SetFormat(primary, (WAVEFORMATEX*)&fmtex); + ok(rc == S_OK, "SetFormat: %08x\n", rc); + + fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + fmtex.Format.nChannels = 2; + fmtex.Format.nSamplesPerSec = 44100; + fmtex.Format.wBitsPerSample = 24; + fmtex.Format.nBlockAlign = fmtex.Format.nChannels * fmtex.Format.wBitsPerSample / 8; + fmtex.Format.nAvgBytesPerSec = fmtex.Format.nSamplesPerSec * fmtex.Format.nBlockAlign; + fmtex.Samples.wValidBitsPerSample = 20; + fmtex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; + fmtex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + rc = IDirectSoundBuffer_SetFormat(primary, (WAVEFORMATEX*)&fmtex); + ok(rc == S_OK, "SetFormat: %08x\n", rc); + + fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + fmtex.Format.nChannels = 2; + fmtex.Format.nSamplesPerSec = 44100; + fmtex.Format.wBitsPerSample = 24; + fmtex.Format.nBlockAlign = fmtex.Format.nChannels * fmtex.Format.wBitsPerSample / 8; + fmtex.Format.nAvgBytesPerSec = fmtex.Format.nSamplesPerSec * fmtex.Format.nBlockAlign; + fmtex.Samples.wValidBitsPerSample = 32; + fmtex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; + fmtex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + rc = IDirectSoundBuffer_SetFormat(primary, (WAVEFORMATEX*)&fmtex); + ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); + IDirectSoundBuffer_Release(primary); }