Commit 552433cf authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

dsound: Validate and correct wValidBitsPerSample in primary buffer SetFormat.

parent f9c875dd
...@@ -353,7 +353,7 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -353,7 +353,7 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
HRESULT err = DSERR_BUFFERLOST; HRESULT err = DSERR_BUFFERLOST;
int i; int i;
WAVEFORMATEX *old_fmt; WAVEFORMATEX *old_fmt;
WAVEFORMATEXTENSIBLE *fmtex; WAVEFORMATEXTENSIBLE *fmtex, *passed_fmtex = (WAVEFORMATEXTENSIBLE*)passed_fmt;
BOOL forced = (device->priolevel == DSSCL_WRITEPRIMARY); BOOL forced = (device->priolevel == DSSCL_WRITEPRIMARY);
TRACE("(%p,%p)\n", device, passed_fmt); TRACE("(%p,%p)\n", device, passed_fmt);
...@@ -380,6 +380,11 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -380,6 +380,11 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
passed_fmt->nBlockAlign != passed_fmt->nChannels * passed_fmt->wBitsPerSample / 8) passed_fmt->nBlockAlign != passed_fmt->nChannels * passed_fmt->wBitsPerSample / 8)
return DSERR_INVALIDPARAM; 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); RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
EnterCriticalSection(&(device->mixlock)); EnterCriticalSection(&(device->mixlock));
...@@ -394,6 +399,13 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -394,6 +399,13 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
goto done; 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); DSOUND_PrimaryClose(device);
err = DSOUND_ReopenDevice(device, FALSE); err = DSOUND_ReopenDevice(device, FALSE);
...@@ -427,6 +439,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -427,6 +439,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
device->pwfx->wBitsPerSample = 32; device->pwfx->wBitsPerSample = 32;
device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); 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); err = DSOUND_ReopenDevice(device, FALSE);
if(SUCCEEDED(err)) if(SUCCEEDED(err))
goto opened; goto opened;
...@@ -434,6 +448,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -434,6 +448,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
device->pwfx->wBitsPerSample = 16; device->pwfx->wBitsPerSample = 16;
device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); 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); err = DSOUND_ReopenDevice(device, FALSE);
if(SUCCEEDED(err)) if(SUCCEEDED(err))
goto opened; goto opened;
...@@ -441,6 +457,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -441,6 +457,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
device->pwfx->wBitsPerSample = 8; device->pwfx->wBitsPerSample = 8;
device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); 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); err = DSOUND_ReopenDevice(device, FALSE);
if(SUCCEEDED(err)) if(SUCCEEDED(err))
goto opened; goto opened;
...@@ -449,6 +467,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -449,6 +467,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
device->pwfx->wBitsPerSample = passed_fmt->wBitsPerSample; device->pwfx->wBitsPerSample = passed_fmt->wBitsPerSample;
device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); 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); err = DSOUND_ReopenDevice(device, FALSE);
if(SUCCEEDED(err)) if(SUCCEEDED(err))
goto opened; goto opened;
...@@ -456,6 +476,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -456,6 +476,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
device->pwfx->wBitsPerSample = 32; device->pwfx->wBitsPerSample = 32;
device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); 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); err = DSOUND_ReopenDevice(device, FALSE);
if(SUCCEEDED(err)) if(SUCCEEDED(err))
goto opened; goto opened;
...@@ -463,6 +485,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -463,6 +485,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
device->pwfx->wBitsPerSample = 16; device->pwfx->wBitsPerSample = 16;
device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); 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); err = DSOUND_ReopenDevice(device, FALSE);
if(SUCCEEDED(err)) if(SUCCEEDED(err))
goto opened; goto opened;
...@@ -470,6 +494,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe ...@@ -470,6 +494,8 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe
device->pwfx->wBitsPerSample = 8; device->pwfx->wBitsPerSample = 8;
device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign; device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8); 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); err = DSOUND_ReopenDevice(device, FALSE);
if(SUCCEEDED(err)) if(SUCCEEDED(err))
goto opened; goto opened;
......
...@@ -1253,6 +1253,7 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid) ...@@ -1253,6 +1253,7 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid)
if (rc==DS_OK && primary!=NULL) { if (rc==DS_OK && primary!=NULL) {
WAVEFORMATEX wfx; WAVEFORMATEX wfx;
WAVEFORMATEXTENSIBLE fmtex;
wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 0; wfx.nChannels = 0;
...@@ -1351,6 +1352,45 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid) ...@@ -1351,6 +1352,45 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid)
rc = IDirectSoundBuffer_SetFormat(primary, &wfx); rc = IDirectSoundBuffer_SetFormat(primary, &wfx);
ok(rc == S_OK, "SetFormat: %08x\n", rc); 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); IDirectSoundBuffer_Release(primary);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment