- Implemented DirectSoundEnumerateA, DirectSoundEnumerateW, DirectSoundCaptureEnumerateA, DirectSoundCaptureEnumerateW, GetDeviceID
- Partly implemented IDirectSound8 / IDirectSoundCapture8, IDirectSoundCaptureBuffer, primary / secondary IDirectSoundBuffer8 interfaces
- DllRegisterServer / DllUnregisterServer are taken from Wine DSound implementation (John K. Hohm)
- Currently only one primary + secondary buffer are supported for playback
- Mixing of IDirectSoundBuffer is not implemented
- Capture mode isnt yet supported
- Vlc now can use dsound for playback, though stutters in low quality streams are present
- Dsound is not yet added to build untill it has stabilized more
svn path=/trunk/; revision=43874
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+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()
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="dsound" type="win32dll" baseaddress="${BASEADDRESS_DSOUND}" installbase="system32" installname="dsound.dll" crt="msvcrt">
+ <autoregister infsection="OleControlDlls" type="DllRegisterServer" />
+ <importlibrary definition="dsound.spec" />
+ <include base="dsound">.</include>
+ <library>uuid</library>
+ <library>ntdll</library>
+ <library>kernel32</library>
+ <library>user32</library>
+ <library>advapi32</library>
+ <library>ole32</library>
+ <library>winmm</library>
+ <library>dxguid</library>
+ <library>setupapi</library>
+ <library>ksuser</library>
+ <file>capture.c</file>
+ <file>capturebuffer.c</file>
+ <file>classfactory.c</file>
+ <file>devicelist.c</file>
+ <file>directsound.c</file>
+ <file>dsound.c</file>
+ <file>enum.c</file>
+ <file>misc.c</file>
+ <file>primary.c</file>
+ <file>property.c</file>
+ <file>regsvr.c</file>
+ <file>secondary.c</file>
+ <file>stubs.c</file>
+ <file>version.rc</file>
+</module>
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#ifndef PRECOMP_H__
+#define PRECOMP_H__
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include <windows.h>
+#include <setupapi.h>
+#include <mmddk.h>
+#include <objbase.h>
+#include <olectl.h>
+#include <unknwn.h>
+#include <dsound.h>
+#include <dsconf.h>
+#include <vfwmsgs.h>
+#include <setupapi.h>
+#define YDEBUG
+#include <debug.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <limits.h>
+#include <stdio.h>
+
+#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
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#ifndef RESOURCE_H__
+#define RESOURCE_H__
+
+#define IDS_PRIMARY_PLAYBACK_DEVICE 100
+#define IDS_PRIMARY_RECORD_DEVICE 101
+
+
+
+
+
+
+
+
+
+
+#endif
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+#include <windows.h>
+#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 <reactos/version.rc>