Andrew Eikum : dsound: Validate and correct wValidBitsPerSample in primary buffer SetFormat.

Alexandre Julliard julliard at winehq.org
Mon Apr 2 13:14:52 CDT 2012


Module: wine
Branch: master
Commit: 552433cf9e195109bbd520bf4eea47ad9afa6d8e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=552433cf9e195109bbd520bf4eea47ad9afa6d8e

Author: Andrew Eikum <aeikum at 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);
     }
 




More information about the wine-cvs mailing list