|  | /* | 
|  | * Unit tests for duplex functions | 
|  | * | 
|  | * Copyright (c) 2006 Robert Reif | 
|  | * | 
|  | * This library is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU Lesser General Public | 
|  | * License as published by the Free Software Foundation; either | 
|  | * version 2.1 of the License, or (at your option) any later version. | 
|  | * | 
|  | * This library is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | * Lesser General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU Lesser General Public | 
|  | * License along with this library; if not, write to the Free Software | 
|  | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
|  | */ | 
|  |  | 
|  | #define NONAMELESSSTRUCT | 
|  | #define NONAMELESSUNION | 
|  | #include <windows.h> | 
|  |  | 
|  | #include <stdio.h> | 
|  |  | 
|  | #include "wine/test.h" | 
|  | #include "dsound.h" | 
|  | #include "mmreg.h" | 
|  | #include "dxerr8.h" | 
|  | #include "dsconf.h" | 
|  |  | 
|  | #include "dsound_test.h" | 
|  |  | 
|  | static HRESULT (WINAPI *pDirectSoundFullDuplexCreate)(LPCGUID, LPCGUID, | 
|  | LPCDSCBUFFERDESC, LPCDSBUFFERDESC, HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, | 
|  | LPDIRECTSOUNDCAPTUREBUFFER8*, LPDIRECTSOUNDBUFFER8*, LPUNKNOWN)=NULL; | 
|  |  | 
|  | 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: %s\n", | 
|  | DXGetErrorString8(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: %s\n", | 
|  | DXGetErrorString8(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: %s\n",DXGetErrorString8(rc)); | 
|  | if (rc==DS_OK) { | 
|  | IDirectSoundFullDuplex * dsfd1; | 
|  | rc=IDirectSound8_QueryInterface(ds8,&IID_IDirectSoundFullDuplex,(LPVOID*)&dsfd1); | 
|  | ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSoundFullDuplex) " | 
|  | "failed: %s\n",DXGetErrorString8(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: %s\n",DXGetErrorString8(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: %s\n",DXGetErrorString8(rc)); | 
|  | if (rc==DS_OK) { | 
|  | ok (dsfdo==dsfd, "different interfaces\n"); | 
|  | ref=IDirectSound8_Release(dsfd); | 
|  | } | 
|  |  | 
|  | ref=IDirectSoundFullDuplex_Release(dsfdo); | 
|  | ok(ref==0, "IDirectSoundFullDuplex_Release() has %d references, " | 
|  | "should have 0\n", ref); | 
|  | } | 
|  |  | 
|  | 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: %s (0x%08lx)\n", | 
|  | DXGetErrorString8(rc), 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: %s (0x%08lx)\n", | 
|  | DXGetErrorString8(rc), 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: %s (0x%08lx)\n", | 
|  | DXGetErrorString8(rc), 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: %s (0x%08lx)\n",DXGetErrorString8(rc), 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: %s\n",DXGetErrorString8(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: %s\n", | 
|  | DXGetErrorString8(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: %s\n", | 
|  | DXGetErrorString8(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: %s\n", | 
|  | DXGetErrorString8(rc)); | 
|  | if (rc==DS_OK && dsfdo) | 
|  | IDirectSoundFullDuplex_Release(dsfdo); | 
|  | } | 
|  |  | 
|  | START_TEST(duplex) | 
|  | { | 
|  | HMODULE hDsound; | 
|  |  | 
|  | CoInitialize(NULL); | 
|  |  | 
|  | hDsound = LoadLibraryA("dsound.dll"); | 
|  | if (!hDsound) { | 
|  | trace("dsound.dll not found\n"); | 
|  | goto done; | 
|  | } | 
|  |  | 
|  | trace("DLL Version: %s\n", get_file_version("dsound.dll")); | 
|  |  | 
|  | pDirectSoundFullDuplexCreate=(void*)GetProcAddress(hDsound,"DirectSoundFullDuplexCreate"); | 
|  | if (!pDirectSoundFullDuplexCreate) | 
|  | { | 
|  | trace("duplex test skipped\n"); | 
|  | goto done; | 
|  | } | 
|  |  | 
|  | IDirectSoundFullDuplex_tests(); | 
|  |  | 
|  | done: | 
|  | CoUninitialize(); | 
|  | } |