/*************************************************************************** * DirectSoundFullDuplexCreate [DSOUND.10] * * Create and initialize a DirectSoundFullDuplex interface. * * PARAMS * capture_dev [I] Address of sound capture device GUID. * render_dev [I] Address of sound render device GUID. * cbufdesc [I] Address of capture buffer description. * bufdesc [I] Address of render buffer description. * hwnd [I] Handle to application window. * level [I] Cooperative level. * dsfd [O] Address where full duplex interface returned. * dscb8 [0] Address where capture buffer interface returned. * dsb8 [0] Address where render buffer interface returned. * outer_unk [I] Must be NULL. * * RETURNS * Success: DS_OK * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM, * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER */ HRESULT WINAPI DirectSoundFullDuplexCreate(const GUID *capture_dev, const GUID *render_dev, const DSCBUFFERDESC *cbufdesc, const DSBUFFERDESC *bufdesc, HWND hwnd, DWORD level, IDirectSoundFullDuplex **dsfd, IDirectSoundCaptureBuffer8 **dscb8, IDirectSoundBuffer8 **dsb8, IUnknown *outer_unk) { HRESULT hr; TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n", debugstr_guid(capture_dev), debugstr_guid(render_dev), cbufdesc, bufdesc, hwnd, level, dsfd, dscb8, dsb8, outer_unk); if (!dsfd) return DSERR_INVALIDPARAM; if (outer_unk) { *dsfd = NULL; return DSERR_NOAGGREGATION; } hr = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, (void**)dsfd); if (hr == DS_OK) { hr = IDirectSoundFullDuplex_Initialize(*dsfd, capture_dev, render_dev, cbufdesc, bufdesc, hwnd, level, dscb8, dsb8); if (hr != DS_OK) { IDirectSoundFullDuplex_Release(*dsfd); *dsfd = NULL; WARN("IDirectSoundFullDuplexImpl_Initialize failed\n"); } } return hr; }
static void IDirectSoundFullDuplex_test(LPDIRECTSOUNDFULLDUPLEX dsfdo, BOOL initialized, LPCGUID lpGuidCapture, LPCGUID lpGuidRender) { HRESULT rc; int ref; IUnknown * unknown; IDirectSound * ds; IDirectSound8 * ds8; IDirectSoundCapture * dsc; IDirectSoundFullDuplex * dsfd; /* Try to Query for objects */ rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IUnknown,(LPVOID*)&unknown); ok(rc==DS_OK,"IDirectSoundFullDuplex_QueryInterface(IID_IUnknown) failed: %08x\n", rc); if (rc==DS_OK) { ref=IDirectSoundFullDuplex_Release(unknown); ok(ref==0, "IDirectSoundFullDuplex_Release() has %d references, " "should have 0\n", ref); } rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IDirectSound,(LPVOID*)&ds); ok(rc==(initialized?DS_OK:E_NOINTERFACE),"IDirectSoundFullDuplex_QueryInterface(IID_IDirectSound) failed: %08x\n", rc); if (rc==DS_OK) { ref=IDirectSound_Release(ds); ok(ref==0, "IDirectSound_Release() has %d references, " "should have 0\n", ref); } rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IDirectSound8,(LPVOID*)&ds8); ok(rc==(initialized?DS_OK:E_NOINTERFACE),"IDirectSoundFullDuplex_QueryInterface(IID_IDirectSound8) " "failed: %08x\n",rc); if (rc==DS_OK) { IDirectSoundFullDuplex * dsfd1; rc=IDirectSound8_QueryInterface(ds8,&IID_IDirectSoundFullDuplex,(LPVOID*)&dsfd1); ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSoundFullDuplex) " "failed: %08x\n",rc); if (rc==DS_OK) { ref=IDirectSoundFullDuplex_Release(dsfd1); ok(ref==1, "IDirectSoundFullDuplex_Release() has %d references, " "should have 1\n", ref); } ref=IDirectSound8_Release(ds8); ok(ref==0, "IDirectSound8_Release() has %d references, " "should have 0\n", ref); } rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IDirectSoundCapture,(LPVOID*)&dsc); ok(rc==(initialized?DS_OK:E_NOINTERFACE),"IDirectSoundFullDuplex_QueryInterface(IID_IDirectSoundCapture) " "failed: %08x\n",rc); if (rc==DS_OK) { ref=IDirectSoundCapture_Release(dsc); ok(ref==0, "IDirectSoundCapture_Release() has %d references, " "should have 0\n", ref); } rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IDirectSoundFullDuplex,(LPVOID*)&dsfd); ok(rc==DS_OK,"IDirectSoundFullDuplex_QueryInterface(IID_IDirectSoundFullDuplex) " "failed: %08x\n",rc); if (rc==DS_OK) { ok(dsfdo==dsfd, "different interfaces\n"); ref=IDirectSound8_Release(dsfd); ok(ref==1, "IDirectSoundFullDuplex_Release() has %d references, should have 1\n", ref); } ref=IDirectSoundFullDuplex_Release(dsfdo); ok(ref==0, "IDirectSoundFullDuplex_Release() has %d references, " "should have 0\n", ref); }
static void test_COM(void) { IDirectSoundFullDuplex *dsfd = (IDirectSoundFullDuplex*)0xdeadbeef; IDirectSound *ds; IDirectSound8 *ds8; IDirectSoundCapture *dsc; IUnknown *unk, *unk8; IDirectSoundBuffer8 *dsb8; IDirectSoundCaptureBuffer8 *dscb8; DSBUFFERDESC bufdesc; DSCBUFFERDESC cbufdesc; WAVEFORMATEX wfx; ULONG refcount; HRESULT hr; /* COM aggregation */ hr = CoCreateInstance(&CLSID_DirectSoundFullDuplex, (IUnknown*)&dsfd, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&dsfd); ok(hr == CLASS_E_NOAGGREGATION, "DirectSoundFullDuplex create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr); ok(!dsfd, "dsfd = %p\n", dsfd); /* Invalid RIID */ hr = CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound3DBuffer, (void**)&dsfd); ok(hr == E_NOINTERFACE, "DirectSoundFullDuplex create failed: %08x, expected E_NOINTERFACE\n", hr); /* Different refcount for IDirectSoundFullDuplex and for IUnknown */ hr = CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSoundFullDuplex, (void**)&dsfd); ok(hr == S_OK, "DirectSoundFullDuplex create failed: %08x, expected S_OK\n", hr); refcount = IDirectSoundFullDuplex_AddRef(dsfd); ok(refcount == 2, "refcount == %u, expected 2\n", refcount); hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IUnknown, (void**)&unk); ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); refcount = IUnknown_AddRef(unk); ok(refcount == 2, "refcount == %u, expected 2\n", refcount); /* Not initialized */ hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSound8, (void**)&ds8); ok(hr == E_NOINTERFACE, "QueryInterface for IID_IDirectSound8 failed: %08x, expected E_NOINTERFACE\n", hr); hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSoundCapture, (void**)&dsc); ok(hr == E_NOINTERFACE, "QueryInterface for IID_IDirectSoundCapture failed: %08x, expected E_NOINTERFACE\n", hr); init_format(&wfx, WAVE_FORMAT_PCM, 44100, 16, 1); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize = sizeof(bufdesc); bufdesc.dwBufferBytes = wfx.nAvgBytesPerSec; bufdesc.lpwfxFormat = &wfx; ZeroMemory(&cbufdesc, sizeof(cbufdesc)); cbufdesc.dwSize = sizeof(cbufdesc); cbufdesc.dwBufferBytes = wfx.nAvgBytesPerSec; cbufdesc.lpwfxFormat = &wfx; hr = IDirectSoundFullDuplex_Initialize(dsfd, NULL, NULL, &cbufdesc, &bufdesc, get_hwnd(), DSSCL_EXCLUSIVE, NULL, NULL); ok(hr == E_INVALIDARG, "IDirectSoundFullDuplex_Initialize failed: %08x, expected E_INVALIDARG\n", hr); hr = IDirectSoundFullDuplex_Initialize(dsfd, NULL, NULL, &cbufdesc, &bufdesc, get_hwnd(), DSSCL_EXCLUSIVE, &dscb8, &dsb8); if (hr == DSERR_NODRIVER || hr == DSERR_INVALIDCALL) { skip("No driver\n"); return; } ok(hr == S_OK, "IDirectSoundFullDuplex_Initialize failed: %08x\n", hr); /* IDirectSound and IDirectSound8 */ hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSound8, (void**)&ds8); ok(hr == S_OK, "QueryInterface for IID_IDirectSound8 failed: %08x\n", hr); refcount = IDirectSound8_AddRef(ds8); ok(refcount == 2, "refcount == %u, expected 2\n", refcount); hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSound, (void**)&ds); ok(hr == S_OK, "QueryInterface for IID_IDirectSound failed: %08x\n", hr); refcount = IDirectSound8_AddRef(ds8); ok(refcount == 4, "refcount == %u, expected 4\n", refcount); refcount = IDirectSound_AddRef(ds); ok(refcount == 5, "refcount == %u, expected 5\n", refcount); hr = IDirectSound8_QueryInterface(ds8, &IID_IUnknown, (void**)&unk8); ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); ok(unk == unk8, "Got different IUnknown when QI'ing IDirectSoundFullDuplex and IDirectSound\n"); refcount = IUnknown_AddRef(unk8); ok(refcount == 4, "refcount == %u, expected 4\n", refcount); refcount = IDirectSound_AddRef(ds); ok(refcount == 6, "refcount == %u, expected 6\n", refcount); refcount = IDirectSoundFullDuplex_AddRef(dsfd); ok(refcount == 3, "refcount == %u, expected 3\n", refcount); /* IDirectSoundCapture */ hr = IDirectSoundFullDuplex_QueryInterface(dsfd, &IID_IDirectSoundCapture, (void**)&dsc); ok(hr == S_OK, "QueryInterface for IID_IDirectSoundCapture failed: %08x\n", hr); refcount = IDirectSoundCapture_AddRef(dsc); ok(refcount == 2, "refcount == %u, expected 2\n", refcount); refcount = IDirectSoundFullDuplex_AddRef(dsfd); ok(refcount == 4, "refcount == %u, expected 4\n", refcount); hr = IDirectSoundCapture_QueryInterface(ds8, &IID_IUnknown, (void**)&unk8); ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); ok(unk == unk8, "Got different IUnknown when QI'ing IDirectSoundFullDuplex and IDirectSoundCapture\n"); refcount = IUnknown_AddRef(unk8); ok(refcount == 6, "refcount == %u, expected 6\n", refcount); IDirectSoundBuffer8_Release(dsb8); IDirectSoundCaptureBuffer8_Release(dscb8); while (IDirectSound8_Release(ds8)); while (IDirectSoundCapture_Release(dsc)); while (IDirectSoundFullDuplex_Release(dsfd)); while (IUnknown_Release(unk)); }
static void IDirectSoundFullDuplex_tests(void) { HRESULT rc; LPDIRECTSOUNDFULLDUPLEX dsfdo = NULL; DSCBUFFERDESC DSCBufferDesc; DSBUFFERDESC DSBufferDesc; LPDIRECTSOUNDCAPTUREBUFFER8 pDSCBuffer8; LPDIRECTSOUNDBUFFER8 pDSBuffer8; WAVEFORMATEX wfex; trace("Testing IDirectSoundFullDuplex\n"); /* try the COM class factory method of creation with no devices specified */ rc=CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSoundFullDuplex, (void**)&dsfdo); ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG||rc==CLASS_E_CLASSNOTAVAILABLE, "CoCreateInstance(CLSID_DirectSoundFullDuplex) failed: 0x%08x\n", rc); if (rc==REGDB_E_CLASSNOTREG) { trace(" Class Not Registered\n"); return; } else if (rc==CLASS_E_CLASSNOTAVAILABLE) { trace(" Class Not Available\n"); return; } if (dsfdo) IDirectSoundFullDuplex_test(dsfdo, FALSE, NULL, NULL); /* try the COM class factory method of creation with default devices * specified */ rc=CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSoundFullDuplex, (void**)&dsfdo); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundFullDuplex) failed: 0x%08x\n", rc); if (dsfdo) IDirectSoundFullDuplex_test(dsfdo, FALSE, &DSDEVID_DefaultCapture, &DSDEVID_DefaultPlayback); /* try the COM class factory method of creation with default voice * devices specified */ rc=CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSoundFullDuplex, (void**)&dsfdo); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundFullDuplex) failed: 0x%08x\n", rc); if (dsfdo) IDirectSoundFullDuplex_test(dsfdo, FALSE, &DSDEVID_DefaultVoiceCapture, &DSDEVID_DefaultVoicePlayback); /* try the COM class factory method of creation with a bad * IID specified */ rc=CoCreateInstance(&CLSID_DirectSoundFullDuplex, NULL, CLSCTX_INPROC_SERVER, &CLSID_DirectSoundPrivate, (void**)&dsfdo); ok(rc==E_NOINTERFACE, "CoCreateInstance(CLSID_DirectSoundFullDuplex,CLSID_DirectSoundPrivate) " "should have failed: 0x%08x\n", rc); ZeroMemory(&wfex, sizeof(wfex)); wfex.wFormatTag = WAVE_FORMAT_PCM; wfex.nChannels = 1; wfex.nSamplesPerSec = 8000; wfex.wBitsPerSample = 16; wfex.nBlockAlign = (wfex.wBitsPerSample * wfex.nChannels) / 8; wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; ZeroMemory(&DSCBufferDesc, sizeof(DSCBufferDesc)); DSCBufferDesc.dwSize = sizeof(DSCBufferDesc); DSCBufferDesc.dwFlags = DSCBCAPS_WAVEMAPPED; DSCBufferDesc.dwBufferBytes = 8192; DSCBufferDesc.lpwfxFormat = &wfex; ZeroMemory(&DSBufferDesc, sizeof(DSBufferDesc)); DSBufferDesc.dwSize = sizeof(DSBufferDesc); DSBufferDesc.dwFlags = DSBCAPS_GLOBALFOCUS; DSBufferDesc.dwBufferBytes = 8192; DSBufferDesc.lpwfxFormat = &wfex; /* try with no device specified */ rc=pDirectSoundFullDuplexCreate(NULL,NULL,&DSCBufferDesc,&DSBufferDesc, get_hwnd(),DSSCL_EXCLUSIVE ,&dsfdo,&pDSCBuffer8, &pDSBuffer8,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL||rc==DSERR_INVALIDCALL, "DirectSoundFullDuplexCreate(NULL,NULL) failed: %08x\n",rc); if (rc==S_OK && dsfdo) IDirectSoundFullDuplex_test(dsfdo, TRUE, NULL, NULL); /* try with default devices specified */ rc=pDirectSoundFullDuplexCreate(&DSDEVID_DefaultCapture, &DSDEVID_DefaultPlayback,&DSCBufferDesc, &DSBufferDesc,get_hwnd(),DSSCL_EXCLUSIVE,&dsfdo, &pDSCBuffer8,&pDSBuffer8,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL||rc==DSERR_INVALIDCALL, "DirectSoundFullDuplexCreate(DSDEVID_DefaultCapture," "DSDEVID_DefaultPlayback) failed: %08x\n", rc); if (rc==DS_OK && dsfdo) IDirectSoundFullDuplex_test(dsfdo, TRUE, NULL, NULL); /* try with default voice devices specified */ rc=pDirectSoundFullDuplexCreate(&DSDEVID_DefaultVoiceCapture, &DSDEVID_DefaultVoicePlayback, &DSCBufferDesc,&DSBufferDesc,get_hwnd(),DSSCL_EXCLUSIVE, &dsfdo,&pDSCBuffer8,&pDSBuffer8,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL||rc==DSERR_INVALIDCALL, "DirectSoundFullDuplexCreate(DSDEVID_DefaultVoiceCapture," "DSDEVID_DefaultVoicePlayback) failed: %08x\n", rc); if (rc==DS_OK && dsfdo) IDirectSoundFullDuplex_test(dsfdo, TRUE, NULL, NULL); /* try with bad devices specified */ rc=pDirectSoundFullDuplexCreate(&DSDEVID_DefaultVoicePlayback, &DSDEVID_DefaultVoiceCapture, &DSCBufferDesc,&DSBufferDesc,get_hwnd(),DSSCL_EXCLUSIVE, &dsfdo,&pDSCBuffer8,&pDSBuffer8,NULL); ok(rc==DSERR_NODRIVER||rc==DSERR_INVALIDCALL, "DirectSoundFullDuplexCreate(DSDEVID_DefaultVoicePlayback," "DSDEVID_DefaultVoiceCapture) should have failed: %08x\n", rc); if (rc==DS_OK && dsfdo) IDirectSoundFullDuplex_Release(dsfdo); }