+static void test_formats2(void)
+{
+ IAudioClient *ac;
+ HRESULT hr;
+ WAVEFORMATEX *pwfx, *pwfx2;
+ WAVEFORMATEXTENSIBLE *pwfe, wfe, *pwfe2;
+
+ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+ NULL, (void**)&ac);
+
+ ok(hr == S_OK, "Activation failed with %08x\n", hr);
+ if (hr != S_OK)
+ return;
+
+ hr = IAudioClient_GetMixFormat(ac, &pwfx);
+ ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
+ if (hr != S_OK)
+ return;
+
+ ok(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Invalid wFormatTag\n");
+ if (pwfx->wFormatTag != WAVE_FORMAT_EXTENSIBLE) {
+ CoTaskMemFree(pwfx);
+ return;
+ }
+
+ pwfe = (WAVEFORMATEXTENSIBLE*)pwfx;
+ ok(pwfe->Samples.wValidBitsPerSample, "wValidBitsPerSample should be non-zero\n");
+
+ if (pwfx->nChannels > 2) {
+ trace("Limiting channels to 2\n");
+ pwfx->nChannels = 2;
+ pwfx->nBlockAlign = pwfx->wBitsPerSample / 8 * pwfx->nChannels;
+ pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
+ pwfe->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+ }
+
+ wfe = *pwfe;
+ pwfx->nAvgBytesPerSec = pwfx->nBlockAlign = 0;
+
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+ ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+ "Exclusive IsFormatSupported with nAvgBytesPerSec=0 and nBlockAlign=0 returned %08x\n", hr);
+
+ pwfx2 = NULL;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok((hr == E_INVALIDARG || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !pwfx2,
+ "Shared IsFormatSupported with nAvgBytesPerSec=0 and nBlockAlign=0 returned %08x %p\n", hr, pwfx2);
+ CoTaskMemFree(pwfx2);
+
+ pwfx->wFormatTag = WAVE_FORMAT_PCM;
+ pwfx2 = NULL;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok((hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !pwfx2,
+ "Shared IsFormatSupported with nAvgBytesPerSec=0 and nBlockAlign=0 returned %08x %p\n", hr, pwfx2);
+ CoTaskMemFree(pwfx2);
+
+ *pwfe = wfe;
+ pwfe->dwChannelMask = 0;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+ ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+ "Exclusive IsFormatSupported with dwChannelMask=0 returned %08x\n", hr);
+
+ pwfx2 = NULL;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok(hr == S_OK,
+ "Shared IsFormatSupported with dwChannelMask=0 returned %08x\n", hr);
+ CoTaskMemFree(pwfx2);
+
+
+ pwfe->dwChannelMask = 0x3ffff;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+ ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+ "Exclusive IsFormatSupported with dwChannelMask=0x3ffff returned %08x\n", hr);
+
+ pwfx2 = NULL;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok(hr == S_OK && !pwfx2,
+ "Shared IsFormatSupported with dwChannelMask=0x3ffff returned %08x %p\n", hr, pwfx2);
+ CoTaskMemFree(pwfx2);
+
+
+ pwfe->dwChannelMask = 0x40000000;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+ ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+ "Exclusive IsFormatSupported with dwChannelMask=0x40000000 returned %08x\n", hr);
+
+ pwfx2 = NULL;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok(hr == S_OK && !pwfx2,
+ "Shared IsFormatSupported with dwChannelMask=0x40000000 returned %08x %p\n", hr, pwfx2);
+ CoTaskMemFree(pwfx2);
+
+ pwfe->dwChannelMask = SPEAKER_ALL | SPEAKER_RESERVED;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+ ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+ "Exclusive IsFormatSupported with dwChannelMask=SPEAKER_ALL | SPEAKER_RESERVED returned %08x\n", hr);
+
+ pwfx2 = NULL;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok(hr == S_OK && !pwfx2,
+ "Shared IsFormatSupported with dwChannelMask=SPEAKER_ALL | SPEAKER_RESERVED returned %08x %p\n", hr, pwfx2);
+ CoTaskMemFree(pwfx2);
+
+ *pwfe = wfe;
+ pwfe->Samples.wValidBitsPerSample = 0;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+ ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+ "Exclusive IsFormatSupported with wValidBitsPerSample=0 returned %08x\n", hr);
+
+ pwfx2 = NULL;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok((hr == S_FALSE || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && pwfx2,
+ "Shared IsFormatSupported with wValidBitsPerSample=0 returned %08x %p\n", hr, pwfx2);
+ if (pwfx2) {
+ pwfe2 = (WAVEFORMATEXTENSIBLE*)pwfx2;
+ ok(pwfe2->Samples.wValidBitsPerSample == pwfx->wBitsPerSample,
+ "Shared IsFormatSupported had wValidBitsPerSample set to %u, not %u\n",
+ pwfe2->Samples.wValidBitsPerSample, pwfx->wBitsPerSample);
+ CoTaskMemFree(pwfx2);
+ }
+
+ pwfx2 = NULL;
+ pwfe->Samples.wValidBitsPerSample = pwfx->wBitsPerSample + 1;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok((hr == E_INVALIDARG || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !pwfx2,
+ "Shared IsFormatSupported with wValidBitsPerSample += 1 returned %08x %p\n", hr, pwfx2);
+
+ *pwfe = wfe;
+ memset(&pwfe->SubFormat, 0xff, 16);
+ pwfx2 = NULL;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && !pwfx2,
+ "Shared IsFormatSupported with SubFormat=-1 returned %08x %p\n", hr, pwfx2);
+ CoTaskMemFree(pwfx2);
+
+ *pwfe = wfe;
+ pwfx2 = NULL;
+ pwfe->Samples.wValidBitsPerSample = pwfx->wBitsPerSample = 256;
+ pwfx->nBlockAlign = pwfx->wBitsPerSample / 8 * pwfx->nChannels;
+ pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok((hr == E_INVALIDARG || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !pwfx2,
+ "Shared IsFormatSupported with wBitsPerSample=256 returned %08x %p\n", hr, pwfx2);
+ CoTaskMemFree(pwfx2);
+
+ *pwfe = wfe;
+ pwfx2 = NULL;
+ pwfe->Samples.wValidBitsPerSample = pwfx->wBitsPerSample - 1;
+ hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+ ok(hr == S_FALSE && pwfx2,
+ "Shared IsFormatSupported with wValidBitsPerSample-=1 returned %08x %p\n", hr, pwfx2);
+ if (pwfx2) {
+ pwfe2 = (WAVEFORMATEXTENSIBLE*)pwfx2;
+ ok(pwfe2->Samples.wValidBitsPerSample == pwfx->wBitsPerSample,
+ "Shared IsFormatSupported had wValidBitsPerSample set to %u, not %u\n",
+ pwfe2->Samples.wValidBitsPerSample, pwfx->wBitsPerSample);
+ CoTaskMemFree(pwfx2);
+ }
+
+ CoTaskMemFree(pwfx);
+ IAudioClient_Release(ac);
+}
+