1 /* 2 * Unit tests for duplex functions 3 * 4 * Copyright (c) 2006 Robert Reif 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "dsound_test.h" 22 23 static HRESULT (WINAPI *pDirectSoundFullDuplexCreate)(LPCGUID, LPCGUID, 24 LPCDSCBUFFERDESC, LPCDSBUFFERDESC, HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, 25 LPDIRECTSOUNDCAPTUREBUFFER8*, LPDIRECTSOUNDBUFFER8*, LPUNKNOWN)=NULL; 26 27 static void IDirectSoundFullDuplex_test(LPDIRECTSOUNDFULLDUPLEX dsfdo, 28 BOOL initialized, LPCGUID lpGuidCapture, 29 LPCGUID lpGuidRender) 30 { 31 HRESULT rc; 32 int ref; 33 IUnknown * unknown; 34 IDirectSound * ds; 35 IDirectSound8 * ds8; 36 IDirectSoundCapture * dsc; 37 IDirectSoundFullDuplex * dsfd; 38 39 /* Try to Query for objects */ 40 rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IUnknown,(LPVOID*)&unknown); 41 ok(rc==DS_OK,"IDirectSoundFullDuplex_QueryInterface(IID_IUnknown) failed: %08x\n", rc); 42 if (rc==DS_OK) { 43 ref=IDirectSoundFullDuplex_Release(unknown); 44 ok(ref==0, "IDirectSoundFullDuplex_Release() has %d references, " 45 "should have 0\n", ref); 46 } 47 48 rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IDirectSound,(LPVOID*)&ds); 49 ok(rc==(initialized?DS_OK:E_NOINTERFACE),"IDirectSoundFullDuplex_QueryInterface(IID_IDirectSound) failed: %08x\n", rc); 50 if (rc==DS_OK) { 51 ref=IDirectSound_Release(ds); 52 ok(ref==0, "IDirectSound_Release() has %d references, " 53 "should have 0\n", ref); 54 } 55 56 rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IDirectSound8,(LPVOID*)&ds8); 57 ok(rc==(initialized?DS_OK:E_NOINTERFACE),"IDirectSoundFullDuplex_QueryInterface(IID_IDirectSound8) " 58 "failed: %08x\n",rc); 59 if (rc==DS_OK) { 60 IDirectSoundFullDuplex * dsfd1; 61 rc=IDirectSound8_QueryInterface(ds8,&IID_IDirectSoundFullDuplex,(LPVOID*)&dsfd1); 62 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSoundFullDuplex) " 63 "failed: %08x\n",rc); 64 if (rc==DS_OK) { 65 ref=IDirectSoundFullDuplex_Release(dsfd1); 66 ok(ref==1, "IDirectSoundFullDuplex_Release() has %d references, " 67 "should have 1\n", ref); 68 } 69 ref=IDirectSound8_Release(ds8); 70 ok(ref==0, "IDirectSound8_Release() has %d references, " 71 "should have 0\n", ref); 72 } 73 74 rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IDirectSoundCapture,(LPVOID*)&dsc); 75 ok(rc==(initialized?DS_OK:E_NOINTERFACE),"IDirectSoundFullDuplex_QueryInterface(IID_IDirectSoundCapture) " 76 "failed: %08x\n",rc); 77 if (rc==DS_OK) { 78 ref=IDirectSoundCapture_Release(dsc); 79 ok(ref==0, "IDirectSoundCapture_Release() has %d references, " 80 "should have 0\n", ref); 81 } 82 83 rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IDirectSoundFullDuplex,(LPVOID*)&dsfd); 84 ok(rc==DS_OK,"IDirectSoundFullDuplex_QueryInterface(IID_IDirectSoundFullDuplex) " 85 "failed: %08x\n",rc); 86 if (rc==DS_OK) { 87 ok(dsfdo==dsfd, "different interfaces\n"); 88 ref=IDirectSound8_Release(dsfd); 89 ok(ref==1, "IDirectSoundFullDuplex_Release() has %d references, should have 1\n", ref); 90 } 91 92 ref=IDirectSoundFullDuplex_Release(dsfdo); 93 ok(ref==0, "IDirectSoundFullDuplex_Release() has %d references, " 94 "should have 0\n", ref); 95 } 96 97 static void IDirectSoundFullDuplex_tests(void) 98 { 99 HRESULT rc; 100 LPDIRECTSOUNDFULLDUPLEX dsfdo = NULL; 101 DSCBUFFERDESC DSCBufferDesc; 102 DSBUFFERDESC DSBufferDesc; 103 LPDIRECTSOUNDCAPTUREBUFFER8 pDSCBuffer8; 104 LPDIRECTSOUNDBUFFER8 pDSBuffer8; 105 WAVEFORMATEX wfex; 106 107 trace("Testing IDirectSoundFullDuplex\n"); 108 109 /* try the COM class factory method of creation with no devices specified */ 110 rc=CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, 111 CLSCTX_INPROC_SERVER, &IID_IDirectSoundFullDuplex, 112 (void**)&dsfdo); 113 ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG||rc==CLASS_E_CLASSNOTAVAILABLE, 114 "CoCreateInstance(CLSID_DirectSoundFullDuplex) failed: 0x%08x\n", rc); 115 if (rc==REGDB_E_CLASSNOTREG) { 116 trace(" Class Not Registered\n"); 117 return; 118 } else if (rc==CLASS_E_CLASSNOTAVAILABLE) { 119 trace(" Class Not Available\n"); 120 return; 121 } 122 if (dsfdo) 123 IDirectSoundFullDuplex_test(dsfdo, FALSE, NULL, NULL); 124 125 /* try the COM class factory method of creation with default devices 126 * specified */ 127 rc=CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, 128 CLSCTX_INPROC_SERVER, &IID_IDirectSoundFullDuplex, 129 (void**)&dsfdo); 130 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundFullDuplex) failed: 0x%08x\n", rc); 131 if (dsfdo) 132 IDirectSoundFullDuplex_test(dsfdo, FALSE, &DSDEVID_DefaultCapture, 133 &DSDEVID_DefaultPlayback); 134 135 /* try the COM class factory method of creation with default voice 136 * devices specified */ 137 rc=CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, 138 CLSCTX_INPROC_SERVER, &IID_IDirectSoundFullDuplex, 139 (void**)&dsfdo); 140 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundFullDuplex) failed: 0x%08x\n", rc); 141 if (dsfdo) 142 IDirectSoundFullDuplex_test(dsfdo, FALSE, &DSDEVID_DefaultVoiceCapture, 143 &DSDEVID_DefaultVoicePlayback); 144 145 /* try the COM class factory method of creation with a bad 146 * IID specified */ 147 rc=CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, 148 CLSCTX_INPROC_SERVER, &CLSID_DirectSoundPrivate, 149 (void**)&dsfdo); 150 ok(rc==E_NOINTERFACE, 151 "CoCreateInstance(CLSID_DirectSoundFullDuplex,CLSID_DirectSoundPrivate) " 152 "should have failed: 0x%08x\n", rc); 153 154 ZeroMemory(&wfex, sizeof(wfex)); 155 wfex.wFormatTag = WAVE_FORMAT_PCM; 156 wfex.nChannels = 1; 157 wfex.nSamplesPerSec = 8000; 158 wfex.wBitsPerSample = 16; 159 wfex.nBlockAlign = (wfex.wBitsPerSample * wfex.nChannels) / 8; 160 wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; 161 162 ZeroMemory(&DSCBufferDesc, sizeof(DSCBufferDesc)); 163 DSCBufferDesc.dwSize = sizeof(DSCBufferDesc); 164 DSCBufferDesc.dwFlags = DSCBCAPS_WAVEMAPPED; 165 DSCBufferDesc.dwBufferBytes = 8192; 166 DSCBufferDesc.lpwfxFormat = &wfex; 167 168 ZeroMemory(&DSBufferDesc, sizeof(DSBufferDesc)); 169 DSBufferDesc.dwSize = sizeof(DSBufferDesc); 170 DSBufferDesc.dwFlags = DSBCAPS_GLOBALFOCUS; 171 DSBufferDesc.dwBufferBytes = 8192; 172 DSBufferDesc.lpwfxFormat = &wfex; 173 174 /* try with no device specified */ 175 rc=pDirectSoundFullDuplexCreate(NULL,NULL,&DSCBufferDesc,&DSBufferDesc, 176 get_hwnd(),DSSCL_EXCLUSIVE ,&dsfdo,&pDSCBuffer8, 177 &pDSBuffer8,NULL); 178 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL||rc==DSERR_INVALIDCALL, 179 "DirectSoundFullDuplexCreate(NULL,NULL) failed: %08x\n",rc); 180 if (rc==S_OK && dsfdo) 181 IDirectSoundFullDuplex_test(dsfdo, TRUE, NULL, NULL); 182 183 /* try with default devices specified */ 184 rc=pDirectSoundFullDuplexCreate(&DSDEVID_DefaultCapture, 185 &DSDEVID_DefaultPlayback,&DSCBufferDesc, 186 &DSBufferDesc,get_hwnd(),DSSCL_EXCLUSIVE,&dsfdo, 187 &pDSCBuffer8,&pDSBuffer8,NULL); 188 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL||rc==DSERR_INVALIDCALL, 189 "DirectSoundFullDuplexCreate(DSDEVID_DefaultCapture," 190 "DSDEVID_DefaultPlayback) failed: %08x\n", rc); 191 if (rc==DS_OK && dsfdo) 192 IDirectSoundFullDuplex_test(dsfdo, TRUE, NULL, NULL); 193 194 /* try with default voice devices specified */ 195 rc=pDirectSoundFullDuplexCreate(&DSDEVID_DefaultVoiceCapture, 196 &DSDEVID_DefaultVoicePlayback, 197 &DSCBufferDesc,&DSBufferDesc,get_hwnd(),DSSCL_EXCLUSIVE, 198 &dsfdo,&pDSCBuffer8,&pDSBuffer8,NULL); 199 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL||rc==DSERR_INVALIDCALL, 200 "DirectSoundFullDuplexCreate(DSDEVID_DefaultVoiceCapture," 201 "DSDEVID_DefaultVoicePlayback) failed: %08x\n", rc); 202 if (rc==DS_OK && dsfdo) 203 IDirectSoundFullDuplex_test(dsfdo, TRUE, NULL, NULL); 204 205 /* try with bad devices specified */ 206 rc=pDirectSoundFullDuplexCreate(&DSDEVID_DefaultVoicePlayback, 207 &DSDEVID_DefaultVoiceCapture, 208 &DSCBufferDesc,&DSBufferDesc,get_hwnd(),DSSCL_EXCLUSIVE, 209 &dsfdo,&pDSCBuffer8,&pDSBuffer8,NULL); 210 ok(rc==DSERR_NODRIVER||rc==DSERR_INVALIDCALL, 211 "DirectSoundFullDuplexCreate(DSDEVID_DefaultVoicePlayback," 212 "DSDEVID_DefaultVoiceCapture) should have failed: %08x\n", rc); 213 if (rc==DS_OK && dsfdo) 214 IDirectSoundFullDuplex_Release(dsfdo); 215 } 216 217 static void test_COM(void) 218 { 219 IDirectSoundFullDuplex *dsfd = (IDirectSoundFullDuplex*)0xdeadbeef; 220 IDirectSound *ds; 221 IDirectSound8 *ds8; 222 IDirectSoundCapture *dsc; 223 IUnknown *unk, *unk8; 224 IDirectSoundBuffer8 *dsb8; 225 IDirectSoundCaptureBuffer8 *dscb8; 226 DSBUFFERDESC bufdesc; 227 DSCBUFFERDESC cbufdesc; 228 WAVEFORMATEX wfx; 229 ULONG refcount; 230 HRESULT hr; 231 232 /* COM aggregation */ 233 hr = CoCreateInstance(&CLSID_DirectSoundFullDuplex, (IUnknown*)&dsfd, CLSCTX_INPROC_SERVER, 234 &IID_IUnknown, (void**)&dsfd); 235 ok(hr == CLASS_E_NOAGGREGATION, 236 "DirectSoundFullDuplex create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr); 237 ok(!dsfd, "dsfd = %p\n", dsfd); 238 239 /* Invalid RIID */ 240 hr = CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, CLSCTX_INPROC_SERVER, 241 &IID_IDirectSound3DBuffer, (void**)&dsfd); 242 ok(hr == E_NOINTERFACE, 243 "DirectSoundFullDuplex create failed: %08x, expected E_NOINTERFACE\n", hr); 244 245 /* Different refcount for IDirectSoundFullDuplex and for IUnknown */ 246 hr = CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, CLSCTX_INPROC_SERVER, 247 &IID_IDirectSoundFullDuplex, (void**)&dsfd); 248 ok(hr == S_OK, "DirectSoundFullDuplex create failed: %08x, expected S_OK\n", hr); 249 refcount = IDirectSoundFullDuplex_AddRef(dsfd); 250 ok(refcount == 2, "refcount == %u, expected 2\n", refcount); 251 hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IUnknown, (void**)&unk); 252 ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); 253 refcount = IUnknown_AddRef(unk); 254 ok(refcount == 2, "refcount == %u, expected 2\n", refcount); 255 256 /* Not initialized */ 257 hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSound8, (void**)&ds8); 258 ok(hr == E_NOINTERFACE, 259 "QueryInterface for IID_IDirectSound8 failed: %08x, expected E_NOINTERFACE\n", hr); 260 hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSoundCapture, (void**)&dsc); 261 ok(hr == E_NOINTERFACE, 262 "QueryInterface for IID_IDirectSoundCapture failed: %08x, expected E_NOINTERFACE\n", hr); 263 264 init_format(&wfx, WAVE_FORMAT_PCM, 44100, 16, 1); 265 ZeroMemory(&bufdesc, sizeof(bufdesc)); 266 bufdesc.dwSize = sizeof(bufdesc); 267 bufdesc.dwBufferBytes = wfx.nAvgBytesPerSec; 268 bufdesc.lpwfxFormat = &wfx; 269 ZeroMemory(&cbufdesc, sizeof(cbufdesc)); 270 cbufdesc.dwSize = sizeof(cbufdesc); 271 cbufdesc.dwBufferBytes = wfx.nAvgBytesPerSec; 272 cbufdesc.lpwfxFormat = &wfx; 273 hr = IDirectSoundFullDuplex_Initialize(dsfd, NULL, NULL, &cbufdesc, &bufdesc, get_hwnd(), 274 DSSCL_EXCLUSIVE, NULL, NULL); 275 ok(hr == E_INVALIDARG, 276 "IDirectSoundFullDuplex_Initialize failed: %08x, expected E_INVALIDARG\n", hr); 277 hr = IDirectSoundFullDuplex_Initialize(dsfd, NULL, NULL, &cbufdesc, &bufdesc, get_hwnd(), 278 DSSCL_EXCLUSIVE, &dscb8, &dsb8); 279 if (hr == DSERR_NODRIVER || hr == DSERR_INVALIDCALL) { 280 skip("No driver\n"); 281 return; 282 } 283 ok(hr == S_OK, "IDirectSoundFullDuplex_Initialize failed: %08x\n", hr); 284 285 /* IDirectSound and IDirectSound8 */ 286 hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSound8, (void**)&ds8); 287 ok(hr == S_OK, "QueryInterface for IID_IDirectSound8 failed: %08x\n", hr); 288 refcount = IDirectSound8_AddRef(ds8); 289 ok(refcount == 2, "refcount == %u, expected 2\n", refcount); 290 hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSound, (void**)&ds); 291 ok(hr == S_OK, "QueryInterface for IID_IDirectSound failed: %08x\n", hr); 292 refcount = IDirectSound8_AddRef(ds8); 293 ok(refcount == 4, "refcount == %u, expected 4\n", refcount); 294 refcount = IDirectSound_AddRef(ds); 295 ok(refcount == 5, "refcount == %u, expected 5\n", refcount); 296 hr = IDirectSound8_QueryInterface(ds8, &IID_IUnknown, (void**)&unk8); 297 ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); 298 ok(unk == unk8, "Got different IUnknown when QI'ing IDirectSoundFullDuplex and IDirectSound\n"); 299 refcount = IUnknown_AddRef(unk8); 300 ok(refcount == 4, "refcount == %u, expected 4\n", refcount); 301 refcount = IDirectSound_AddRef(ds); 302 ok(refcount == 6, "refcount == %u, expected 6\n", refcount); 303 refcount = IDirectSoundFullDuplex_AddRef(dsfd); 304 ok(refcount == 3, "refcount == %u, expected 3\n", refcount); 305 306 /* IDirectSoundCapture */ 307 hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSoundCapture, (void**)&dsc); 308 ok(hr == S_OK, "QueryInterface for IID_IDirectSoundCapture failed: %08x\n", hr); 309 refcount = IDirectSoundCapture_AddRef(dsc); 310 ok(refcount == 2, "refcount == %u, expected 2\n", refcount); 311 refcount = IDirectSoundFullDuplex_AddRef(dsfd); 312 ok(refcount == 4, "refcount == %u, expected 4\n", refcount); 313 hr = IDirectSoundCapture_QueryInterface(ds8, &IID_IUnknown, (void**)&unk8); 314 ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); 315 ok(unk == unk8, 316 "Got different IUnknown when QI'ing IDirectSoundFullDuplex and IDirectSoundCapture\n"); 317 refcount = IUnknown_AddRef(unk8); 318 ok(refcount == 6, "refcount == %u, expected 6\n", refcount); 319 320 IDirectSoundBuffer8_Release(dsb8); 321 IDirectSoundCaptureBuffer8_Release(dscb8); 322 while (IDirectSound8_Release(ds8)); 323 while (IDirectSoundCapture_Release(dsc)); 324 while (IDirectSoundFullDuplex_Release(dsfd)); 325 while (IUnknown_Release(unk)); 326 } 327 328 START_TEST(duplex) 329 { 330 HMODULE hDsound; 331 332 CoInitialize(NULL); 333 334 hDsound = LoadLibrary("dsound.dll"); 335 if (hDsound) 336 { 337 338 pDirectSoundFullDuplexCreate=(void*)GetProcAddress(hDsound, 339 "DirectSoundFullDuplexCreate"); 340 if (pDirectSoundFullDuplexCreate) { 341 test_COM(); 342 IDirectSoundFullDuplex_tests(); 343 } else 344 skip("DirectSoundFullDuplexCreate missing - skipping all tests\n"); 345 346 FreeLibrary(hDsound); 347 } 348 else 349 skip("dsound.dll not found - skipping all tests\n"); 350 351 CoUninitialize(); 352 } 353