diff --git a/reactos/dll/directx/dsound_new/capture.c b/reactos/dll/directx/dsound_new/capture.c new file mode 100644 index 00000000000..a824fd3159e --- /dev/null +++ b/reactos/dll/directx/dsound_new/capture.c @@ -0,0 +1,296 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/capture.c + * PURPOSE: Implement IDirectSoundCapture + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + +#include "precomp.h" + +typedef struct +{ + IDirectSoundCaptureVtbl *lpVtbl; + LONG ref; + GUID DeviceGUID; + BOOL bInitialized; + LPFILTERINFO Filter; +}CDirectSoundCaptureImpl, *LPCDirectSoundCaptureImpl; + + +HRESULT +WINAPI +CDirectSoundCapture_fnQueryInterface( + LPDIRECTSOUNDCAPTURE8 iface, + REFIID riid, + LPVOID * ppobj) +{ + LPOLESTR pStr; + LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); + + /* check if the interface is supported */ + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDirectSoundCapture)) + { + *ppobj = (LPVOID)&This->lpVtbl; + InterlockedIncrement(&This->ref); + return S_OK; + } + + /* unsupported interface */ + if (SUCCEEDED(StringFromIID(riid, &pStr))) + { + DPRINT("No Interface for class %s\n", pStr); + CoTaskMemFree(pStr); + } + return E_NOINTERFACE; +} + +ULONG +WINAPI +CDirectSoundCapture_fnAddRef( + LPDIRECTSOUNDCAPTURE8 iface) +{ + ULONG ref; + LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); + + /* increment reference count */ + ref = InterlockedIncrement(&This->ref); + + return ref; +} + +ULONG +WINAPI +CDirectSoundCapture_fnRelease( + LPDIRECTSOUNDCAPTURE8 iface) +{ + ULONG ref; + LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); + + /* release reference count */ + ref = InterlockedDecrement(&(This->ref)); + + if (!ref) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + + +HRESULT +WINAPI +CDirectSoundCapture_fnCreateCaptureBuffer( + LPDIRECTSOUNDCAPTURE8 iface, + LPCDSCBUFFERDESC lpcDSBufferDesc, + LPDIRECTSOUNDCAPTUREBUFFER *ppDSCBuffer, + LPUNKNOWN pUnkOuter) +{ + HRESULT hResult; + LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); + + if (!This->bInitialized) + { + /* object not yet initialized */ + return DSERR_UNINITIALIZED; + } + + if (!lpcDSBufferDesc || !ppDSCBuffer || pUnkOuter != NULL) + { + DPRINT("Invalid parameter %p %p %p\n", lpcDSBufferDesc, ppDSCBuffer, pUnkOuter); + return DSERR_INVALIDPARAM; + } + + /* check buffer description */ + if ((lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC) && lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC1)) || lpcDSBufferDesc->dwReserved != 0) + { + DPRINT("Invalid buffer description size %u expected %u dwReserved %u\n", lpcDSBufferDesc->dwSize, sizeof(DSBUFFERDESC1), lpcDSBufferDesc->dwReserved); + return DSERR_INVALIDPARAM; + } + + /* sanity check */ + ASSERT(lpcDSBufferDesc->lpwfxFormat); + + if (lpcDSBufferDesc->lpwfxFormat) + { + DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n", + This, lpcDSBufferDesc->lpwfxFormat->wFormatTag, lpcDSBufferDesc->lpwfxFormat->nChannels, lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec, lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec, lpcDSBufferDesc->lpwfxFormat->nBlockAlign, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample, lpcDSBufferDesc->lpwfxFormat->cbSize); + } + + hResult = NewDirectSoundCaptureBuffer((LPDIRECTSOUNDCAPTUREBUFFER8*)ppDSCBuffer, This->Filter, lpcDSBufferDesc); + return hResult; +} + + +HRESULT +WINAPI +CDirectSoundCapture_fnGetCaps( + LPDIRECTSOUNDCAPTURE8 iface, + LPDSCCAPS pDSCCaps) +{ + WAVEINCAPSW Caps; + MMRESULT Result; + LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); + + if (!This->bInitialized) + { + /* object not yet initialized */ + return DSERR_UNINITIALIZED; + } + + if (!pDSCCaps || pDSCCaps->dwSize != sizeof(DSCCAPS)) + { + /* invalid param */ + return DSERR_INVALIDPARAM; + } + + /* We are certified ;) */ + pDSCCaps->dwFlags = DSCCAPS_CERTIFIED; + + Result = waveInGetDevCapsW(This->Filter->MappedId[0], &Caps, sizeof(WAVEINCAPSW)); + if (Result != MMSYSERR_NOERROR) + { + /* failed */ + DPRINT("waveInGetDevCapsW for device %u failed with %x\n", This->Filter->MappedId[0], Result); + return DSERR_UNSUPPORTED; + } + + pDSCCaps->dwFormats = Caps.dwFormats; + pDSCCaps->dwChannels = Caps.wChannels; + + return DS_OK; +} + + +HRESULT +WINAPI +CDirectSoundCapture_fnInitialize( + LPDIRECTSOUNDCAPTURE8 iface, + LPCGUID pcGuidDevice) +{ + GUID DeviceGuid; + LPOLESTR pGuidStr; + HRESULT hr; + LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); + + /* sanity check */ + ASSERT(RootInfo); + + if (This->bInitialized) + { + /* object has already been initialized */ + return DSERR_ALREADYINITIALIZED; + } + + /* fixme mutual exlucsion */ + + if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL)) + { + /* use default playback device id */ + pcGuidDevice = &DSDEVID_DefaultCapture; + } + + /* now verify the guid */ + if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK) + { + if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr))) + { + DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr); + CoTaskMemFree(pGuidStr); + } + return DSERR_INVALIDPARAM; + } + + hr = FindDeviceByGuid(&DeviceGuid, &This->Filter); + + if (SUCCEEDED(hr)) + { + This->bInitialized = TRUE; + return DS_OK; + } + + DPRINT("Failed to find device\n"); + return DSERR_INVALIDPARAM; +} + +static IDirectSoundCaptureVtbl vt_DirectSoundCapture = +{ + /* IUnknown methods */ + CDirectSoundCapture_fnQueryInterface, + CDirectSoundCapture_fnAddRef, + CDirectSoundCapture_fnRelease, + CDirectSoundCapture_fnCreateCaptureBuffer, + CDirectSoundCapture_fnGetCaps, + CDirectSoundCapture_fnInitialize +}; + +HRESULT +InternalDirectSoundCaptureCreate( + LPCGUID lpcGUID, + LPDIRECTSOUNDCAPTURE8 *ppDS, + IUnknown *pUnkOuter) +{ + LPCDirectSoundCaptureImpl This; + HRESULT hr; + + if (!ppDS || pUnkOuter != NULL) + { + /* invalid parameter passed */ + return DSERR_INVALIDPARAM; + } + + /* allocate CDirectSoundCaptureImpl struct */ + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureImpl)); + if (!This) + { + /* not enough memory */ + return DSERR_OUTOFMEMORY; + } + + /* initialize IDirectSoundCapture object */ + This->ref = 1; + This->lpVtbl = &vt_DirectSoundCapture; + + + /* initialize direct sound interface */ + hr = IDirectSoundCapture_Initialize((LPDIRECTSOUNDCAPTURE8)&This->lpVtbl, lpcGUID); + + /* check for success */ + if (!SUCCEEDED(hr)) + { + /* failed */ + DPRINT("Failed to initialize DirectSoundCapture object with %x\n", hr); + IDirectSoundCapture_Release((LPDIRECTSOUND8)&This->lpVtbl); + return hr; + } + + /* store result */ + *ppDS = (LPDIRECTSOUNDCAPTURE8)&This->lpVtbl; + DPRINT("DirectSoundCapture object %p\n", *ppDS); + return DS_OK; +} + + + +HRESULT +WINAPI +DirectSoundCaptureCreate( + LPCGUID lpcGUID, + LPDIRECTSOUNDCAPTURE *ppDSC, + LPUNKNOWN pUnkOuter) +{ + return InternalDirectSoundCaptureCreate(lpcGUID, (LPDIRECTSOUNDCAPTURE8*)ppDSC, pUnkOuter); +} + +HRESULT +WINAPI +DirectSoundCaptureCreate8( + LPCGUID lpcGUID, + LPDIRECTSOUNDCAPTURE8 *ppDSC8, + LPUNKNOWN pUnkOuter) +{ + return InternalDirectSoundCaptureCreate(lpcGUID, ppDSC8, pUnkOuter); +} diff --git a/reactos/dll/directx/dsound_new/capturebuffer.c b/reactos/dll/directx/dsound_new/capturebuffer.c new file mode 100644 index 00000000000..97aa608e391 --- /dev/null +++ b/reactos/dll/directx/dsound_new/capturebuffer.c @@ -0,0 +1,331 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/capturebuffer.c + * PURPOSE: IDirectSoundCaptureBuffer8 implementation + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + + +#include "precomp.h" + +const GUID KSINTERFACESETID_Standard = {0x1A8766A0L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; +const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; + + +typedef struct +{ + IDirectSoundCaptureBuffer8Vtbl *lpVtbl; + LONG ref; + LPFILTERINFO Filter; + HANDLE hPin; + PUCHAR Buffer; + DWORD BufferSize; + LPWAVEFORMATEX Format; + KSSTATE State; + + +}CDirectSoundCaptureBufferImpl, *LPCDirectSoundCaptureBufferImpl; + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_QueryInterface( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + IN REFIID riid, + LPVOID* ppobj) +{ + LPOLESTR pStr; + LPCDirectSoundCaptureBufferImpl This = (LPCDirectSoundCaptureBufferImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureBufferImpl, lpVtbl); + + /* check if requested interface is supported */ + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer) || + IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer8)) + { + *ppobj = (LPVOID)&This->lpVtbl; + InterlockedIncrement(&This->ref); + return S_OK; + } + + /* interface not supported */ + if (SUCCEEDED(StringFromIID(riid, &pStr))) + { + DPRINT("No Interface for class %s\n", pStr); + CoTaskMemFree(pStr); + } + return E_NOINTERFACE; +} + +ULONG +WINAPI +IDirectSoundCaptureBufferImpl_AddRef( + LPDIRECTSOUNDCAPTUREBUFFER8 iface) +{ + ULONG ref; + LPCDirectSoundCaptureBufferImpl This = (LPCDirectSoundCaptureBufferImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureBufferImpl, lpVtbl); + + /* increment reference count */ + ref = InterlockedIncrement(&This->ref); + + return ref; + +} + +ULONG +WINAPI +IDirectSoundCaptureBufferImpl_Release( + LPDIRECTSOUNDCAPTUREBUFFER8 iface) +{ + ULONG ref; + LPCDirectSoundCaptureBufferImpl This = (LPCDirectSoundCaptureBufferImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureBufferImpl, lpVtbl); + + /* release reference count */ + ref = InterlockedDecrement(&(This->ref)); + + if (!ref) + { + /* free capture buffer */ + HeapFree(GetProcessHeap(), 0, This->Buffer); + HeapFree(GetProcessHeap(), 0, This->Format); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_GetCaps( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + LPDSCBCAPS lpDSCBCaps ) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_GetCurrentPosition( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + LPDWORD lpdwCapturePosition, + LPDWORD lpdwReadPosition) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_GetFormat( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + LPWAVEFORMATEX lpwfxFormat, + DWORD dwSizeAllocated, + LPDWORD lpdwSizeWritten) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_GetStatus( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + LPDWORD lpdwStatus ) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_Initialize( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + LPDIRECTSOUNDCAPTURE lpDSC, + LPCDSCBUFFERDESC lpcDSCBDesc) +{ + /* capture buffer is already initialized */ + return DSERR_ALREADYINITIALIZED; +} + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_Lock( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + DWORD dwReadCusor, + DWORD dwReadBytes, + LPVOID* lplpvAudioPtr1, + LPDWORD lpdwAudioBytes1, + LPVOID* lplpvAudioPtr2, + LPDWORD lpdwAudioBytes2, + DWORD dwFlags ) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_Start( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + DWORD dwFlags ) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface ) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_Unlock( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + LPVOID lpvAudioPtr1, + DWORD dwAudioBytes1, + LPVOID lpvAudioPtr2, + DWORD dwAudioBytes2 ) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_GetObjectInPath( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + REFGUID rguidObject, + DWORD dwIndex, + REFGUID rguidInterface, + LPVOID* ppObject ) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSoundCaptureBufferImpl_GetFXStatus( + LPDIRECTSOUNDCAPTUREBUFFER8 iface, + DWORD dwFXCount, + LPDWORD pdwFXStatus ) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + + +static IDirectSoundCaptureBuffer8Vtbl vt_DirectSoundCaptureBuffer8 = +{ + /* IUnknown methods */ + IDirectSoundCaptureBufferImpl_QueryInterface, + IDirectSoundCaptureBufferImpl_AddRef, + IDirectSoundCaptureBufferImpl_Release, + + /* IDirectSoundCaptureBuffer methods */ + IDirectSoundCaptureBufferImpl_GetCaps, + IDirectSoundCaptureBufferImpl_GetCurrentPosition, + IDirectSoundCaptureBufferImpl_GetFormat, + IDirectSoundCaptureBufferImpl_GetStatus, + IDirectSoundCaptureBufferImpl_Initialize, + IDirectSoundCaptureBufferImpl_Lock, + IDirectSoundCaptureBufferImpl_Start, + IDirectSoundCaptureBufferImpl_Stop, + IDirectSoundCaptureBufferImpl_Unlock, + + /* IDirectSoundCaptureBuffer methods */ + IDirectSoundCaptureBufferImpl_GetObjectInPath, + IDirectSoundCaptureBufferImpl_GetFXStatus +}; + + +HRESULT +NewDirectSoundCaptureBuffer( + LPDIRECTSOUNDCAPTUREBUFFER8 *OutBuffer, + LPFILTERINFO Filter, + LPCDSCBUFFERDESC lpcDSBufferDesc) +{ + DWORD FormatSize; + ULONG DeviceId = 0, PinId; + DWORD Result = ERROR_SUCCESS; + + LPCDirectSoundCaptureBufferImpl This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureBufferImpl)); + + if (!This) + { + /* not enough memory */ + return DSERR_OUTOFMEMORY; + } + + /* calculate format size */ + FormatSize = sizeof(WAVEFORMATEX) + lpcDSBufferDesc->lpwfxFormat->cbSize; + /* allocate format struct */ + This->Format = HeapAlloc(GetProcessHeap(), 0, FormatSize); + if (!This->Format) + { + /* not enough memory */ + HeapFree(GetProcessHeap(), 0, This); + return DSERR_OUTOFMEMORY; + } + + /* sanity check */ + ASSERT(lpcDSBufferDesc->dwBufferBytes); + + /* allocate capture buffer */ + This->Buffer = HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc->dwBufferBytes); + if (!This->Buffer) + { + /* not enough memory */ + HeapFree(GetProcessHeap(), 0, This->Format); + HeapFree(GetProcessHeap(), 0, This); + return DSERR_OUTOFMEMORY; + } + + /* store buffer size */ + This->BufferSize = lpcDSBufferDesc->dwBufferBytes; + ASSERT(lpcDSBufferDesc->lpwfxFormat->cbSize == 0); + + do + { + /* try all available recording pins on that filter */ + PinId = GetPinIdFromFilter(Filter, TRUE, DeviceId); + DPRINT("PinId %u DeviceId %u\n", PinId, DeviceId); + + if (PinId == ULONG_MAX) + break; + + Result = OpenPin(Filter->hFilter, PinId, lpcDSBufferDesc->lpwfxFormat, &This->hPin, TRUE); + if (Result == ERROR_SUCCESS) + break; + + DeviceId++; + }while(TRUE); + + if (Result != ERROR_SUCCESS) + { + /* failed to instantiate the capture pin */ + HeapFree(GetProcessHeap(), 0, This->Buffer); + HeapFree(GetProcessHeap(), 0, This->Format); + HeapFree(GetProcessHeap(), 0, This); + return DSERR_OUTOFMEMORY; + } + + /* initialize capture buffer */ + This->ref = 1; + This->lpVtbl = &vt_DirectSoundCaptureBuffer8; + This->Filter = Filter; + This->State = KSSTATE_STOP; + + *OutBuffer = (LPDIRECTSOUNDCAPTUREBUFFER8)&This->lpVtbl; + return DS_OK; +} diff --git a/reactos/dll/directx/dsound_new/classfactory.c b/reactos/dll/directx/dsound_new/classfactory.c new file mode 100644 index 00000000000..ee31e6154cd --- /dev/null +++ b/reactos/dll/directx/dsound_new/classfactory.c @@ -0,0 +1,141 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/classfactory.c + * PURPOSE: IClassFactory implementation + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + + +#include "precomp.h" + +typedef struct +{ + const IClassFactoryVtbl *lpVtbl; + LONG ref; + CLSID *rclsid; + LPFNCREATEINSTANCE lpfnCI; + const IID * riidInst; +} IClassFactoryImpl; + + +static +HRESULT +WINAPI +IClassFactory_fnQueryInterface( + LPCLASSFACTORY iface, + REFIID riid, + LPVOID *ppvObj) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + *ppvObj = NULL; + + /* check requested interface */ + if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) + { + *ppvObj = This; + InterlockedIncrement(&This->ref); + return S_OK; + } + return E_NOINTERFACE; +} + +static +ULONG +WINAPI +IClassFactory_fnAddRef( + LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + /* increment reference count */ + ULONG refCount = InterlockedIncrement(&This->ref); + + return refCount; +} + +static +ULONG +WINAPI +IClassFactory_fnRelease( + LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + /* decrement reference count */ + if (!refCount) + { + /* free class factory */ + CoTaskMemFree(This); + return 0; + } + return refCount; +} + +static +HRESULT +WINAPI +IClassFactory_fnCreateInstance( + LPCLASSFACTORY iface, + LPUNKNOWN pUnkOuter, + REFIID riid, + LPVOID *ppvObject) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + *ppvObject = NULL; + + if ( This->riidInst==NULL || IsEqualCLSID(riid, This->riidInst) || IsEqualCLSID(riid, &IID_IUnknown) ) + { + /* instantiate object */ + return This->lpfnCI(pUnkOuter, riid, ppvObject); + } + + return E_NOINTERFACE; +} + +static +HRESULT +WINAPI IClassFactory_fnLockServer( + LPCLASSFACTORY iface, + BOOL fLock) +{ + //IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + return E_NOTIMPL; +} + + +static const IClassFactoryVtbl dclfvt = +{ + IClassFactory_fnQueryInterface, + IClassFactory_fnAddRef, + IClassFactory_fnRelease, + IClassFactory_fnCreateInstance, + IClassFactory_fnLockServer +}; + + +IClassFactory * +IClassFactory_fnConstructor( + LPFNCREATEINSTANCE lpfnCI, + PLONG pcRefDll, + REFIID riidInst) +{ + IClassFactoryImpl* lpclf; + + lpclf = CoTaskMemAlloc(sizeof(IClassFactoryImpl)); + lpclf->ref = 1; + lpclf->lpVtbl = &dclfvt; + lpclf->lpfnCI = lpfnCI; + + if (pcRefDll) + InterlockedIncrement(pcRefDll); + lpclf->riidInst = riidInst; + + return (LPCLASSFACTORY)lpclf; +} + + diff --git a/reactos/dll/directx/dsound_new/devicelist.c b/reactos/dll/directx/dsound_new/devicelist.c new file mode 100644 index 00000000000..a252c821498 --- /dev/null +++ b/reactos/dll/directx/dsound_new/devicelist.c @@ -0,0 +1,498 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/devicelist.c + * PURPOSE: Enumeration of audio devices + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + +#include "precomp.h" + +ULONG +GetPinIdFromFilter( + LPFILTERINFO Filter, + BOOL bCapture, + ULONG Offset) +{ + ULONG Index; + + for(Index = Offset; Index < Filter->PinCount; Index++) + { + if (Filter->Pin[Index] == PIN_TYPE_PLAYBACK && !bCapture) + return Index; + + if (Filter->Pin[Index] == PIN_TYPE_RECORDING && bCapture) + return Index; + } + return ULONG_MAX; +} + + +DWORD +OpenDeviceList( + IN LPGUID InterfaceGuid, + OUT HDEVINFO * OutHandle) +{ + HDEVINFO DeviceHandle; + + DeviceHandle = SetupDiGetClassDevs(InterfaceGuid, + NULL, + NULL, + DIGCF_DEVICEINTERFACE); //DIGCF_PRESENT + + /* check for success */ + if (DeviceHandle == INVALID_HANDLE_VALUE) + { + /* failed to create device list */ + return GetLastError(); + } + + /* store result */ + *OutHandle = DeviceHandle; + + return ERROR_SUCCESS; +} + +BOOL +CloseDeviceList( + HDEVINFO Handle) +{ + return SetupDiDestroyDeviceInfoList(Handle); +} + +BOOL +GetDeviceListInterfaces( + HDEVINFO DeviceHandle, + IN LPGUID InterfaceGuid, + LPFILTERINFO *OutPath) +{ + ULONG Length, Index = 0; + SP_DEVICE_INTERFACE_DATA InterfaceData; + PSP_DEVICE_INTERFACE_DETAIL_DATA_W DetailData; + SP_DEVINFO_DATA DeviceData; + LPFILTERINFO LastDevice = NULL, RootDevice = NULL, CurDevice; + BOOL Result; + + + do + { + InterfaceData.cbSize = sizeof(InterfaceData); + InterfaceData.Reserved = 0; + + /* query device interface */ + Result = SetupDiEnumDeviceInterfaces(DeviceHandle, + NULL, + InterfaceGuid, + Index, + &InterfaceData); + + if (!Result) + { + /* failed */ + DPRINT("SetupDiEnumDeviceInterfaces Index %u failed with %lx\n", Index, GetLastError()); + break; + } + + /* allocate device interface struct */ + Length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR); + DetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + Length); + + if (!DetailData) + { + /* insufficient memory */ + break; + } + + /* initialize device interface detail struct */ + DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); + + DeviceData.cbSize = sizeof(DeviceData); + DeviceData.Reserved = 0; + + Result = SetupDiGetDeviceInterfaceDetailW(DeviceHandle, + &InterfaceData, + DetailData, + Length, + NULL, + &DeviceData); + + if (!Result) + { + /* failed */ + DPRINT("SetupDiGetDeviceInterfaceDetail failed with %x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, DetailData); + + break; + } + + /* allocate device path struct */ + CurDevice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FILTERINFO)); + if (!CurDevice) + { + /* no memory */ + HeapFree(GetProcessHeap(), 0, DetailData); + break; + } + + /* store device path */ + CopyMemory(&CurDevice->DeviceData, &DeviceData, sizeof(SP_DEVINFO_DATA)); + wcscpy(CurDevice->DevicePath, DetailData->DevicePath); + CurDevice->MappedId[0] = ULONG_MAX; + CurDevice->MappedId[1] = ULONG_MAX; + + DPRINT("DevicePath %S\n", CurDevice->DevicePath); + + if (!RootDevice) + RootDevice = CurDevice; + + if (LastDevice) + { + LastDevice->lpNext = CurDevice; + } + + /* set as last device */ + LastDevice = CurDevice; + + /* free device interface struct */ + HeapFree(GetProcessHeap(), 0, DetailData); + + /* increment device interface index */ + Index++; + }while(TRUE); + + /* store result */ + *OutPath = RootDevice; + + if (!RootDevice) + return FALSE; + + + return TRUE; +} + +DWORD +OpenDeviceKey( + HDEVINFO Handle, + PSP_DEVINFO_DATA FILTERINFOData, + DWORD KeyType, + REGSAM DesiredAccess, + OUT HKEY * OutKey) +{ + HKEY hKey; + + /* try open device registry key */ + hKey = SetupDiOpenDevRegKey(Handle, FILTERINFOData, DICS_FLAG_CONFIGSPECIFIC, 0, KeyType, DesiredAccess); + + if (hKey == INVALID_HANDLE_VALUE) + return GetLastError(); + + /* store result */ + *OutKey = hKey; + + return ERROR_SUCCESS; +} + +VOID +FindAudioFilterPins( + LPFILTERINFO CurInfo, + OUT PULONG WaveInPins, + OUT PULONG WaveOutPins) +{ + ULONG Index; + KSPIN_COMMUNICATION Communication; + KSPIN_DATAFLOW DataFlow; + + *WaveInPins = 0; + *WaveOutPins = 0; + + /* traverse all pins */ + for(Index = 0; Index < CurInfo->PinCount; Index++) + { + if (GetFilterPinCommunication(CurInfo->hFilter, Index, &Communication) == ERROR_SUCCESS && + GetFilterPinDataFlow(CurInfo->hFilter, Index, &DataFlow) == ERROR_SUCCESS) + { + if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN) + { + /* found a wave out device */ + CurInfo->Pin[Index] = PIN_TYPE_PLAYBACK; + (*WaveOutPins)++; + } + else if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT) + { + /* found a wave in device */ + CurInfo->Pin[Index] = PIN_TYPE_RECORDING; + (*WaveInPins)++; + } + else + { + /* bridge pin / topology pin etc */ + CurInfo->Pin[Index] = PIN_TYPE_NONE; + } + } + else + { + /* bridge pin / topology pin etc */ + CurInfo->Pin[Index] = PIN_TYPE_NONE; + } + } +} + +BOOL +FindWinMMDeviceIndex( + LPFILTERINFO CurInfo, + BOOL bRecord) +{ + ULONG DeviceCount, Index; + WCHAR Buffer[MAX_PATH]; + DWORD Size, dwResult; + + if (bRecord) + DeviceCount = waveInGetNumDevs(); + else + DeviceCount = waveOutGetNumDevs(); + + /* sanity check */ + //ASSERT(DeviceCount); + + for(Index = 0; Index < DeviceCount; Index++) + { + Size = 0; + + /* query device interface size */ + if (bRecord) + dwResult = waveInMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&Size, 0); + else + dwResult = waveOutMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&Size, 0); + + if (dwResult != MMSYSERR_NOERROR) + { + DPRINT("Failed DRV_QUERYDEVICEINTERFACESIZE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index); + continue; + } + + /* sanity check */ + ASSERT(Size < MAX_PATH); + + /* now get the device interface string */ + if (bRecord) + dwResult = waveInMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)Buffer, MAX_PATH); + else + dwResult = waveOutMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)Buffer, MAX_PATH); + + if (dwResult != MMSYSERR_NOERROR) + { + DPRINT("Failed DRV_QUERYDEVICEINTERFACE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index); + continue; + } + + if (!wcsicmp(CurInfo->DevicePath, Buffer)) + { + if (bRecord) + CurInfo->MappedId[0] = Index; + else + CurInfo->MappedId[1] = Index; + + return TRUE; + } + } + + DPRINT1("Failed to find device %ws bRecord %u Count %u\n", CurInfo->DevicePath, bRecord, DeviceCount); + + // HACK + if (bRecord) + CurInfo->MappedId[0] = 0; + else + CurInfo->MappedId[1] = 0; + + + return TRUE; +} + +HRESULT +EnumerateAudioFilter( + LPFILTERINFO CurInfo, + OUT PULONG WaveInCount, + OUT PULONG WaveOutCount) +{ + DWORD Status; + ULONG PinCount, WaveInPins, WaveOutPins; + + /* first step open filter */ + Status = OpenFilter((LPCWSTR)CurInfo->DevicePath, &CurInfo->hFilter); + if (Status != ERROR_SUCCESS) + { + DPRINT("Failed to open filter with %lx Path %ws\n", Status, CurInfo->DevicePath); + return E_FAIL; + } + + /* get filter pin count */ + Status = GetFilterPinCount(CurInfo->hFilter, &PinCount); + if (Status != ERROR_SUCCESS) + { + DPRINT("Failed to get pin count with %lx\n", Status); + return E_FAIL; + } + + /* sanity check */ + ASSERT(PinCount); + + /* store pin count */ + CurInfo->PinCount = PinCount; + + /* now allocate an pin array */ + CurInfo->Pin = HeapAlloc(GetProcessHeap(), 0, PinCount * sizeof(ULONG)); + if (!CurInfo->Pin) + { + /* no memory */ + return E_FAIL; + } + + /* no try to find playback / recording pins */ + FindAudioFilterPins(CurInfo, &WaveInPins, &WaveOutPins); + + DPRINT("WaveInPins %u WaveOutPins %u %S\n", WaveInPins, WaveOutPins, CurInfo->DevicePath); + + if (WaveOutPins) + { + /* create a unique guid for this playback device */ + if (FindWinMMDeviceIndex(CurInfo, TRUE)) + { + (*WaveOutCount)++; + INIT_GUID(CurInfo->DeviceGuid[0], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveInCount); + } + } + + + if (WaveInPins) + { + if (FindWinMMDeviceIndex(CurInfo, FALSE)) + { + /* create a unique guid for this record device */ + (*WaveInCount)++; + INIT_GUID(CurInfo->DeviceGuid[1], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveOutCount); + } + } + + return S_OK; +} + + +HRESULT +EnumAudioDeviceInterfaces( + LPFILTERINFO *OutRootInfo) +{ + HDEVINFO hList; + DWORD Status; + HRESULT hResult; + ULONG WaveOutCount, WaveInCount; + GUID AudioDeviceGuid = {STATIC_KSCATEGORY_AUDIO}; + LPFILTERINFO RootInfo = NULL, CurInfo; + + /* try open the device list */ + Status = OpenDeviceList(&AudioDeviceGuid, &hList); + + if (Status != ERROR_SUCCESS) + { + DPRINT1("OpenDeviceList failed with %lx\n", Status); + return E_FAIL; + } + + if (!GetDeviceListInterfaces(hList, &AudioDeviceGuid, &RootInfo)) + { + DPRINT1("No devices found\n"); + CloseDeviceList(hList); + return S_FALSE; + } + + /* sanity check */ + ASSERT(RootInfo); + + CurInfo = RootInfo; + + WaveOutCount = 0; + WaveInCount = 0; + + /* now check all audio filters */ + while(CurInfo) + { + /* now check details of the audio filter */ + hResult = EnumerateAudioFilter(CurInfo, &WaveInCount, &WaveOutCount); + + if (hResult != S_OK) + { + DPRINT1("EnumerateAudioFilter failed with %lx\n", Status); + break; + } + + /* move to next filter */ + CurInfo = CurInfo->lpNext; + } + + /* close device list */ + CloseDeviceList(hList); + + /* store result */ + *OutRootInfo = RootInfo; + + /* done */ + return hResult; +} + +BOOL +FindDeviceByMappedId( + IN ULONG DeviceID, + LPFILTERINFO *Filter, + BOOL bPlayback) +{ + LPFILTERINFO CurInfo; + if (!RootInfo) + return FALSE; + + /* get first entry */ + CurInfo = RootInfo; + + while(CurInfo) + { + if ((bPlayback && CurInfo->MappedId[1] == DeviceID) || + (!bPlayback && CurInfo->MappedId[0] == DeviceID)) + { + /* found filter */ + *Filter = CurInfo; + return TRUE; + } + + CurInfo = CurInfo->lpNext; + } + return FALSE; +} + +BOOL +FindDeviceByGuid( + LPCGUID pGuidSrc, + LPFILTERINFO *Filter) +{ + LPFILTERINFO CurInfo; + if (!RootInfo) + return FALSE; + + /* get first entry */ + CurInfo = RootInfo; + + while(CurInfo) + { + if (IsEqualGUID(&CurInfo->DeviceGuid[0], pGuidSrc) || + IsEqualGUID(&CurInfo->DeviceGuid[1], pGuidSrc)) + { + /* found filter */ + *Filter = CurInfo; + return TRUE; + } + + CurInfo = CurInfo->lpNext; + } + + return FALSE; +} diff --git a/reactos/dll/directx/dsound_new/directsound.c b/reactos/dll/directx/dsound_new/directsound.c new file mode 100644 index 00000000000..dd710c7cb35 --- /dev/null +++ b/reactos/dll/directx/dsound_new/directsound.c @@ -0,0 +1,389 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/directsound.c + * PURPOSE: Handles IDirectSound interface + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + +#include "precomp.h" + +typedef struct +{ + IDirectSound8Vtbl *lpVtbl; + LONG ref; + GUID DeviceGUID; + BOOL bInitialized; + DWORD dwLevel; + LPFILTERINFO Filter; + LPDIRECTSOUNDBUFFER8 PrimaryBuffer; + + +}CDirectSoundImpl, *LPCDirectSoundImpl; + +HRESULT +WINAPI +IDirectSound8_fnQueryInterface( + LPDIRECTSOUND8 iface, + REFIID riid, + LPVOID * ppobj) +{ + LPOLESTR pStr; + LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); + + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDirectSound) || + IsEqualIID(riid, &IID_IDirectSound8)) + { + *ppobj = (LPVOID)&This->lpVtbl; + InterlockedIncrement(&This->ref); + return S_OK; + } + + if (SUCCEEDED(StringFromIID(riid, &pStr))) + { + DPRINT("No Interface for class %s\n", pStr); + CoTaskMemFree(pStr); + } + return E_NOINTERFACE; +} + +ULONG +WINAPI +IDirectSound8_fnAddRef( + LPDIRECTSOUND8 iface) +{ + ULONG ref; + LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); + + ref = InterlockedIncrement(&This->ref); + + return ref; +} + +ULONG +WINAPI +IDirectSound8_fnRelease( + LPDIRECTSOUND8 iface) +{ + ULONG ref; + LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); + + ref = InterlockedDecrement(&(This->ref)); + + if (!ref) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +HRESULT +WINAPI +IDirectSound8_fnCreateSoundBuffer( + LPDIRECTSOUND8 iface, + LPCDSBUFFERDESC lpcDSBufferDesc, + LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer, + IUnknown FAR* pUnkOuter) +{ + HRESULT hResult; + LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); + + if (!This->bInitialized) + { + /* object not yet initialized */ + return DSERR_UNINITIALIZED; + } + + if (!lpcDSBufferDesc || !lplpDirectSoundBuffer || pUnkOuter != NULL) + { + DPRINT("Invalid parameter %p %p %p\n", lpcDSBufferDesc, lplpDirectSoundBuffer, pUnkOuter); + return DSERR_INVALIDPARAM; + } + + /* check buffer description */ + if ((lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC) && lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC1)) || lpcDSBufferDesc->dwReserved != 0) + { + DPRINT("Invalid buffer description size %u expected %u dwReserved %u\n", lpcDSBufferDesc->dwSize, sizeof(DSBUFFERDESC1), lpcDSBufferDesc->dwReserved); + return DSERR_INVALIDPARAM; + } + + DPRINT("This %p dwFlags %x dwBufferBytes %u lpwfxFormat %p dwSize %u\n", This, lpcDSBufferDesc->dwFlags, lpcDSBufferDesc->dwBufferBytes, lpcDSBufferDesc->lpwfxFormat, lpcDSBufferDesc->dwSize); + + if (lpcDSBufferDesc->dwFlags & DSBCAPS_PRIMARYBUFFER) + { + if (lpcDSBufferDesc->lpwfxFormat != NULL) + { + /* format must be null for primary sound buffer */ + return DSERR_INVALIDPARAM; + } + + if (This->PrimaryBuffer) + { + /* primary buffer already exists */ + IDirectSoundBuffer8_AddRef(This->PrimaryBuffer); + *lplpDirectSoundBuffer = (LPDIRECTSOUNDBUFFER)This->PrimaryBuffer; + return S_OK; + } + + hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel); + if (SUCCEEDED(hResult)) + { + /* store primary buffer */ + This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer; + } + return hResult; + } + else + { + if (lpcDSBufferDesc->lpwfxFormat == NULL) + { + /* format must not be null */ + return DSERR_INVALIDPARAM; + } + + if (!This->PrimaryBuffer) + { + hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel); + if (SUCCEEDED(hResult)) + { + /* store primary buffer */ + This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer; + } + else + { + DPRINT("Failed to create primary buffer with %x\n", hResult); + return hResult; + } + + } + + ASSERT(This->PrimaryBuffer); + + DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n", + This, lpcDSBufferDesc->lpwfxFormat->wFormatTag, lpcDSBufferDesc->lpwfxFormat->nChannels, lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec, lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec, lpcDSBufferDesc->lpwfxFormat->nBlockAlign, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample, lpcDSBufferDesc->lpwfxFormat->cbSize); + + hResult = NewSecondarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc, This->PrimaryBuffer); + return hResult; + } +} + +HRESULT +WINAPI +IDirectSound8_fnGetCaps( + LPDIRECTSOUND8 iface, + LPDSCAPS lpDSCaps) +{ + UNIMPLEMENTED; + return DSERR_GENERIC; +} + +HRESULT +WINAPI +IDirectSound8_fnDuplicateSoundBuffer( + LPDIRECTSOUND8 iface, + LPDIRECTSOUNDBUFFER lpDsbOriginal, + LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate) +{ + UNIMPLEMENTED; + return DSERR_OUTOFMEMORY; +} + +HRESULT +WINAPI +IDirectSound8_fnSetCooperativeLevel( + LPDIRECTSOUND8 iface, + HWND hwnd, + DWORD dwLevel) +{ + LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); + + if (!This->bInitialized) + { + /* object not yet initialized */ + return DSERR_UNINITIALIZED; + } + + /* store cooperation level */ + This->dwLevel = dwLevel; + return DS_OK; +} + +HRESULT +WINAPI +IDirectSound8_fnCompact( + LPDIRECTSOUND8 iface) +{ + UNIMPLEMENTED; + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSound8_fnGetSpeakerConfig( + LPDIRECTSOUND8 iface, + LPDWORD pdwSpeakerConfig) +{ + UNIMPLEMENTED; + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSound8_fnSetSpeakerConfig( + LPDIRECTSOUND8 iface, + DWORD dwSpeakerConfig) +{ + UNIMPLEMENTED; + return DSERR_INVALIDPARAM; +} + + +HRESULT +WINAPI +IDirectSound8_fnInitialize( + LPDIRECTSOUND8 iface, + LPCGUID pcGuidDevice) +{ + GUID DeviceGuid; + LPOLESTR pGuidStr; + HRESULT hr; + LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); + + /* sanity check */ + ASSERT(RootInfo); + + if (This->bInitialized) + { + /* object has already been initialized */ + return DSERR_ALREADYINITIALIZED; + } + + /* fixme mutual exlucsion */ + + if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL)) + { + /* use default playback device id */ + pcGuidDevice = &DSDEVID_DefaultPlayback; + } + + /* now verify the guid */ + if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK) + { + if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr))) + { + DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr); + CoTaskMemFree(pGuidStr); + } + return DSERR_INVALIDPARAM; + } + + hr = FindDeviceByGuid(&DeviceGuid, &This->Filter); + + if (SUCCEEDED(hr)) + { + This->bInitialized = TRUE; + return DS_OK; + } + + DPRINT("Failed to find device\n"); + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +IDirectSound8_fnVerifyCertification( + LPDIRECTSOUND8 iface, + LPDWORD pdwCertified) +{ + UNIMPLEMENTED; + return DS_CERTIFIED; +} + +static IDirectSound8Vtbl vt_DirectSound8 = +{ + /* IUnknown methods */ + IDirectSound8_fnQueryInterface, + IDirectSound8_fnAddRef, + IDirectSound8_fnRelease, + /* IDirectSound methods */ + IDirectSound8_fnCreateSoundBuffer, + IDirectSound8_fnGetCaps, + IDirectSound8_fnDuplicateSoundBuffer, + IDirectSound8_fnSetCooperativeLevel, + IDirectSound8_fnCompact, + IDirectSound8_fnGetSpeakerConfig, + IDirectSound8_fnSetSpeakerConfig, + IDirectSound8_fnInitialize, + /* IDirectSound8 methods */ + IDirectSound8_fnVerifyCertification +}; + +HRESULT +InternalDirectSoundCreate( + LPCGUID lpcGUID, + LPDIRECTSOUND8 *ppDS, + IUnknown *pUnkOuter) +{ + LPCDirectSoundImpl This; + HRESULT hr; + + if (!ppDS || pUnkOuter != NULL) + { + /* invalid parameter passed */ + return DSERR_INVALIDPARAM; + } + + /* allocate CDirectSoundImpl struct */ + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundImpl)); + if (!This) + { + /* not enough memory */ + return DSERR_OUTOFMEMORY; + } + + /* initialize IDirectSound object */ + This->ref = 1; + This->lpVtbl = &vt_DirectSound8; + + + /* initialize direct sound interface */ + hr = IDirectSound8_Initialize((LPDIRECTSOUND8)&This->lpVtbl, lpcGUID); + + /* check for success */ + if (!SUCCEEDED(hr)) + { + /* failed */ + DPRINT("Failed to initialize DirectSound object with %x\n", hr); + IDirectSound8_Release((LPDIRECTSOUND8)&This->lpVtbl); + return hr; + } + + /* store result */ + *ppDS = (LPDIRECTSOUND8)&This->lpVtbl; + DPRINT("DirectSound object %p\n", *ppDS); + return DS_OK; +} + +HRESULT +WINAPI +DirectSoundCreate( + LPCGUID lpcGUID, + LPDIRECTSOUND *ppDS, + IUnknown *pUnkOuter) +{ + return InternalDirectSoundCreate(lpcGUID, (LPDIRECTSOUND8*)ppDS, pUnkOuter); +} + +HRESULT +WINAPI +DirectSoundCreate8( + LPCGUID lpcGUID, + LPDIRECTSOUND8 *ppDS, + IUnknown *pUnkOuter) +{ + return InternalDirectSoundCreate(lpcGUID, ppDS, pUnkOuter); +} diff --git a/reactos/dll/directx/dsound_new/dsound.c b/reactos/dll/directx/dsound_new/dsound.c new file mode 100644 index 00000000000..8743341e0b5 --- /dev/null +++ b/reactos/dll/directx/dsound_new/dsound.c @@ -0,0 +1,180 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/dsound.c + * PURPOSE: Handles DSound initialization + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + +#include "precomp.h" + +HINSTANCE dsound_hInstance; +LPFILTERINFO RootInfo = NULL; + +static INTERFACE_TABLE InterfaceTable[] = +{ + { + &CLSID_DirectSoundPrivate, + NewKsPropertySet + }, + { + NULL, + NULL + } +}; + + +HRESULT +WINAPI +DllCanUnloadNow() +{ + return S_FALSE; +} + +HRESULT +WINAPI +GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest) +{ + ULONG DeviceID = ULONG_MAX, Flags; + MMRESULT Result; + LPFILTERINFO Filter; + + if (!pGuidSrc || !pGuidDest) + { + /* invalid param */ + return DSERR_INVALIDPARAM; + } + + /* sanity check */ + ASSERT(!IsEqualGUID(pGuidSrc, &GUID_NULL)); + + if (IsEqualGUID(&DSDEVID_DefaultPlayback, pGuidSrc) || + IsEqualGUID(&DSDEVID_DefaultVoicePlayback, pGuidSrc)) + { + Result = waveOutMessage(UlongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&DeviceID, (DWORD_PTR)&Flags); + if (Result != MMSYSERR_NOERROR || DeviceID == ULONG_MAX) + { + /* hack */ + DPRINT1("Failed to get DRVM_MAPPER_PREFERRED_GET, using device 0\n"); + DeviceID = 0; + } + + if (!FindDeviceByMappedId(DeviceID, &Filter, TRUE)) + { + /* device not found */ + return DSERR_INVALIDPARAM; + } + + /* copy device guid */ + RtlMoveMemory(pGuidDest, &Filter->DeviceGuid[1], sizeof(GUID)); + return DS_OK; + } + else if (IsEqualGUID(&DSDEVID_DefaultCapture, pGuidSrc) || + IsEqualGUID(&DSDEVID_DefaultVoiceCapture, pGuidSrc)) + { + Result = waveInMessage(UlongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&DeviceID, (DWORD_PTR)&Flags); + if (Result != MMSYSERR_NOERROR || DeviceID == ULONG_MAX) + { + /* hack */ + DPRINT1("Failed to get DRVM_MAPPER_PREFERRED_GET, for record using device 0\n"); + DeviceID = 0; + } + + if (!FindDeviceByMappedId(DeviceID, &Filter, FALSE)) + { + /* device not found */ + return DSERR_INVALIDPARAM; + } + + /* copy device guid */ + RtlMoveMemory(pGuidDest, &Filter->DeviceGuid[0], sizeof(GUID)); + return DS_OK; + } + + if (!FindDeviceByGuid(pGuidSrc, &Filter)) + { + /* unknown guid */ + return DSERR_INVALIDPARAM; + } + + /* done */ + return DS_OK; +} + + +HRESULT +WINAPI +DllGetClassObject( + REFCLSID rclsid, + REFIID riid, + LPVOID* ppv +) +{ + LPOLESTR pStr, pStr2; + UINT i; + HRESULT hres = E_OUTOFMEMORY; + IClassFactory * pcf = NULL; + + if (!ppv) + return E_INVALIDARG; + + *ppv = NULL; + + for (i = 0; InterfaceTable[i].riid; i++) + { + if (IsEqualIID(InterfaceTable[i].riid, rclsid)) + { + pcf = IClassFactory_fnConstructor(InterfaceTable[i].lpfnCI, NULL, NULL); + break; + } + } + + if (!pcf) + { + StringFromIID(rclsid, &pStr); + StringFromIID(riid, &pStr2); + DPRINT("No Class Available for %ws IID %ws\n", pStr, pStr2); + CoTaskMemFree(pStr); + CoTaskMemFree(pStr2); + ASSERT(0); + return CLASS_E_CLASSNOTAVAILABLE; + } + + hres = IClassFactory_QueryInterface(pcf, riid, ppv); + IClassFactory_Release(pcf); + + return hres; +} + + + +BOOL +WINAPI +DllMain( + HINSTANCE hInstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + dsound_hInstance = hInstDLL; +#if 0 + DPRINT("NumDevs %u\n", waveOutGetNumDevs()); + if (EnumAudioDeviceInterfaces(&RootInfo) != S_OK) + { + DPRINT("EnumAudioDeviceInterfaces failed\n"); + RootInfo = NULL; + } +DPRINT1("EnumAudioDeviceInterfaces %p %u\n", RootInfo, waveOutGetNumDevs()); +#endif + DisableThreadLibraryCalls(dsound_hInstance); + break; + default: + break; + } + + return TRUE; +} + diff --git a/reactos/dll/directx/dsound_new/dsound.spec b/reactos/dll/directx/dsound_new/dsound.spec new file mode 100644 index 00000000000..e4878a81692 --- /dev/null +++ b/reactos/dll/directx/dsound_new/dsound.spec @@ -0,0 +1,14 @@ +1 stdcall DirectSoundCreate(ptr ptr ptr) +2 stdcall DirectSoundEnumerateA(ptr ptr) +3 stdcall DirectSoundEnumerateW(ptr ptr) +6 stdcall DirectSoundCaptureCreate(ptr ptr ptr) +7 stdcall DirectSoundCaptureEnumerateA(ptr ptr) +8 stdcall DirectSoundCaptureEnumerateW(ptr ptr) +9 stdcall GetDeviceID(ptr ptr) +10 stdcall DirectSoundFullDuplexCreate(ptr ptr ptr ptr long long ptr ptr ptr ptr) +11 stdcall DirectSoundCreate8(ptr ptr ptr) +12 stdcall DirectSoundCaptureCreate8(ptr ptr ptr) +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/dll/directx/dsound_new/dsound_new.rbuild b/reactos/dll/directx/dsound_new/dsound_new.rbuild new file mode 100644 index 00000000000..a7f1646a8fe --- /dev/null +++ b/reactos/dll/directx/dsound_new/dsound_new.rbuild @@ -0,0 +1,31 @@ + + + + + + . + uuid + ntdll + kernel32 + user32 + advapi32 + ole32 + winmm + dxguid + setupapi + ksuser + capture.c + capturebuffer.c + classfactory.c + devicelist.c + directsound.c + dsound.c + enum.c + misc.c + primary.c + property.c + regsvr.c + secondary.c + stubs.c + version.rc + diff --git a/reactos/dll/directx/dsound_new/enum.c b/reactos/dll/directx/dsound_new/enum.c new file mode 100644 index 00000000000..163c19ff2dc --- /dev/null +++ b/reactos/dll/directx/dsound_new/enum.c @@ -0,0 +1,229 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/enum.c + * PURPOSE: Handles DSound device enumeration + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + +#include "precomp.h" + +VOID +LoadResourceString( + UINT ResourceId, + LPVOID Buffer, + UINT ccount, + LPVOID DefaultString, + BOOL bUnicode) +{ + if (bUnicode) + { + /* load localized string */ + if (!LoadStringW(dsound_hInstance, ResourceId, (LPWSTR)Buffer, ccount)) + { + /* default device name */ + wcscpy((LPWSTR)Buffer, (LPWSTR)DefaultString); + } + } + else + { + /* load localized string */ + if (!LoadStringA(dsound_hInstance, ResourceId, (LPSTR)Buffer, ccount)) + { + /* default device name */ + strcpy((LPSTR)Buffer, (LPSTR)DefaultString); + } + } +} + + +BOOL +DoDSoundCallback( + LPDSENUMCALLBACKA lpDSEnumCallbackA, + LPDSENUMCALLBACKW lpDSEnumCallbackW, + LPGUID DeviceGuid, + UINT ResourceId, + LPWSTR ProductName, + LPWSTR DriverName, + LPVOID lpContext) +{ + WCHAR Buffer[200] = {0}; + char DriverNameA[200]; + + static LPWSTR SoundDriverW = L"Primary Sound Driver"; + static LPWSTR SoundDriverA = L"Primary Sound Driver"; + + if (lpDSEnumCallbackW) + { + if (ResourceId) + { + /* load resource string */ + Buffer[0] = 0; + LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(WCHAR), (LPVOID)SoundDriverW, TRUE); + Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = '\0'; + } + else + { + /* use passed string */ + ASSERT(ProductName); + wcscpy(Buffer, ProductName); + } + + /* perform callback */ + return lpDSEnumCallbackW(DeviceGuid, Buffer, DriverName, lpContext); + } + else + { + if (ResourceId) + { + /* load resource string */ + Buffer[0] = 0; + LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(char), (LPVOID)SoundDriverA, FALSE); + Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0; + } + else + { + /* use passed string */ + Buffer[0] = 0; + WideCharToMultiByte(CP_ACP, 0, ProductName, -1, (LPSTR)Buffer, sizeof(Buffer) / sizeof(char), NULL, NULL); + Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0; + } + + DriverNameA[0] = 0; + WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL); + + return lpDSEnumCallbackA(DeviceGuid, (LPSTR)Buffer, DriverNameA, lpContext); + } +} + + +HRESULT +DSoundEnumerate( + LPDSENUMCALLBACKA lpDSEnumCallbackA, + LPDSENUMCALLBACKW lpDSEnumCallbackW, + LPVOID lpContext, + BOOL bPlayback) +{ + ULONG ResourceId; + BOOL bResult; + LPFILTERINFO CurInfo; + WAVEOUTCAPSW WaveOutCaps; + WAVEINCAPSW WaveInCaps; + + if (!RootInfo) + { + EnumAudioDeviceInterfaces(&RootInfo); + } + + if (lpDSEnumCallbackA == NULL && lpDSEnumCallbackW == NULL) + { + DPRINT("No callback\n"); + return DSERR_INVALIDPARAM; + } + + if (bPlayback) + { + /* use resource id of playback string */ + ResourceId = IDS_PRIMARY_PLAYBACK_DEVICE; + } + else + { + /* use resource id of playback string */ + ResourceId = IDS_PRIMARY_RECORD_DEVICE; + } + + if (RootInfo) + { + /* perform first callback */ + bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, NULL, ResourceId, NULL, L"", lpContext); + if (!bResult) + { + /* callback asked as to stop */ + return DS_OK; + } + + /* now iterate through all devices */ + CurInfo = RootInfo; + + do + { + if (bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[1], &GUID_NULL)) + { + RtlZeroMemory(&WaveOutCaps, sizeof(WAVEOUTCAPSW)); + + /* sanity check */ + ASSERT(CurInfo->MappedId[1] != ULONG_MAX); + + /* get wave out caps */ + waveOutGetDevCapsW((UINT_PTR)CurInfo->MappedId[1], &WaveOutCaps, sizeof(WAVEOUTCAPSW)); + WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0'; + + bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[1], 0, WaveOutCaps.szPname, L"" /* FIXME */, lpContext); + if (!bResult) + { + /* callback asked as to stop */ + return DS_OK; + } + } + else if (!bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[0], &GUID_NULL)) + { + RtlZeroMemory(&WaveInCaps, sizeof(WAVEINCAPSW)); + + /* sanity check */ + ASSERT(CurInfo->MappedId[1] != ULONG_MAX); + + /* get wave in caps */ + waveInGetDevCapsW((UINT_PTR)CurInfo->MappedId[0], &WaveInCaps, sizeof(WAVEINCAPSW)); + WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0'; + + bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[0], 0, WaveInCaps.szPname, L"" /* FIXME */, lpContext); + if (!bResult) + { + /* callback asked as to stop */ + return DS_OK; + } + } + + /* move to next entry */ + CurInfo = CurInfo->lpNext; + }while(CurInfo); + } + return DS_OK; +} + +HRESULT +WINAPI +DirectSoundEnumerateA( + LPDSENUMCALLBACKA lpDSEnumCallback, + LPVOID lpContext) +{ + return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, TRUE); +} + +HRESULT +WINAPI +DirectSoundEnumerateW( + LPDSENUMCALLBACKW lpDSEnumCallback, + LPVOID lpContext ) +{ + return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, TRUE); +} + +HRESULT +WINAPI +DirectSoundCaptureEnumerateA( + LPDSENUMCALLBACKA lpDSEnumCallback, + LPVOID lpContext) +{ + return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, FALSE); +} + +HRESULT +WINAPI +DirectSoundCaptureEnumerateW( + LPDSENUMCALLBACKW lpDSEnumCallback, + LPVOID lpContext) +{ + return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, FALSE); +} diff --git a/reactos/dll/directx/dsound_new/misc.c b/reactos/dll/directx/dsound_new/misc.c new file mode 100644 index 00000000000..9c7b9829e45 --- /dev/null +++ b/reactos/dll/directx/dsound_new/misc.c @@ -0,0 +1,316 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/misc.c + * PURPOSE: Misc support routines + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + +#include "precomp.h" + +const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_Audio = {0x45FFAAA0L, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; + +DWORD +OpenPin( + HANDLE hFilter, + ULONG PinId, + LPWAVEFORMATEX WaveFormatEx, + PHANDLE hPin, + BOOL bLoop) +{ + DWORD Size, Result; + PKSPIN_CONNECT PinConnect; + PKSDATAFORMAT_WAVEFORMATEX DataFormat; + + /* calculate request size */ + Size = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX); + + PinConnect = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size); + if (!PinConnect) + { + /* not enough memory */ + return DSERR_OUTOFMEMORY; + } + /* build pin request */ + PinConnect->Interface.Set = KSINTERFACESETID_Standard; + + if (bLoop) + PinConnect->Interface.Id = KSINTERFACE_STANDARD_LOOPED_STREAMING; + else + PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; + + PinConnect->Interface.Flags = 0; + PinConnect->Medium.Set = KSMEDIUMSETID_Standard; + PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; + PinConnect->Medium.Flags = 0; + PinConnect->PinToHandle = NULL; + PinConnect->PinId = PinId; + PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; + PinConnect->Priority.PrioritySubClass = 1; + + DataFormat = (PKSDATAFORMAT_WAVEFORMATEX) (PinConnect + 1); + + /* initialize data format */ + DataFormat->WaveFormatEx.wFormatTag = WaveFormatEx->wFormatTag; + DataFormat->WaveFormatEx.nChannels = WaveFormatEx->nChannels; + DataFormat->WaveFormatEx.nSamplesPerSec = WaveFormatEx->nSamplesPerSec; + DataFormat->WaveFormatEx.nBlockAlign = WaveFormatEx->nBlockAlign; + DataFormat->WaveFormatEx.nAvgBytesPerSec = WaveFormatEx->nAvgBytesPerSec; + DataFormat->WaveFormatEx.wBitsPerSample = WaveFormatEx->wBitsPerSample; + DataFormat->WaveFormatEx.cbSize = 0; + DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX); + DataFormat->DataFormat.Flags = 0; + DataFormat->DataFormat.Reserved = 0; + DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; + + DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; + DataFormat->DataFormat.SampleSize = 4; + + Result = KsCreatePin(hFilter, PinConnect, GENERIC_READ | GENERIC_WRITE, hPin); + + HeapFree(GetProcessHeap(), 0, PinConnect); + + return Result; +} + + +DWORD +OpenFilter( + IN LPCWSTR lpFileName, + IN PHANDLE OutHandle) +{ + HANDLE Handle; + + /* open the filter */ + Handle = CreateFileW(lpFileName, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + + /* check for success */ + if (Handle == INVALID_HANDLE_VALUE) + { + DPRINT("Failed to open Filter %ws\n", lpFileName); + return GetLastError(); + } + + *OutHandle = Handle; + return ERROR_SUCCESS; +} + +DWORD +SyncOverlappedDeviceIoControl( + IN HANDLE Handle, + IN DWORD IoControlCode, + IN LPVOID InBuffer, + IN DWORD InBufferSize, + OUT LPVOID OutBuffer, + IN DWORD OutBufferSize, + OUT LPDWORD BytesTransferred OPTIONAL) +{ + OVERLAPPED Overlapped; + BOOLEAN IoResult; + DWORD Transferred; + + /* Overlapped I/O is done here - this is used for waiting for completion */ + ZeroMemory(&Overlapped, sizeof(OVERLAPPED)); + Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + if (!Overlapped.hEvent) + return GetLastError(); + + /* Talk to the device */ + IoResult = DeviceIoControl(Handle, + IoControlCode, + InBuffer, + InBufferSize, + OutBuffer, + OutBufferSize, + BytesTransferred, + &Overlapped); + + /* If failure occurs, make sure it's not just due to the overlapped I/O */ + if (!IoResult) + { + if ( GetLastError() != ERROR_IO_PENDING ) + { + CloseHandle(Overlapped.hEvent); + return GetLastError(); + } + } + + /* Wait for the I/O to complete */ + IoResult = GetOverlappedResult(Handle, + &Overlapped, + &Transferred, + TRUE); + + /* Don't need this any more */ + CloseHandle(Overlapped.hEvent); + + if (!IoResult) + return GetLastError(); + + if ( BytesTransferred ) + *BytesTransferred = Transferred; + + return ERROR_SUCCESS; +} + +DWORD +GetFilterPinCount( + IN HANDLE hFilter, + OUT PULONG NumPins) +{ + KSPROPERTY Pin; + + *NumPins = 0; + + /* setup the pin request */ + Pin.Flags = KSPROPERTY_TYPE_GET; + Pin.Set = KSPROPSETID_Pin; + Pin.Id = KSPROPERTY_PIN_CTYPES; + + /* query the device */ + return SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Pin, sizeof(KSPROPERTY), (PVOID)NumPins, sizeof(ULONG), NULL); +} + +DWORD +GetFilterNodeProperty( + IN HANDLE hFilter, + IN ULONG PropertyId, + OUT PKSMULTIPLE_ITEM *OutMultipleItem) +{ + DWORD Status, BytesReturned; + PKSMULTIPLE_ITEM MultipleItem; + KSPROPERTY Property; + + /* setup query request */ + Property.Id = PropertyId; + Property.Flags = KSPROPERTY_TYPE_GET; + Property.Set = KSPROPSETID_Topology; + + /* query the size */ + Status = SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &BytesReturned); + + if (Status != ERROR_MORE_DATA) + { + /* failed */ + DPRINT("Failed to query PropertyId %lu ErrorCode %lx\n", PropertyId, Status); + return Status; + } + + MultipleItem = HeapAlloc(GetProcessHeap(), 0, BytesReturned); + if (!MultipleItem) + { + /* not enough memory */ + DPRINT("Failed to allocate %u Bytes\n", BytesReturned); + return ERROR_OUTOFMEMORY; + } + + /* retrieve data ranges */ + Status = SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), (LPVOID)MultipleItem, BytesReturned, &BytesReturned); + + + if (Status != ERROR_SUCCESS) + { + /* failed to get data ranges */ + DPRINT("SyncOverlappedDeviceIoControl failed with %lx\n", Status); + + HeapFree(GetProcessHeap(), 0, MultipleItem); + return Status; + } + + /* save result */ + *OutMultipleItem = MultipleItem; + return Status; + +} + +DWORD +GetFilterPinCommunication( + IN HANDLE hFilter, + IN ULONG PinId, + OUT PKSPIN_COMMUNICATION Communication) +{ + KSP_PIN Property; + + Property.Property.Flags = KSPROPERTY_TYPE_GET; + Property.Property.Set = KSPROPSETID_Pin; + Property.Property.Id = KSPROPERTY_PIN_COMMUNICATION; + Property.PinId = PinId; + Property.Reserved = 0; + + return SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), (LPVOID)Communication, sizeof(KSPIN_COMMUNICATION), NULL); +} + +DWORD +GetFilterPinDataFlow( + IN HANDLE hFilter, + IN ULONG PinId, + OUT PKSPIN_DATAFLOW DataFlow) +{ + KSP_PIN Property; + + Property.Property.Flags = KSPROPERTY_TYPE_GET; + Property.Property.Set = KSPROPSETID_Pin; + Property.Property.Id = KSPROPERTY_PIN_DATAFLOW; + Property.PinId = PinId; + Property.Reserved = 0; + + return SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), (LPVOID)DataFlow, sizeof(KSPIN_DATAFLOW), NULL); +} + +DWORD +GetFilterPinDataRanges( + IN HANDLE hFilter, + IN ULONG PinId, + IN OUT PKSMULTIPLE_ITEM * OutMultipleItem) +{ + KSP_PIN Property; + ULONG BytesReturned = 0; + DWORD Status; + PKSMULTIPLE_ITEM MultipleItem; + + /* prepare request */ + Property.Reserved = 0; + Property.PinId = PinId; + Property.Property.Set = KSPROPSETID_Pin; + Property.Property.Id = KSPROPERTY_PIN_DATARANGES; + Property.Property.Flags = KSPROPERTY_TYPE_GET; + + /* retrieve size of data ranges buffer */ + Status = SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned); + + if (Status != ERROR_MORE_DATA) + { + DPRINT("SyncOverlappedDeviceIoControl failed with %lx\n", Status); + return Status; + } + + MultipleItem = HeapAlloc(GetProcessHeap(), 0, BytesReturned); + if (!MultipleItem) + { + /* not enough memory */ + DPRINT("Failed to allocate %u Bytes\n", BytesReturned); + return ERROR_OUTOFMEMORY; + } + + /* retrieve data ranges */ + Status = SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), (LPVOID)MultipleItem, BytesReturned, &BytesReturned); + + + if (Status != ERROR_SUCCESS) + { + /* failed to get data ranges */ + DPRINT("SyncOverlappedDeviceIoControl failed with %lx\n", Status); + + HeapFree(GetProcessHeap(), 0, MultipleItem); + return Status; + } + + /* save result */ + *OutMultipleItem = MultipleItem; + return Status; +} diff --git a/reactos/dll/directx/dsound_new/precomp.h b/reactos/dll/directx/dsound_new/precomp.h new file mode 100644 index 00000000000..fb80d8b3626 --- /dev/null +++ b/reactos/dll/directx/dsound_new/precomp.h @@ -0,0 +1,209 @@ +#ifndef PRECOMP_H__ +#define PRECOMP_H__ + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define YDEBUG +#include +#include +#include +#include +#include + +#include "resource.h" + + +/* factory method */ +typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject); + +/* factory table */ +typedef struct +{ + REFIID riid; + LPFNCREATEINSTANCE lpfnCI; +} INTERFACE_TABLE; + + +typedef struct tagFILTERINFO +{ + SP_DEVINFO_DATA DeviceData; + WCHAR DevicePath[MAX_PATH]; + HANDLE hFilter; + ULONG PinCount; + PULONG Pin; + GUID DeviceGuid[2]; + ULONG MappedId[2]; + + struct tagFILTERINFO *lpNext; +}FILTERINFO, *LPFILTERINFO; + +#define INIT_GUID(guid, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + guid.Data1 = l; guid.Data2 = w1; guid.Data3 = w2; \ + guid.Data4[0] = b1; guid.Data4[1] = b2; guid.Data4[2] = b3; \ + guid.Data4[3] = b4; guid.Data4[4] = b5; guid.Data4[5] = b6; \ + guid.Data4[6] = b7; guid.Data4[7] = b8; + +typedef enum +{ + PIN_TYPE_NONE = 0, + PIN_TYPE_PLAYBACK = 1, + PIN_TYPE_RECORDING = 2 +}PIN_TYPE; + +/* globals */ +extern HINSTANCE dsound_hInstance; +extern LPFILTERINFO RootInfo; + +/* classfactory.c */ + +IClassFactory * +IClassFactory_fnConstructor( + LPFNCREATEINSTANCE lpfnCI, + PLONG pcRefDll, + REFIID riidInst); + + +/* devicelist.c */ + +HRESULT +EnumAudioDeviceInterfaces( + LPFILTERINFO *OutRootInfo); + +BOOL +FindDeviceByGuid( + LPCGUID pGuidSrc, + LPFILTERINFO *Filter); + +BOOL +FindDeviceByMappedId( + IN ULONG DeviceID, + LPFILTERINFO *Filter, + BOOL bPlayback); + +ULONG +GetPinIdFromFilter( + LPFILTERINFO Filter, + BOOL bCapture, + ULONG Offset); + + +/* misc.c */ + +DWORD +SyncOverlappedDeviceIoControl( + IN HANDLE Handle, + IN DWORD IoControlCode, + IN LPVOID InBuffer, + IN DWORD InBufferSize, + OUT LPVOID OutBuffer, + IN DWORD OutBufferSize, + OUT LPDWORD BytesTransferred OPTIONAL); + +DWORD +PrimaryDirectSoundBuffer_Write( + LPDIRECTSOUNDBUFFER8 iface, + LPVOID Buffer, + DWORD BufferSize); + + +DWORD +OpenPin( + HANDLE hFilter, + ULONG PinId, + LPWAVEFORMATEX WaveFormatEx, + PHANDLE hPin, + BOOL bLoop); + +DWORD +OpenFilter( + IN LPCWSTR lpFileName, + IN PHANDLE OutHandle); + +DWORD +GetFilterPinCount( + IN HANDLE hFilter, + OUT PULONG NumPins); + +DWORD +GetFilterPinCommunication( + IN HANDLE hFilter, + IN ULONG PinId, + OUT PKSPIN_COMMUNICATION Communication); + +DWORD +GetFilterPinDataFlow( + IN HANDLE hFilter, + IN ULONG PinId, + OUT PKSPIN_DATAFLOW DataFlow); + +/* primary.c */ + +HRESULT +PrimaryDirectSoundBuffer_GetPosition( + LPDIRECTSOUNDBUFFER8 iface, + LPDWORD pdwCurrentPlayCursor, + LPDWORD pdwCurrentWriteCursor); + +VOID +PrimaryDirectSoundBuffer_SetState( + LPDIRECTSOUNDBUFFER8 iface, + KSSTATE State); + +HRESULT +NewPrimarySoundBuffer( + LPDIRECTSOUNDBUFFER8 *OutBuffer, + LPFILTERINFO Filter, + DWORD dwLevel); + +HRESULT +PrimaryDirectSoundBuffer_SetFormat( + LPDIRECTSOUNDBUFFER8 iface, + LPWAVEFORMATEX pcfxFormat, + BOOL bLooped); + +VOID +PrimaryDirectSoundBuffer_AcquireLock( + LPDIRECTSOUNDBUFFER8 iface); + +VOID +PrimaryDirectSoundBuffer_ReleaseLock( + LPDIRECTSOUNDBUFFER8 iface); + +/* secondary.c */ + +HRESULT +NewSecondarySoundBuffer( + LPDIRECTSOUNDBUFFER8 *OutBuffer, + LPFILTERINFO Filter, + DWORD dwLevel, + LPCDSBUFFERDESC lpcDSBufferDesc, + LPDIRECTSOUNDBUFFER8 PrimaryBuffer); + +/* property.c */ +HRESULT +CALLBACK +NewKsPropertySet( + IUnknown* pUnkOuter, + REFIID riid, + LPVOID* ppvObject); + +/* capturebuffer.c */ +HRESULT +NewDirectSoundCaptureBuffer( + LPDIRECTSOUNDCAPTUREBUFFER8 *OutBuffer, + LPFILTERINFO Filter, + LPCDSCBUFFERDESC lpcDSBufferDesc); + +#endif diff --git a/reactos/dll/directx/dsound_new/primary.c b/reactos/dll/directx/dsound_new/primary.c new file mode 100644 index 00000000000..e3820e8c659 --- /dev/null +++ b/reactos/dll/directx/dsound_new/primary.c @@ -0,0 +1,595 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/primary.c + * PURPOSE: Primary IDirectSoundBuffer8 implementation + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + + +#include "precomp.h" + +typedef struct +{ + const IDirectSoundBuffer8Vtbl *lpVtbl; + LONG ref; + + LPFILTERINFO Filter; + DWORD dwLevel; + WAVEFORMATEX Format; + HANDLE hPin; + CRITICAL_SECTION Lock; + KSSTATE State; +}CDirectSoundBuffer, *LPCDirectSoundBuffer; + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnQueryInterface( + LPDIRECTSOUNDBUFFER8 iface, + IN REFIID riid, + LPVOID* ppobj) +{ + LPOLESTR pStr; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDirectSoundBuffer) || + IsEqualIID(riid, &IID_IDirectSoundBuffer8)) + { + *ppobj = (LPVOID)&This->lpVtbl; + InterlockedIncrement(&This->ref); + return S_OK; + } + + if (SUCCEEDED(StringFromIID(riid, &pStr))) + { + DPRINT("No Interface for class %s\n", pStr); + CoTaskMemFree(pStr); + } + return E_NOINTERFACE; +} + +ULONG +WINAPI +PrimaryDirectSoundBuffer8Impl_fnAddRef( + LPDIRECTSOUNDBUFFER8 iface) +{ + ULONG ref; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + ref = InterlockedIncrement(&This->ref); + + return ref; + +} + +ULONG +WINAPI +PrimaryDirectSoundBuffer8Impl_fnRelease( + LPDIRECTSOUNDBUFFER8 iface) +{ + ULONG ref; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + ref = InterlockedDecrement(&(This->ref)); + + if (!ref) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnGetCaps( + LPDIRECTSOUNDBUFFER8 iface, + LPDSBCAPS pDSBufferCaps) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition( + LPDIRECTSOUNDBUFFER8 iface, + LPDWORD pdwCurrentPlayCursor, + LPDWORD pdwCurrentWriteCursor) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnGetFormat( + LPDIRECTSOUNDBUFFER8 iface, + LPWAVEFORMATEX pwfxFormat, + DWORD dwSizeAllocated, + LPDWORD pdwSizeWritten) +{ + DWORD FormatSize; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + FormatSize = sizeof(WAVEFORMATEX) + This->Format.cbSize; + + if (!pwfxFormat && !pdwSizeWritten) + { + /* invalid parameter */ + return DSERR_INVALIDPARAM; + } + + if (!pwfxFormat) + { + /* return required format size */ + *pdwSizeWritten = FormatSize; + return DS_OK; + } + else + { + if (dwSizeAllocated >= FormatSize) + { + /* copy format */ + CopyMemory(pwfxFormat, &This->Format, FormatSize); + + if (pdwSizeWritten) + *pdwSizeWritten = FormatSize; + + return DS_OK; + } + /* buffer too small */ + if (pdwSizeWritten) + *pdwSizeWritten = 0; + + return DSERR_INVALIDPARAM; + } +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnGetVolume( + LPDIRECTSOUNDBUFFER8 iface, + LPLONG plVolume) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnGetPan( + LPDIRECTSOUNDBUFFER8 iface, + LPLONG plPan) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnGetFrequency( + LPDIRECTSOUNDBUFFER8 iface, + LPDWORD pdwFrequency) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnGetStatus( + LPDIRECTSOUNDBUFFER8 iface, + LPDWORD pdwStatus) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnInitialize( + LPDIRECTSOUNDBUFFER8 iface, + LPDIRECTSOUND pDirectSound, + LPCDSBUFFERDESC pcDSBufferDesc) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnLock( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwOffset, + DWORD dwBytes, + LPVOID *ppvAudioPtr1, + LPDWORD pdwAudioBytes1, + LPVOID *ppvAudioPtr2, + LPDWORD pdwAudioBytes2, + DWORD dwFlags) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnPlay( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwReserved1, + DWORD dwPriority, + DWORD dwFlags) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwNewPosition) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnSetFormat( + LPDIRECTSOUNDBUFFER8 iface, + LPCWAVEFORMATEX pcfxFormat) +{ + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + if (This->dwLevel == DSSCL_NORMAL) + { + /* can't change format with this level */ + return DSERR_PRIOLEVELNEEDED; + } + + ASSERT(pcfxFormat->cbSize == 0); + + + DPRINT("This %p Format: Tag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u nBlockAlign %u wBitsPerSample %u cbSize %u\n", This, + pcfxFormat->wFormatTag, pcfxFormat->nChannels, pcfxFormat->nSamplesPerSec, pcfxFormat->nAvgBytesPerSec, pcfxFormat->nBlockAlign, pcfxFormat->wBitsPerSample, pcfxFormat->cbSize); + + CopyMemory(&This->Format, pcfxFormat, sizeof(WAVEFORMATEX)); + + return DS_OK; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnSetVolume( + LPDIRECTSOUNDBUFFER8 iface, + LONG lVolume) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnSetPan( + LPDIRECTSOUNDBUFFER8 iface, + LONG lPan) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnSetFrequency( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwFrequency) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnStop( + LPDIRECTSOUNDBUFFER8 iface) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnUnlock( + LPDIRECTSOUNDBUFFER8 iface, + LPVOID pvAudioPtr1, + DWORD dwAudioBytes1, + LPVOID pvAudioPtr2, + DWORD dwAudioBytes2) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + + + + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnRestore( + LPDIRECTSOUNDBUFFER8 iface) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnSetFX( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwEffectsCount, + LPDSEFFECTDESC pDSFXDesc, + LPDWORD pdwResultCodes) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnAcquireResources( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwFlags, + DWORD dwEffectsCount, + LPDWORD pdwResultCodes) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath( + LPDIRECTSOUNDBUFFER8 iface, + REFGUID rguidObject, + DWORD dwIndex, + REFGUID rguidInterface, + LPVOID *ppObject) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8 = +{ + /* IUnknown methods */ + PrimaryDirectSoundBuffer8Impl_fnQueryInterface, + PrimaryDirectSoundBuffer8Impl_fnAddRef, + PrimaryDirectSoundBuffer8Impl_fnRelease, + /* IDirectSoundBuffer methods */ + PrimaryDirectSoundBuffer8Impl_fnGetCaps, + PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition, + PrimaryDirectSoundBuffer8Impl_fnGetFormat, + PrimaryDirectSoundBuffer8Impl_fnGetVolume, + PrimaryDirectSoundBuffer8Impl_fnGetPan, + PrimaryDirectSoundBuffer8Impl_fnGetFrequency, + PrimaryDirectSoundBuffer8Impl_fnGetStatus, + PrimaryDirectSoundBuffer8Impl_fnInitialize, + PrimaryDirectSoundBuffer8Impl_fnLock, + PrimaryDirectSoundBuffer8Impl_fnPlay, + PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition, + PrimaryDirectSoundBuffer8Impl_fnSetFormat, + PrimaryDirectSoundBuffer8Impl_fnSetVolume, + PrimaryDirectSoundBuffer8Impl_fnSetPan, + PrimaryDirectSoundBuffer8Impl_fnSetFrequency, + PrimaryDirectSoundBuffer8Impl_fnStop, + PrimaryDirectSoundBuffer8Impl_fnUnlock, + PrimaryDirectSoundBuffer8Impl_fnRestore, + /* IDirectSoundBuffer8 methods */ + PrimaryDirectSoundBuffer8Impl_fnSetFX, + PrimaryDirectSoundBuffer8Impl_fnAcquireResources, + PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath +}; + +DWORD +PrimaryDirectSoundBuffer_Write( + LPDIRECTSOUNDBUFFER8 iface, + LPVOID Buffer, + DWORD BufferSize) +{ + KSSTREAM_HEADER Header; + DWORD Result, BytesTransferred; + OVERLAPPED Overlapped; + + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + ZeroMemory(&Overlapped, sizeof(OVERLAPPED)); + Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + + ASSERT(This->hPin); + ZeroMemory(&Header, sizeof(KSSTREAM_HEADER)); + + Header.FrameExtent = BufferSize; + Header.DataUsed = BufferSize; + Header.Data = Buffer; + Header.Size = sizeof(KSSTREAM_HEADER); + Header.PresentationTime.Numerator = 1; + Header.PresentationTime.Denominator = 1; + + Result = DeviceIoControl(This->hPin, IOCTL_KS_WRITE_STREAM, NULL, 0, &Header, sizeof(KSSTREAM_HEADER), &BytesTransferred, &Overlapped); + + if (Result != ERROR_SUCCESS) + return 0; + + return BytesTransferred; +} + +VOID +PrimaryDirectSoundBuffer_SetState( + LPDIRECTSOUNDBUFFER8 iface, + KSSTATE State) +{ + KSPROPERTY Property; + DWORD Result, BytesTransferred; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + if (This->State == State) + return; + + Property.Set = KSPROPSETID_Connection; + Property.Id = KSPROPERTY_CONNECTION_STATE; + Property.Flags = KSPROPERTY_TYPE_SET; + + Result = SyncOverlappedDeviceIoControl(This->hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesTransferred); + if (Result == ERROR_SUCCESS) + { + This->State = State; + } +} + +HRESULT +PrimaryDirectSoundBuffer_GetPosition( + LPDIRECTSOUNDBUFFER8 iface, + LPDWORD pdwCurrentPlayCursor, + LPDWORD pdwCurrentWriteCursor) +{ + KSAUDIO_POSITION Position; + KSPROPERTY Request; + DWORD Result; + + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + if (!This->hPin) + { + if (pdwCurrentPlayCursor) + *pdwCurrentPlayCursor = 0; + + if (pdwCurrentWriteCursor) + *pdwCurrentWriteCursor = 0; + + DPRINT("No Audio Pin\n"); + return DS_OK; + } + + /* setup audio position property request */ + Request.Id = KSPROPERTY_AUDIO_POSITION; + Request.Set = KSPROPSETID_Audio; + Request.Flags = KSPROPERTY_TYPE_GET; + + + Result = SyncOverlappedDeviceIoControl(This->hPin, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSPROPERTY), (PVOID)&Position, sizeof(KSAUDIO_POSITION), NULL); + + if (Result != ERROR_SUCCESS) + { + DPRINT("GetPosition failed with %x\n", Result); + return DSERR_UNSUPPORTED; + } + + //DPRINT("Play %I64u Write %I64u \n", Position.PlayOffset, Position.WriteOffset); + + if (pdwCurrentPlayCursor) + *pdwCurrentPlayCursor = (DWORD)Position.PlayOffset; + + if (pdwCurrentWriteCursor) + *pdwCurrentWriteCursor = (DWORD)Position.WriteOffset; + + return DS_OK; +} + +HRESULT +PrimaryDirectSoundBuffer_SetFormat( + LPDIRECTSOUNDBUFFER8 iface, + LPWAVEFORMATEX pcfxFormat, + BOOL bLooped) +{ + ULONG PinId, DeviceId = 0, Result; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + if (This->hPin) + { + /* fixme change format */ + ASSERT(0); + } + + do + { + /* try all available recording pins on that filter */ + PinId = GetPinIdFromFilter(This->Filter, FALSE, DeviceId); + DPRINT("PinId %u DeviceId %u\n", PinId, DeviceId); + + if (PinId == ULONG_MAX) + break; + + Result = OpenPin(This->Filter->hFilter, PinId, (LPWAVEFORMATEX)pcfxFormat, &This->hPin, bLooped); + DPRINT("PinId %u Result %u\n", PinId, Result); + if (Result == ERROR_SUCCESS) + break; + + This->hPin = NULL; + DeviceId++; + }while(TRUE); + + if (!This->hPin) + { + DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat failed\n"); + return DSERR_INVALIDPARAM; + } + + DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat success\n"); + return DS_OK; +} + +VOID +PrimaryDirectSoundBuffer_AcquireLock( + LPDIRECTSOUNDBUFFER8 iface) +{ + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + EnterCriticalSection(&This->Lock); + + +} + +VOID +PrimaryDirectSoundBuffer_ReleaseLock( + LPDIRECTSOUNDBUFFER8 iface) +{ + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + LeaveCriticalSection(&This->Lock); + +} + + +HRESULT +NewPrimarySoundBuffer( + LPDIRECTSOUNDBUFFER8 *OutBuffer, + LPFILTERINFO Filter, + DWORD dwLevel) +{ + LPCDirectSoundBuffer This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundBuffer)); + + if (!This) + { + /* not enough memory */ + return DSERR_OUTOFMEMORY; + } + + This->ref = 1; + This->lpVtbl = &vt_DirectSoundBuffer8; + This->Filter = Filter; + This->dwLevel = dwLevel; + This->hPin = NULL; + + InitializeCriticalSection(&This->Lock); + + *OutBuffer = (LPDIRECTSOUNDBUFFER8)&This->lpVtbl; + return DS_OK; +} + diff --git a/reactos/dll/directx/dsound_new/property.c b/reactos/dll/directx/dsound_new/property.c new file mode 100644 index 00000000000..b06238a6b5b --- /dev/null +++ b/reactos/dll/directx/dsound_new/property.c @@ -0,0 +1,273 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/secondary.c + * PURPOSE: Secondary IDirectSoundBuffer8 implementation + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + + +#include "precomp.h" + +typedef struct +{ + IKsPropertySetVtbl *lpVtbl; + LONG ref; + +}CKsPropertySetImpl, *LPCKsPropertySetImpl; + +HRESULT +WINAPI +KSPropertySetImpl_fnQueryInterface( + LPKSPROPERTYSET iface, + REFIID riid, + LPVOID * ppobj) +{ + LPOLESTR pStr; + LPCKsPropertySetImpl This = (LPCKsPropertySetImpl)CONTAINING_RECORD(iface, CKsPropertySetImpl, lpVtbl); + + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IKsPropertySet)) + { + *ppobj = (LPVOID)&This->lpVtbl; + InterlockedIncrement(&This->ref); + return S_OK; + } + + if (SUCCEEDED(StringFromIID(riid, &pStr))) + { + DPRINT("No Interface for riid %s\n", pStr); + CoTaskMemFree(pStr); + } + return E_NOINTERFACE; +} + +ULONG +WINAPI +KSPropertySetImpl_fnAddRef( + LPKSPROPERTYSET iface) +{ + ULONG ref; + LPCKsPropertySetImpl This = (LPCKsPropertySetImpl)CONTAINING_RECORD(iface, CKsPropertySetImpl, lpVtbl); + + ref = InterlockedIncrement(&This->ref); + + return ref; +} + +ULONG +WINAPI +KSPropertySetImpl_fnRelease( + LPKSPROPERTYSET iface) +{ + ULONG ref; + LPCKsPropertySetImpl This = (LPCKsPropertySetImpl)CONTAINING_RECORD(iface, CKsPropertySetImpl, lpVtbl); + + ref = InterlockedDecrement(&(This->ref)); + + if (!ref) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + + +HRESULT +WINAPI +KSPropertySetImpl_Get( + LPKSPROPERTYSET iface, + REFGUID guidPropSet, + ULONG dwPropID, + LPVOID pInstanceData, + ULONG cbInstanceData, + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned ) +{ + LPOLESTR pStr; + //HRESULT hr; + MMRESULT Result; + WAVEINCAPSW CapsIn; + WAVEOUTCAPSW CapsOut; + + GUID DeviceGuid; + LPFILTERINFO Filter = NULL; + PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA Desc; + + StringFromIID(guidPropSet, &pStr); + + //DPRINT("Requested Property %ws dwPropID %u pInstanceData %p cbInstanceData %u pPropData %p cbPropData %u pcbReturned %p\n", + // pStr, dwPropID, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned); + CoTaskMemFree(pStr); + + if (!IsEqualGUID(guidPropSet, &DSPROPSETID_DirectSoundDevice)) + { + /* unsupported property set */ + return E_PROP_ID_UNSUPPORTED; + } + + if (dwPropID == DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1) + { + if (cbPropData < sizeof(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA)) + { + /* invalid parameter */ + return DSERR_INVALIDPARAM; + } + + Desc = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA)pPropData; + + if (IsEqualGUID(&Desc->DeviceId, &GUID_NULL)) + { + if (Desc->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) + { + DPRINT("Using default capture guid\n"); + CopyMemory(&DeviceGuid, &DSDEVID_DefaultCapture, sizeof(GUID)); + } + else + { + DPRINT("Using default capture guid\n"); + CopyMemory(&DeviceGuid, &DSDEVID_DefaultPlayback, sizeof(GUID)); + } + } + else + { + /* use provided guid */ + CopyMemory(&DeviceGuid, &Desc->DeviceId, sizeof(GUID)); + } + + if (GetDeviceID(&DeviceGuid, &Desc->DeviceId) != DS_OK) + { + DPRINT("Unknown device guid\n"); + return DSERR_INVALIDPARAM; + } + + /* sanity check */ + ASSERT(FindDeviceByGuid(&Desc->DeviceId, &Filter)); + ASSERT(Filter != NULL); + + /* fill in description */ + if (IsEqualGUID(&Desc->DeviceId, &Filter->DeviceGuid[0])) + { + /* capture device */ + Desc->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; + Desc->WaveDeviceId = Filter->MappedId[0]; + + Result = waveInGetDevCapsW(Filter->MappedId[0], &CapsIn, sizeof(WAVEINCAPSW)); + if (Result != MMSYSERR_NOERROR) + { + CapsIn.szPname[0] = 0; + DPRINT("waveInGetDevCaps Device %u failed with %x\n", Filter->MappedId[0], Result); + } + + CapsIn.szPname[MAXPNAMELEN-1] = 0; + wcscpy(Desc->DescriptionW, CapsIn.szPname); + WideCharToMultiByte(CP_ACP, 0, CapsIn.szPname, -1, Desc->DescriptionA, sizeof(Desc->DescriptionA), NULL, NULL); + + } + else + { + /* render device */ + Desc->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; + Desc->WaveDeviceId = Filter->MappedId[1]; + + Result = waveOutGetDevCapsW(Filter->MappedId[1], &CapsOut, sizeof(WAVEOUTCAPSW)); + if (Result != MMSYSERR_NOERROR) + { + CapsOut.szPname[0] = 0; + DPRINT("waveOutGetDevCaps Device %u failed with %x\n", Filter->MappedId[1], Result); + } + + CapsOut.szPname[MAXPNAMELEN-1] = 0; + wcscpy(Desc->DescriptionW, CapsOut.szPname); + WideCharToMultiByte(CP_ACP, 0, CapsOut.szPname, -1, Desc->DescriptionA, sizeof(Desc->DescriptionA), NULL, NULL); + } + + /* ReactOS doesnt support vxd or emulated */ + Desc->Type = DIRECTSOUNDDEVICE_TYPE_WDM; + Desc->ModuleA[0] = 0; + Desc->ModuleW[0] = 0; + + *pcbReturned = sizeof(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA); + return S_OK; + } + + + UNIMPLEMENTED + return E_PROP_ID_UNSUPPORTED; +} + +HRESULT +WINAPI +KSPropertySetImpl_Set( + LPKSPROPERTYSET iface, + REFGUID guidPropSet, + ULONG dwPropID, + LPVOID pInstanceData, + ULONG cbInstanceData, + LPVOID pPropData, + ULONG cbPropData ) +{ + UNIMPLEMENTED + return E_PROP_ID_UNSUPPORTED; +} + +HRESULT +WINAPI +KSPropertySetImpl_QuerySupport( + LPKSPROPERTYSET iface, + REFGUID guidPropSet, + ULONG dwPropID, + PULONG pTypeSupport ) +{ + UNIMPLEMENTED + return E_PROP_ID_UNSUPPORTED; +} + +static IKsPropertySetVtbl vt_KsPropertySet = +{ + /* IUnknown methods */ + KSPropertySetImpl_fnQueryInterface, + KSPropertySetImpl_fnAddRef, + KSPropertySetImpl_fnRelease, + /* IKsPropertySet methods */ + KSPropertySetImpl_Get, + KSPropertySetImpl_Set, + KSPropertySetImpl_QuerySupport +}; + +HRESULT +CALLBACK +NewKsPropertySet( + IUnknown* pUnkOuter, + REFIID riid, + LPVOID* ppvObject) +{ + LPOLESTR pStr; + LPCKsPropertySetImpl This; + + /* check requested interface */ + if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IKsPropertySet)) + { + *ppvObject = 0; + StringFromIID(riid, &pStr); + DPRINT("KsPropertySet does not support Interface %ws\n", pStr); + CoTaskMemFree(pStr); + return E_NOINTERFACE; + } + + /* allocate object */ + This = HeapAlloc(GetProcessHeap(), 0, sizeof(CKsPropertySetImpl)); + if (!This) + return E_OUTOFMEMORY; + + /* initialize object */ + This->ref = 1; + This->lpVtbl = &vt_KsPropertySet; + *ppvObject = (LPVOID)&This->lpVtbl; + + return S_OK; +} diff --git a/reactos/dll/directx/dsound_new/regsvr.c b/reactos/dll/directx/dsound_new/regsvr.c new file mode 100644 index 00000000000..3bf9e0791a0 --- /dev/null +++ b/reactos/dll/directx/dsound_new/regsvr.c @@ -0,0 +1,511 @@ +/* + * self-registerable dll functions for dsound.dll + * + * Copyright (C) 2003 John K. Hohm + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "precomp.h" + +static LSTATUS (WINAPI *pRegDeleteTreeW)(HKEY,LPCWSTR); +static LSTATUS (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR); + +/* + * Near the bottom of this file are the exported DllRegisterServer and + * DllUnregisterServer, which make all this worthwhile. + */ + +/*********************************************************************** + * interface for self-registering + */ +struct regsvr_interface +{ + IID const *iid; /* NULL for end of list */ + LPCSTR name; /* can be NULL to omit */ + IID const *base_iid; /* can be NULL to omit */ + int num_methods; /* can be <0 to omit */ + CLSID const *ps_clsid; /* can be NULL to omit */ + CLSID const *ps_clsid32; /* can be NULL to omit */ +}; + +static HRESULT register_interfaces(struct regsvr_interface const *list); +static HRESULT unregister_interfaces(struct regsvr_interface const *list); + +struct regsvr_coclass +{ + CLSID const *clsid; /* NULL for end of list */ + LPCSTR name; /* can be NULL to omit */ + LPCSTR ips; /* can be NULL to omit */ + LPCSTR ips32; /* can be NULL to omit */ + LPCSTR ips32_tmodel; /* can be NULL to omit */ + LPCSTR progid; /* can be NULL to omit */ + LPCSTR viprogid; /* can be NULL to omit */ + LPCSTR progid_extra; /* can be NULL to omit */ +}; + +static HRESULT register_coclasses(struct regsvr_coclass const *list); +static HRESULT unregister_coclasses(struct regsvr_coclass const *list); + +/*********************************************************************** + * static string constants + */ +static WCHAR const interface_keyname[10] = { + 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 }; +static WCHAR const base_ifa_keyname[14] = { + 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', + 'e', 0 }; +static WCHAR const num_methods_keyname[11] = { + 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 }; +static WCHAR const ps_clsid_keyname[15] = { + 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', + 'i', 'd', 0 }; +static WCHAR const ps_clsid32_keyname[17] = { + 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', + 'i', 'd', '3', '2', 0 }; +static WCHAR const clsid_keyname[6] = { + 'C', 'L', 'S', 'I', 'D', 0 }; +static WCHAR const curver_keyname[7] = { + 'C', 'u', 'r', 'V', 'e', 'r', 0 }; +static WCHAR const ips_keyname[13] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', + 0 }; +static WCHAR const ips32_keyname[15] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', + '3', '2', 0 }; +static WCHAR const progid_keyname[7] = { + 'P', 'r', 'o', 'g', 'I', 'D', 0 }; +static WCHAR const viprogid_keyname[25] = { + 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p', + 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D', + 0 }; +static char const tmodel_valuename[] = "ThreadingModel"; + +/*********************************************************************** + * static helper functions + */ +static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid); +static LONG register_key_defvalueW(HKEY base, WCHAR const *name, + WCHAR const *value); +static LONG register_key_defvalueA(HKEY base, WCHAR const *name, + char const *value); +static LONG register_progid(WCHAR const *clsid, + char const *progid, char const *curver_progid, + char const *name, char const *extra); + +/*********************************************************************** + * register_interfaces + */ +static HRESULT register_interfaces(struct regsvr_interface const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY interface_key; + + res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &interface_key, NULL); + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->iid; ++list) { + WCHAR buf[39]; + HKEY iid_key; + + StringFromGUID2(list->iid, buf, 39); + res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &iid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_interface_key; + + if (list->name) { + res = RegSetValueExA(iid_key, NULL, 0, REG_SZ, + (CONST BYTE*)(list->name), + strlen(list->name) + 1); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + if (list->base_iid) { + res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + if (0 <= list->num_methods) { + static WCHAR const fmt[3] = { '%', 'd', 0 }; + HKEY key; + + res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + + swprintf(buf, fmt, list->num_methods); + res = RegSetValueExW(key, NULL, 0, REG_SZ, + (CONST BYTE*)buf, + (lstrlenW(buf) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + if (list->ps_clsid) { + res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + if (list->ps_clsid32) { + res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + error_close_iid_key: + RegCloseKey(iid_key); + } + +error_close_interface_key: + RegCloseKey(interface_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * unregister_interfaces + */ +static HRESULT unregister_interfaces(struct regsvr_interface const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY interface_key; + + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, + KEY_READ | KEY_WRITE, &interface_key); + if (res == ERROR_FILE_NOT_FOUND) return S_OK; + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->iid; ++list) { + WCHAR buf[39]; + + StringFromGUID2(list->iid, buf, 39); + res = pRegDeleteTreeW(interface_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + } + + RegCloseKey(interface_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * register_coclasses + */ +static HRESULT register_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + HKEY clsid_key; + + StringFromGUID2(list->clsid, buf, 39); + res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->name) { + res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, + (CONST BYTE*)(list->name), + strlen(list->name) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips) { + res = register_key_defvalueA(clsid_key, ips_keyname, list->ips); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips32) { + HKEY ips32_key; + + res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, + &ips32_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, + (CONST BYTE*)list->ips32, + lstrlenA(list->ips32) + 1); + if (res == ERROR_SUCCESS && list->ips32_tmodel) + res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, + (CONST BYTE*)list->ips32_tmodel, + strlen(list->ips32_tmodel) + 1); + RegCloseKey(ips32_key); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->progid) { + res = register_key_defvalueA(clsid_key, progid_keyname, + list->progid); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = register_progid(buf, list->progid, NULL, + list->name, list->progid_extra); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->viprogid) { + res = register_key_defvalueA(clsid_key, viprogid_keyname, + list->viprogid); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = register_progid(buf, list->viprogid, list->progid, + list->name, list->progid_extra); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + error_close_clsid_key: + RegCloseKey(clsid_key); + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * unregister_coclasses + */ +static HRESULT unregister_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, + KEY_READ | KEY_WRITE, &coclass_key); + if (res == ERROR_FILE_NOT_FOUND) return S_OK; + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + + StringFromGUID2(list->clsid, buf, 39); + res = pRegDeleteTreeW(coclass_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->progid) { + res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + + if (list->viprogid) { + res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * regsvr_key_guid + */ +static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid) +{ + WCHAR buf[39]; + + StringFromGUID2(guid, buf, 39); + return register_key_defvalueW(base, name, buf); +} + +/*********************************************************************** + * regsvr_key_defvalueW + */ +static LONG register_key_defvalueW( + HKEY base, + WCHAR const *name, + WCHAR const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + (lstrlenW(value) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * regsvr_key_defvalueA + */ +static LONG register_key_defvalueA( + HKEY base, + WCHAR const *name, + char const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + lstrlenA(value) + 1); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * regsvr_progid + */ +static LONG register_progid( + WCHAR const *clsid, + char const *progid, + char const *curver_progid, + char const *name, + char const *extra) +{ + LONG res; + HKEY progid_key; + + res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0, + NULL, 0, KEY_READ | KEY_WRITE, NULL, + &progid_key, NULL); + if (res != ERROR_SUCCESS) return res; + + if (name) { + res = RegSetValueExA(progid_key, NULL, 0, REG_SZ, + (CONST BYTE*)name, strlen(name) + 1); + if (res != ERROR_SUCCESS) goto error_close_progid_key; + } + + if (clsid) { + res = register_key_defvalueW(progid_key, clsid_keyname, clsid); + if (res != ERROR_SUCCESS) goto error_close_progid_key; + } + + if (curver_progid) { + res = register_key_defvalueA(progid_key, curver_keyname, + curver_progid); + if (res != ERROR_SUCCESS) goto error_close_progid_key; + } + + if (extra) { + HKEY extra_key; + + res = RegCreateKeyExA(progid_key, extra, 0, + NULL, 0, KEY_READ | KEY_WRITE, NULL, + &extra_key, NULL); + if (res == ERROR_SUCCESS) + RegCloseKey(extra_key); + } + +error_close_progid_key: + RegCloseKey(progid_key); + return res; +} + +/*********************************************************************** + * coclass list + */ +static GUID const CLSID_DirectSoundBufferConfig = { + 0xB2F586D4, 0x5558, 0x49D1, {0xA0,0x7B,0x32,0x49,0xDB,0xBB,0x33,0xC2} }; + +static struct regsvr_coclass const coclass_list[] = { + { &CLSID_DirectSound, + "DirectSound Object", + NULL, + "dsound.dll", + "Both" + }, + { &CLSID_DirectSound8, + "DirectSound 8.0 Object", + NULL, + "dsound.dll", + "Both" + }, + { &CLSID_DirectSoundBufferConfig, + "DirectSoundBufferConfig Object", + NULL, + "dsound.dll", + "Both" + }, + { &CLSID_DirectSoundCapture, + "DirectSoundCapture Object", + NULL, + "dsound.dll", + "Both" + }, + { &CLSID_DirectSoundCapture8, + "DirectSoundCapture 8.0 Object", + NULL, + "dsound.dll", + "Both" + }, + { &CLSID_DirectSoundFullDuplex, + "DirectSoundFullDuplex Object", + NULL, + "dsound.dll", + "Both" + }, + { NULL } /* list terminator */ +}; + +/*********************************************************************** + * interface list + */ + +static struct regsvr_interface const interface_list[] = { + { NULL } /* list terminator */ +}; + +/*********************************************************************** + * DllRegisterServer (DSOUND.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + HRESULT hr; + + hr = register_coclasses(coclass_list); + if (SUCCEEDED(hr)) + hr = register_interfaces(interface_list); + return hr; +} + +/*********************************************************************** + * DllUnregisterServer (DSOUND.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + HRESULT hr; + + HMODULE advapi32 = GetModuleHandleA("advapi32"); + if (!advapi32) return E_FAIL; + pRegDeleteTreeA = (void *) GetProcAddress(advapi32, "RegDeleteTreeA"); + pRegDeleteTreeW = (void *) GetProcAddress(advapi32, "RegDeleteTreeW"); + if (!pRegDeleteTreeA || !pRegDeleteTreeW) return E_FAIL; + + hr = unregister_coclasses(coclass_list); + if (SUCCEEDED(hr)) + hr = unregister_interfaces(interface_list); + return hr; +} diff --git a/reactos/dll/directx/dsound_new/resource.h b/reactos/dll/directx/dsound_new/resource.h new file mode 100644 index 00000000000..5c963cca5f6 --- /dev/null +++ b/reactos/dll/directx/dsound_new/resource.h @@ -0,0 +1,16 @@ +#ifndef RESOURCE_H__ +#define RESOURCE_H__ + +#define IDS_PRIMARY_PLAYBACK_DEVICE 100 +#define IDS_PRIMARY_RECORD_DEVICE 101 + + + + + + + + + + +#endif diff --git a/reactos/dll/directx/dsound_new/secondary.c b/reactos/dll/directx/dsound_new/secondary.c new file mode 100644 index 00000000000..47a2ad772b1 --- /dev/null +++ b/reactos/dll/directx/dsound_new/secondary.c @@ -0,0 +1,537 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/secondary.c + * PURPOSE: Secondary IDirectSoundBuffer8 implementation + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + + +#include "precomp.h" + +typedef struct +{ + const IDirectSoundBuffer8Vtbl *lpVtbl; + LONG ref; + + LPFILTERINFO Filter; + DWORD dwLevel; + LPWAVEFORMATEX Format; + PUCHAR Buffer; + DWORD BufferSize; + KSSTATE State; + DWORD Flags; + DWORD Position; + DWORD PlayPosition; + + LPDIRECTSOUNDBUFFER8 PrimaryBuffer; + + +}CDirectSoundBuffer, *LPCDirectSoundBuffer; + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnQueryInterface( + LPDIRECTSOUNDBUFFER8 iface, + IN REFIID riid, + LPVOID* ppobj) +{ + LPOLESTR pStr; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDirectSoundBuffer) || + IsEqualIID(riid, &IID_IDirectSoundBuffer8)) + { + *ppobj = (LPVOID)&This->lpVtbl; + InterlockedIncrement(&This->ref); + return S_OK; + } + + if (SUCCEEDED(StringFromIID(riid, &pStr))) + { + DPRINT("No Interface for class %s\n", pStr); + CoTaskMemFree(pStr); + } + return E_NOINTERFACE; +} + +ULONG +WINAPI +SecondaryDirectSoundBuffer8Impl_fnAddRef( + LPDIRECTSOUNDBUFFER8 iface) +{ + ULONG ref; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + ref = InterlockedIncrement(&This->ref); + + return ref; + +} + +ULONG +WINAPI +SecondaryDirectSoundBuffer8Impl_fnRelease( + LPDIRECTSOUNDBUFFER8 iface) +{ + ULONG ref; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + ref = InterlockedDecrement(&(This->ref)); + + if (!ref) + { + HeapFree(GetProcessHeap(), 0, This->Buffer); + HeapFree(GetProcessHeap(), 0, This->Format); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnGetCaps( + LPDIRECTSOUNDBUFFER8 iface, + LPDSBCAPS pDSBufferCaps) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition( + LPDIRECTSOUNDBUFFER8 iface, + LPDWORD pdwCurrentPlayCursor, + LPDWORD pdwCurrentWriteCursor) +{ + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + //DPRINT("SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition This %p Play %p Write %p\n", This, pdwCurrentPlayCursor, pdwCurrentWriteCursor); + + return PrimaryDirectSoundBuffer_GetPosition(This->PrimaryBuffer, pdwCurrentPlayCursor, pdwCurrentWriteCursor); +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnGetFormat( + LPDIRECTSOUNDBUFFER8 iface, + LPWAVEFORMATEX pwfxFormat, + DWORD dwSizeAllocated, + LPDWORD pdwSizeWritten) +{ + DWORD FormatSize; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + FormatSize = sizeof(WAVEFORMATEX) + This->Format->cbSize; + + if (!pwfxFormat && !pdwSizeWritten) + { + /* invalid parameter */ + return DSERR_INVALIDPARAM; + } + + if (!pwfxFormat) + { + /* return required format size */ + *pdwSizeWritten = FormatSize; + return DS_OK; + } + else + { + if (dwSizeAllocated >= FormatSize) + { + /* copy format */ + CopyMemory(pwfxFormat, This->Format, FormatSize); + + if (pdwSizeWritten) + *pdwSizeWritten = FormatSize; + + return DS_OK; + } + /* buffer too small */ + if (pdwSizeWritten) + *pdwSizeWritten = 0; + + return DSERR_INVALIDPARAM; + } +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnGetVolume( + LPDIRECTSOUNDBUFFER8 iface, + LPLONG plVolume) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnGetPan( + LPDIRECTSOUNDBUFFER8 iface, + LPLONG plPan) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnGetFrequency( + LPDIRECTSOUNDBUFFER8 iface, + LPDWORD pdwFrequency) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnGetStatus( + LPDIRECTSOUNDBUFFER8 iface, + LPDWORD pdwStatus) +{ + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + if (!pdwStatus) + { + /* invalid parameter */ + return DSERR_INVALIDPARAM; + } + + *pdwStatus = 0; + if (This->State == KSSTATE_RUN || This->State == KSSTATE_ACQUIRE) + { + /* buffer is playing */ + *pdwStatus |= DSBSTATUS_PLAYING; + if (This->Flags & DSBPLAY_LOOPING) + *pdwStatus |= DSBSTATUS_LOOPING; + } + + return DS_OK; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnInitialize( + LPDIRECTSOUNDBUFFER8 iface, + LPDIRECTSOUND pDirectSound, + LPCDSBUFFERDESC pcDSBufferDesc) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnLock( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwOffset, + DWORD dwBytes, + LPVOID *ppvAudioPtr1, + LPDWORD pdwAudioBytes1, + LPVOID *ppvAudioPtr2, + LPDWORD pdwAudioBytes2, + DWORD dwFlags) +{ + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + DPRINT("This %p dwOffset %u dwBytes %u ppvAudioPtr1 %p pdwAudioBytes1 %p ppvAudioPtr2 %p pdwAudioBytes2 %p dwFlags %x This->BufferSize %u\n", + This, dwOffset, dwBytes, ppvAudioPtr1, pdwAudioBytes1, ppvAudioPtr2, pdwAudioBytes2, dwFlags, This->BufferSize); + + if (dwFlags == DSBLOCK_ENTIREBUFFER) + { + *ppvAudioPtr1 = (LPVOID)This->Buffer; + *pdwAudioBytes1 = This->BufferSize; + if (ppvAudioPtr2) + *ppvAudioPtr2 = NULL; + if (pdwAudioBytes2) + *pdwAudioBytes2 = 0; + + return DS_OK; + } + else if (dwFlags & DSBLOCK_FROMWRITECURSOR) + { + UNIMPLEMENTED + return DSERR_UNSUPPORTED; + } + else + { + ASSERT(dwOffset < This->BufferSize); + ASSERT(dwBytes < This->BufferSize); + ASSERT(dwBytes + dwOffset <= This->BufferSize); + + *ppvAudioPtr1 = This->Buffer + dwOffset; + *pdwAudioBytes1 = dwBytes; + if (ppvAudioPtr2) + *ppvAudioPtr2 = NULL; + if (pdwAudioBytes2) + *pdwAudioBytes2 = 0; + + return DS_OK; + } +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnPlay( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwReserved1, + DWORD dwPriority, + DWORD dwFlags) +{ + HRESULT hResult; + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + if (dwReserved1 != 0) + { + /* must be zero */ + return DSERR_INVALIDPARAM; + } + + DPRINT("SecondaryDirectSoundBuffer8Impl_fnPlay dwPriority %x dwFlags %x\n", dwPriority, dwFlags); + hResult = PrimaryDirectSoundBuffer_SetFormat(This->PrimaryBuffer, This->Format, (dwFlags & DSBPLAY_LOOPING)); + + DPRINT("Result %x\n", hResult); + if (!SUCCEEDED(hResult)) + { + /* failed */ + return hResult; + } + + PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_RUN); + + + PrimaryDirectSoundBuffer_AcquireLock(This->PrimaryBuffer); + + PrimaryDirectSoundBuffer_Write(This->PrimaryBuffer, This->Buffer, This->BufferSize); + + PrimaryDirectSoundBuffer_ReleaseLock(This->PrimaryBuffer); + + return DS_OK; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwNewPosition) +{ + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + DPRINT("Setting position %u\n", dwNewPosition); + This->Position = dwNewPosition; + + return DS_OK; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnSetFormat( + LPDIRECTSOUNDBUFFER8 iface, + LPCWAVEFORMATEX pcfxFormat) +{ + return DSERR_INVALIDCALL; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnSetVolume( + LPDIRECTSOUNDBUFFER8 iface, + LONG lVolume) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnSetPan( + LPDIRECTSOUNDBUFFER8 iface, + LONG lPan) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnSetFrequency( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwFrequency) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnStop( + LPDIRECTSOUNDBUFFER8 iface) +{ + LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); + + PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_PAUSE); + PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_ACQUIRE); + PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_STOP); + + return DS_OK; +} + + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnUnlock( + LPDIRECTSOUNDBUFFER8 iface, + LPVOID pvAudioPtr1, + DWORD dwAudioBytes1, + LPVOID pvAudioPtr2, + DWORD dwAudioBytes2) +{ + //DPRINT("SecondaryDirectSoundBuffer8Impl_fnUnlock pvAudioPtr1 %p dwAudioBytes1 %u pvAudioPtr2 %p dwAudioBytes2 %u Unimplemented\n"); + return DS_OK; +} + + + + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnRestore( + LPDIRECTSOUNDBUFFER8 iface) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnSetFX( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwEffectsCount, + LPDSEFFECTDESC pDSFXDesc, + LPDWORD pdwResultCodes) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnAcquireResources( + LPDIRECTSOUNDBUFFER8 iface, + DWORD dwFlags, + DWORD dwEffectsCount, + LPDWORD pdwResultCodes) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +HRESULT +WINAPI +SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath( + LPDIRECTSOUNDBUFFER8 iface, + REFGUID rguidObject, + DWORD dwIndex, + REFGUID rguidInterface, + LPVOID *ppObject) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + +static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8 = +{ + /* IUnknown methods */ + SecondaryDirectSoundBuffer8Impl_fnQueryInterface, + SecondaryDirectSoundBuffer8Impl_fnAddRef, + SecondaryDirectSoundBuffer8Impl_fnRelease, + /* IDirectSoundBuffer methods */ + SecondaryDirectSoundBuffer8Impl_fnGetCaps, + SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition, + SecondaryDirectSoundBuffer8Impl_fnGetFormat, + SecondaryDirectSoundBuffer8Impl_fnGetVolume, + SecondaryDirectSoundBuffer8Impl_fnGetPan, + SecondaryDirectSoundBuffer8Impl_fnGetFrequency, + SecondaryDirectSoundBuffer8Impl_fnGetStatus, + SecondaryDirectSoundBuffer8Impl_fnInitialize, + SecondaryDirectSoundBuffer8Impl_fnLock, + SecondaryDirectSoundBuffer8Impl_fnPlay, + SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition, + SecondaryDirectSoundBuffer8Impl_fnSetFormat, + SecondaryDirectSoundBuffer8Impl_fnSetVolume, + SecondaryDirectSoundBuffer8Impl_fnSetPan, + SecondaryDirectSoundBuffer8Impl_fnSetFrequency, + SecondaryDirectSoundBuffer8Impl_fnStop, + SecondaryDirectSoundBuffer8Impl_fnUnlock, + SecondaryDirectSoundBuffer8Impl_fnRestore, + /* IDirectSoundBuffer8 methods */ + SecondaryDirectSoundBuffer8Impl_fnSetFX, + SecondaryDirectSoundBuffer8Impl_fnAcquireResources, + SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath +}; + +HRESULT +NewSecondarySoundBuffer( + LPDIRECTSOUNDBUFFER8 *OutBuffer, + LPFILTERINFO Filter, + DWORD dwLevel, + LPCDSBUFFERDESC lpcDSBufferDesc, + LPDIRECTSOUNDBUFFER8 PrimaryBuffer) +{ + ULONG FormatSize; + LPCDirectSoundBuffer This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundBuffer)); + + if (!This) + { + /* not enough memory */ + return DSERR_OUTOFMEMORY; + } + + FormatSize = sizeof(WAVEFORMATEX) + lpcDSBufferDesc->lpwfxFormat->cbSize; + + This->Format = HeapAlloc(GetProcessHeap(), 0, FormatSize); + if (!This->Format) + { + /* not enough memory */ + HeapFree(GetProcessHeap(), 0, This); + return DSERR_OUTOFMEMORY; + } + + /* sanity check */ + ASSERT(lpcDSBufferDesc->dwBufferBytes); + + /* allocate sound buffer */ + This->Buffer = HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc->dwBufferBytes); + if (!This->Buffer) + { + /* not enough memory */ + HeapFree(GetProcessHeap(), 0, This->Format); + HeapFree(GetProcessHeap(), 0, This); + return DSERR_OUTOFMEMORY; + } + + + This->ref = 1; + This->lpVtbl = &vt_DirectSoundBuffer8; + This->Filter = Filter; + This->dwLevel = dwLevel; + This->State = KSSTATE_STOP; + This->Flags = 0; + This->Position = 0; + This->BufferSize = lpcDSBufferDesc->dwBufferBytes; + This->PrimaryBuffer = PrimaryBuffer; + + CopyMemory(This->Format, lpcDSBufferDesc->lpwfxFormat, FormatSize); + + *OutBuffer = (LPDIRECTSOUNDBUFFER8)&This->lpVtbl; + return DS_OK; +} + diff --git a/reactos/dll/directx/dsound_new/stubs.c b/reactos/dll/directx/dsound_new/stubs.c new file mode 100644 index 00000000000..388d1037731 --- /dev/null +++ b/reactos/dll/directx/dsound_new/stubs.c @@ -0,0 +1,29 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Configuration of network devices + * FILE: dll/directx/dsound_new/stubs.c + * PURPOSE: DSound stubs + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + +#include "precomp.h" + +HRESULT +WINAPI +DirectSoundFullDuplexCreate( + LPCGUID pcGuidCaptureDevice, + LPCGUID pcGuidRenderDevice, + LPCDSCBUFFERDESC pcDSCBufferDesc, + LPCDSBUFFERDESC pcDSBufferDesc, + HWND hWnd, + DWORD dwLevel, + LPDIRECTSOUNDFULLDUPLEX *ppDSFD, + LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8, + LPDIRECTSOUNDBUFFER8 *ppDSBuffer8, + LPUNKNOWN pUnkOuter) +{ + UNIMPLEMENTED + return DSERR_INVALIDPARAM; +} + diff --git a/reactos/dll/directx/dsound_new/version.rc b/reactos/dll/directx/dsound_new/version.rc new file mode 100644 index 00000000000..763c823296a --- /dev/null +++ b/reactos/dll/directx/dsound_new/version.rc @@ -0,0 +1,14 @@ +#include +#include "shlobj.h" +#include "resource.h" + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "DirectSound\0" +#define REACTOS_STR_INTERNAL_NAME "dsound.dll\0" +#define REACTOS_STR_ORIGINAL_FILENAME "dsound.dll\0" +#define REACTOS_STR_PRODUCT_VERSION "5.3.1.904\0" +#define REACTOS_STR_FILE_VERSION "5.3.1.904\0" + +#include