- Start rewrite of DirectSound
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 31 Oct 2009 14:53:06 +0000 (14:53 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 31 Oct 2009 14:53:06 +0000 (14:53 +0000)
- 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

18 files changed:
reactos/dll/directx/dsound_new/capture.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/capturebuffer.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/classfactory.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/devicelist.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/directsound.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/dsound.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/dsound.spec [new file with mode: 0644]
reactos/dll/directx/dsound_new/dsound_new.rbuild [new file with mode: 0644]
reactos/dll/directx/dsound_new/enum.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/misc.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/precomp.h [new file with mode: 0644]
reactos/dll/directx/dsound_new/primary.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/property.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/regsvr.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/resource.h [new file with mode: 0644]
reactos/dll/directx/dsound_new/secondary.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/stubs.c [new file with mode: 0644]
reactos/dll/directx/dsound_new/version.rc [new file with mode: 0644]

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