/*
 * Direct Sound Capture driver
 *
 * Copyright 2004 Robert Reif
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
#endif
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#include <sys/soundcard.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "mmddk.h"
#include "mmreg.h"
#include "dsound.h"
#include "dsdriver.h"
#include "wine/debug.h"

#include "audio.h"

WINE_DEFAULT_DEBUG_CHANNEL(dscapture);

/*======================================================================*
 *           Low level DSOUND capture definitions                       *
 *======================================================================*/

typedef struct IDsCaptureDriverPropertySetImpl IDsCaptureDriverPropertySetImpl;
typedef struct IDsCaptureDriverNotifyImpl IDsCaptureDriverNotifyImpl;
typedef struct IDsCaptureDriverImpl IDsCaptureDriverImpl;
typedef struct IDsCaptureDriverBufferImpl IDsCaptureDriverBufferImpl;

struct IDsCaptureDriverPropertySetImpl
{
    /* IUnknown fields */
    IDsDriverPropertySet                IDsDriverPropertySet_iface;
    LONG                                ref;

    IDsCaptureDriverBufferImpl*         capture_buffer;
};

struct IDsCaptureDriverNotifyImpl
{
    /* IUnknown fields */
    IDsDriverNotify                     IDsDriverNotify_iface;
    LONG                                ref;

    IDsCaptureDriverBufferImpl*         capture_buffer;
};

struct IDsCaptureDriverImpl
{
    /* IUnknown fields */
    IDsCaptureDriver                    IDsCaptureDriver_iface;
    LONG                                ref;

    /* IDsCaptureDriverImpl fields */
    UINT                                wDevID;
    IDsCaptureDriverBufferImpl*         capture_buffer;
};

struct IDsCaptureDriverBufferImpl
{
    /* IUnknown fields */
    IDsCaptureDriverBuffer              IDsCaptureDriverBuffer_iface;
    LONG                                ref;

    /* IDsCaptureDriverBufferImpl fields */
    IDsCaptureDriverImpl*               drv;
    LPBYTE                              buffer;         /* user buffer */
    DWORD                               buflen;         /* user buffer length */
    LPBYTE                              mapping;        /* DMA buffer */
    DWORD                               maplen;         /* DMA buffer length */
    BOOL                                is_direct_map;  /* DMA == user ? */
    DWORD                               fragsize;
    DWORD                               map_writepos;   /* DMA write offset */
    DWORD                               map_readpos;    /* DMA read offset */
    DWORD                               writeptr;       /* user write offset */
    DWORD                               readptr;        /* user read offset */

    /* IDsDriverNotifyImpl fields */
    IDsCaptureDriverNotifyImpl*         notify;
    int                                 notify_index;
    LPDSBPOSITIONNOTIFY                 notifies;
    int                                 nrofnotifies;

    /* IDsDriverPropertySetImpl fields */
    IDsCaptureDriverPropertySetImpl*    property_set;

    BOOL                                is_capturing;
    BOOL                                is_looping;
    WAVEFORMATEX                        wfx;
    HANDLE                              hThread;
    DWORD                               dwThreadID;
    HANDLE                              hStartUpEvent;
    HANDLE                              hExitEvent;
    int                                 pipe_fd[2];
    int                                 fd;
};

static inline IDsCaptureDriverPropertySetImpl *impl_from_IDsDriverPropertySet(IDsDriverPropertySet *iface)
{
    return CONTAINING_RECORD(iface, IDsCaptureDriverPropertySetImpl, IDsDriverPropertySet_iface);
}

static inline IDsCaptureDriverNotifyImpl *impl_from_IDsDriverNotify(IDsDriverNotify *iface)
{
    return CONTAINING_RECORD(iface, IDsCaptureDriverNotifyImpl, IDsDriverNotify_iface);
}

static inline IDsCaptureDriverImpl *impl_from_IDsCaptureDriver(IDsCaptureDriver *iface)
{
    return CONTAINING_RECORD(iface, IDsCaptureDriverImpl, IDsCaptureDriver_iface);
}

static inline IDsCaptureDriverBufferImpl *impl_from_IDsCaptureDriverBuffer(IDsCaptureDriverBuffer *iface)
{
    return CONTAINING_RECORD(iface, IDsCaptureDriverBufferImpl, IDsCaptureDriverBuffer_iface);
}

static HRESULT IDsCaptureDriverPropertySetImpl_Create(
    IDsCaptureDriverBufferImpl * dscdb,
    IDsCaptureDriverPropertySetImpl **pdscdps);

static HRESULT IDsCaptureDriverNotifyImpl_Create(
    IDsCaptureDriverBufferImpl * dsdcb,
    IDsCaptureDriverNotifyImpl **pdscdn);

/*======================================================================*
 *           Low level DSOUND capture property set implementation       *
 *======================================================================*/

static HRESULT WINAPI IDsCaptureDriverPropertySetImpl_QueryInterface(
    PIDSDRIVERPROPERTYSET iface,
    REFIID riid,
    LPVOID *ppobj)
{
    IDsCaptureDriverPropertySetImpl *This = impl_from_IDsDriverPropertySet(iface);
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsDriverPropertySet) ) {
        IDsDriverPropertySet_AddRef(iface);
        *ppobj = This;
        return DS_OK;
    }

    FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );

    *ppobj = 0;
    return E_NOINTERFACE;
}

static ULONG WINAPI IDsCaptureDriverPropertySetImpl_AddRef(
    PIDSDRIVERPROPERTYSET iface)
{
    IDsCaptureDriverPropertySetImpl *This = impl_from_IDsDriverPropertySet(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref was %d\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsCaptureDriverPropertySetImpl_Release(
    PIDSDRIVERPROPERTYSET iface)
{
    IDsCaptureDriverPropertySetImpl *This = impl_from_IDsDriverPropertySet(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref was %d\n", This, refCount + 1);

    if (!refCount) {
        IDsCaptureDriverBuffer_Release((PIDSCDRIVERBUFFER)This->capture_buffer);
        This->capture_buffer->property_set = NULL;
        HeapFree(GetProcessHeap(),0,This);
        TRACE("(%p) released\n",This);
    }
    return refCount;
}

static HRESULT WINAPI IDsCaptureDriverPropertySetImpl_Get(
    PIDSDRIVERPROPERTYSET iface,
    PDSPROPERTY pDsProperty,
    LPVOID pPropertyParams,
    ULONG cbPropertyParams,
    LPVOID pPropertyData,
    ULONG cbPropertyData,
    PULONG pcbReturnedData )
{
    IDsCaptureDriverPropertySetImpl *This = impl_from_IDsDriverPropertySet(iface);
    FIXME("(%p,%p,%p,%x,%p,%x,%p)\n",This,pDsProperty,pPropertyParams,
          cbPropertyParams,pPropertyData,cbPropertyData,pcbReturnedData);
    return DSERR_UNSUPPORTED;
}

static HRESULT WINAPI IDsCaptureDriverPropertySetImpl_Set(
    PIDSDRIVERPROPERTYSET iface,
    PDSPROPERTY pDsProperty,
    LPVOID pPropertyParams,
    ULONG cbPropertyParams,
    LPVOID pPropertyData,
    ULONG cbPropertyData )
{
    IDsCaptureDriverPropertySetImpl *This = impl_from_IDsDriverPropertySet(iface);
    FIXME("(%p,%p,%p,%x,%p,%x)\n",This,pDsProperty,pPropertyParams,
          cbPropertyParams,pPropertyData,cbPropertyData);
    return DSERR_UNSUPPORTED;
}

static HRESULT WINAPI IDsCaptureDriverPropertySetImpl_QuerySupport(
    PIDSDRIVERPROPERTYSET iface,
    REFGUID PropertySetId,
    ULONG PropertyId,
    PULONG pSupport )
{
    IDsCaptureDriverPropertySetImpl *This = impl_from_IDsDriverPropertySet(iface);
    FIXME("(%p,%s,%x,%p)\n",This,debugstr_guid(PropertySetId),PropertyId,
          pSupport);
    return DSERR_UNSUPPORTED;
}

static const IDsDriverPropertySetVtbl dscdpsvt =
{
    IDsCaptureDriverPropertySetImpl_QueryInterface,
    IDsCaptureDriverPropertySetImpl_AddRef,
    IDsCaptureDriverPropertySetImpl_Release,
    IDsCaptureDriverPropertySetImpl_Get,
    IDsCaptureDriverPropertySetImpl_Set,
    IDsCaptureDriverPropertySetImpl_QuerySupport,
};

/*======================================================================*
 *                  Low level DSOUND capture notify implementation      *
 *======================================================================*/

static HRESULT WINAPI IDsCaptureDriverNotifyImpl_QueryInterface(
    PIDSDRIVERNOTIFY iface,
    REFIID riid,
    LPVOID *ppobj)
{
    IDsCaptureDriverNotifyImpl *This = impl_from_IDsDriverNotify(iface);
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsDriverNotify) ) {
        IDsDriverNotify_AddRef(iface);
        *ppobj = This;
        return DS_OK;
    }

    FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );

    *ppobj = 0;
    return E_NOINTERFACE;
}

static ULONG WINAPI IDsCaptureDriverNotifyImpl_AddRef(
    PIDSDRIVERNOTIFY iface)
{
    IDsCaptureDriverNotifyImpl *This = impl_from_IDsDriverNotify(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref was %d\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsCaptureDriverNotifyImpl_Release(
    PIDSDRIVERNOTIFY iface)
{
    IDsCaptureDriverNotifyImpl *This = impl_from_IDsDriverNotify(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref was %d\n", This, refCount + 1);

    if (!refCount) {
        IDsCaptureDriverBuffer_Release((PIDSCDRIVERBUFFER)This->capture_buffer);
        This->capture_buffer->notify = NULL;
        HeapFree(GetProcessHeap(),0,This);
        TRACE("(%p) released\n",This);
    }
    return refCount;
}

static HRESULT WINAPI IDsCaptureDriverNotifyImpl_SetNotificationPositions(
    PIDSDRIVERNOTIFY iface,
    DWORD howmuch,
    LPCDSBPOSITIONNOTIFY notify)
{
    IDsCaptureDriverNotifyImpl *This = impl_from_IDsDriverNotify(iface);
    TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);

    if (!notify) {
        WARN("invalid parameter\n");
        return DSERR_INVALIDPARAM;
    }

    if (TRACE_ON(dscapture)) {
        DWORD i;
        for (i=0;i<howmuch;i++)
            TRACE("notify at %d to 0x%08lx\n",
                notify[i].dwOffset,(DWORD_PTR)notify[i].hEventNotify);
    }

    /* Make an internal copy of the caller-supplied array.
     * Replace the existing copy if one is already present. */
    if (This->capture_buffer->notifies)
        This->capture_buffer->notifies = HeapReAlloc(GetProcessHeap(),
            HEAP_ZERO_MEMORY, This->capture_buffer->notifies,
            howmuch * sizeof(DSBPOSITIONNOTIFY));
    else
        This->capture_buffer->notifies = HeapAlloc(GetProcessHeap(),
            HEAP_ZERO_MEMORY, howmuch * sizeof(DSBPOSITIONNOTIFY));

    memcpy(This->capture_buffer->notifies, notify,
           howmuch * sizeof(DSBPOSITIONNOTIFY));
    This->capture_buffer->nrofnotifies = howmuch;

    return S_OK;
}

static const IDsDriverNotifyVtbl dscdnvt =
{
    IDsCaptureDriverNotifyImpl_QueryInterface,
    IDsCaptureDriverNotifyImpl_AddRef,
    IDsCaptureDriverNotifyImpl_Release,
    IDsCaptureDriverNotifyImpl_SetNotificationPositions,
};

/*======================================================================*
 *                  Low level DSOUND capture implementation             *
 *======================================================================*/

static HRESULT DSCDB_MapBuffer(IDsCaptureDriverBufferImpl *dscdb)
{
    if (!dscdb->mapping) {
        dscdb->mapping = mmap(NULL, dscdb->maplen, PROT_READ, MAP_SHARED,
                              WInDev[dscdb->drv->wDevID].ossdev.fd, 0);
        if (dscdb->mapping == (LPBYTE)-1) {
            TRACE("(%p): Could not map sound device for direct access (%s)\n",
                  dscdb, strerror(errno));
            return DSERR_GENERIC;
        }
        TRACE("(%p): sound device has been mapped for direct access at %p, "
              "size=%d\n", dscdb, dscdb->mapping, dscdb->maplen);
    }
    return DS_OK;
}

static HRESULT DSCDB_UnmapBuffer(IDsCaptureDriverBufferImpl *dscdb)
{
    if (dscdb->mapping) {
        if (munmap(dscdb->mapping, dscdb->maplen) < 0) {
            ERR("(%p): Could not unmap sound device (%s)\n",
                dscdb, strerror(errno));
            return DSERR_GENERIC;
        }
        dscdb->mapping = NULL;
        TRACE("(%p): sound device unmapped\n", dscdb);
    }
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_QueryInterface(
    PIDSCDRIVERBUFFER iface,
    REFIID riid,
    LPVOID *ppobj)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    *ppobj = 0;

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsCaptureDriverBuffer) ) {
        IDsCaptureDriverBuffer_AddRef(iface);
        *ppobj = This;
        return DS_OK;
    }

    if ( IsEqualGUID( &IID_IDsDriverNotify, riid ) ) {
        if (!This->notify)
            IDsCaptureDriverNotifyImpl_Create(This, &(This->notify));
        if (This->notify) {
            IDsDriverNotify_AddRef((PIDSDRIVERNOTIFY)This->notify);
            *ppobj = This->notify;
            return DS_OK;
        }
        return E_FAIL;
    }

    if ( IsEqualGUID( &IID_IDsDriverPropertySet, riid ) ) {
        if (!This->property_set)
            IDsCaptureDriverPropertySetImpl_Create(This, &(This->property_set));
        if (This->property_set) {
            IDsDriverPropertySet_AddRef((PIDSDRIVERPROPERTYSET)This->property_set);
            *ppobj = This->property_set;
            return DS_OK;
        }
        return E_FAIL;
    }

    FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj);
    return DSERR_UNSUPPORTED;
}

static ULONG WINAPI IDsCaptureDriverBufferImpl_AddRef(PIDSCDRIVERBUFFER iface)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref was %d\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsCaptureDriverBufferImpl_Release(PIDSCDRIVERBUFFER iface)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);
    TRACE("(%p) ref was %d\n", This, refCount + 1);

    if (!refCount) {
        WINE_WAVEIN*        wwi;

        wwi = &WInDev[This->drv->wDevID];

        if (This->hThread) {
            int x = 0;

            /* request thread termination */
            write(This->pipe_fd[1], &x, sizeof(x));

            /* wait for reply */
            WaitForSingleObject(This->hExitEvent, INFINITE);
            CloseHandle(This->hExitEvent);
        }

        close(This->pipe_fd[0]);
        close(This->pipe_fd[1]);

        DSCDB_UnmapBuffer(This);

        OSS_CloseDevice(&wwi->ossdev);
        wwi->state = WINE_WS_CLOSED;
        wwi->dwFragmentSize = 0;
        This->drv->capture_buffer = NULL;

        HeapFree(GetProcessHeap(), 0, This->notifies);
        HeapFree(GetProcessHeap(),0,This);
        TRACE("(%p) released\n",This);
    }
    return refCount;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_Lock(
    PIDSCDRIVERBUFFER iface,
    LPVOID* ppvAudio1,
    LPDWORD pdwLen1,
    LPVOID* ppvAudio2,
    LPDWORD pdwLen2,
    DWORD dwWritePosition,
    DWORD dwWriteLen,
    DWORD dwFlags)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    TRACE("(%p,%p,%p,%p,%p,%d,%d,0x%08x)\n",This,ppvAudio1,pdwLen1,
          ppvAudio2,pdwLen2,dwWritePosition,dwWriteLen,dwFlags);

    if (This->is_direct_map) {
        if (ppvAudio1)
            *ppvAudio1 = This->mapping + dwWritePosition;

        if (dwWritePosition + dwWriteLen < This->maplen) {
            if (pdwLen1)
                *pdwLen1 = dwWriteLen;
            if (ppvAudio2)
                *ppvAudio2 = 0;
            if (pdwLen2)
                *pdwLen2 = 0;
        } else {
            if (pdwLen1)
                *pdwLen1 = This->maplen - dwWritePosition;
            if (ppvAudio2)
                *ppvAudio2 = 0;
            if (pdwLen2)
                *pdwLen2 = dwWriteLen - (This->maplen - dwWritePosition);
        }
    } else {
        if (ppvAudio1)
            *ppvAudio1 = This->buffer + dwWritePosition;

        if (dwWritePosition + dwWriteLen < This->buflen) {
            if (pdwLen1)
                *pdwLen1 = dwWriteLen;
            if (ppvAudio2)
                *ppvAudio2 = 0;
            if (pdwLen2)
                *pdwLen2 = 0;
        } else {
            if (pdwLen1)
                *pdwLen1 = This->buflen - dwWritePosition;
            if (ppvAudio2)
                *ppvAudio2 = 0;
            if (pdwLen2)
                *pdwLen2 = dwWriteLen - (This->buflen - dwWritePosition);
        }
    }

    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_Unlock(
    PIDSCDRIVERBUFFER iface,
    LPVOID pvAudio1,
    DWORD dwLen1,
    LPVOID pvAudio2,
    DWORD dwLen2)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    TRACE("(%p,%p,%d,%p,%d)\n",This,pvAudio1,dwLen1,pvAudio2,dwLen2);

    if (This->is_direct_map)
        This->map_readpos = (This->map_readpos + dwLen1 + dwLen2) % This->maplen;
    else
        This->readptr = (This->readptr + dwLen1 + dwLen2) % This->buflen;

    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_GetPosition(
    PIDSCDRIVERBUFFER iface,
    LPDWORD lpdwCapture,
    LPDWORD lpdwRead)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    TRACE("(%p,%p,%p)\n",This,lpdwCapture,lpdwRead);

    if (WInDev[This->drv->wDevID].state == WINE_WS_CLOSED) {
        ERR("device not open, but accessing?\n");
        return DSERR_UNINITIALIZED;
    }

    if (!This->is_capturing) {
        if (lpdwCapture)
            *lpdwCapture = 0;
        if (lpdwRead)
            *lpdwRead = 0;
    }

    if (This->is_direct_map) {
        if (lpdwCapture)
            *lpdwCapture = This->map_writepos;
        if (lpdwRead) {
            *lpdwRead = This->map_readpos;
        }
    } else {
        if (lpdwCapture)
            *lpdwCapture = This->writeptr;
        if (lpdwRead)
            *lpdwRead = This->readptr;
    }

    TRACE("capturepos=%d, readpos=%d\n", lpdwCapture?*lpdwCapture:0,
          lpdwRead?*lpdwRead:0);
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_GetStatus(
    PIDSCDRIVERBUFFER iface,
    LPDWORD lpdwStatus)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    TRACE("(%p,%p)\n",This,lpdwStatus);

    if (This->is_capturing) {
        if (This->is_looping)
            *lpdwStatus = DSCBSTATUS_CAPTURING | DSCBSTATUS_LOOPING;
        else
            *lpdwStatus = DSCBSTATUS_CAPTURING;
    } else
        *lpdwStatus = 0;

    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_Start(
    PIDSCDRIVERBUFFER iface,
    DWORD dwFlags)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    int enable;
    TRACE("(%p,%x)\n",This,dwFlags);

    if (This->is_capturing)
        return DS_OK;

    if (dwFlags & DSCBSTART_LOOPING)
        This->is_looping = TRUE;

    WInDev[This->drv->wDevID].ossdev.bInputEnabled = TRUE;
    enable = getEnables(&WInDev[This->drv->wDevID].ossdev);
    if (ioctl(WInDev[This->drv->wDevID].ossdev.fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
        if (errno == EINVAL) {
            /* Don't give up yet. OSS trigger support is inconsistent. */
            if (WInDev[This->drv->wDevID].ossdev.open_count == 1) {
                /* try the opposite output enable */
                if (WInDev[This->drv->wDevID].ossdev.bOutputEnabled == FALSE)
                    WInDev[This->drv->wDevID].ossdev.bOutputEnabled = TRUE;
                else
                    WInDev[This->drv->wDevID].ossdev.bOutputEnabled = FALSE;
                /* try it again */
                enable = getEnables(&WInDev[This->drv->wDevID].ossdev);
                if (ioctl(WInDev[This->drv->wDevID].ossdev.fd, SNDCTL_DSP_SETTRIGGER, &enable) >= 0) {
                    This->is_capturing = TRUE;
                    return DS_OK;
                }
            }
        }
        ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n",
            WInDev[This->drv->wDevID].ossdev.dev_name, strerror(errno));
        WInDev[This->drv->wDevID].ossdev.bInputEnabled = FALSE;
        return DSERR_GENERIC;
    }

    This->is_capturing = TRUE;
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_Stop(PIDSCDRIVERBUFFER iface)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    int enable;
    TRACE("(%p)\n",This);

    if (!This->is_capturing)
        return DS_OK;

    /* no more capturing */
    WInDev[This->drv->wDevID].ossdev.bInputEnabled = FALSE;
    enable = getEnables(&WInDev[This->drv->wDevID].ossdev);
    if (ioctl(WInDev[This->drv->wDevID].ossdev.fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
        ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n",
            WInDev[This->drv->wDevID].ossdev.dev_name,  strerror(errno));
        return DSERR_GENERIC;
    }

    /* send a final event if necessary */
    if (This->nrofnotifies > 0) {
        if (This->notifies[This->nrofnotifies - 1].dwOffset == DSBPN_OFFSETSTOP)
            SetEvent(This->notifies[This->nrofnotifies - 1].hEventNotify);
    }

    This->is_capturing = FALSE;
    This->is_looping = FALSE;

    if (This->hThread) {
        int x = 0;
        write(This->pipe_fd[1], &x, sizeof(x));
        WaitForSingleObject(This->hExitEvent, INFINITE);
        CloseHandle(This->hExitEvent);
        This->hExitEvent = INVALID_HANDLE_VALUE;
        This->hThread = 0;
    }

    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_SetFormat(
    PIDSCDRIVERBUFFER iface,
    LPWAVEFORMATEX pwfx)
{
    IDsCaptureDriverBufferImpl *This = impl_from_IDsCaptureDriverBuffer(iface);
    FIXME("(%p): stub!\n",This);
    return DSERR_UNSUPPORTED;
}

static const IDsCaptureDriverBufferVtbl dscdbvt =
{
    IDsCaptureDriverBufferImpl_QueryInterface,
    IDsCaptureDriverBufferImpl_AddRef,
    IDsCaptureDriverBufferImpl_Release,
    IDsCaptureDriverBufferImpl_Lock,
    IDsCaptureDriverBufferImpl_Unlock,
    IDsCaptureDriverBufferImpl_SetFormat,
    IDsCaptureDriverBufferImpl_GetPosition,
    IDsCaptureDriverBufferImpl_GetStatus,
    IDsCaptureDriverBufferImpl_Start,
    IDsCaptureDriverBufferImpl_Stop
};

static HRESULT WINAPI IDsCaptureDriverImpl_QueryInterface(
    PIDSCDRIVER iface,
    REFIID riid,
    LPVOID *ppobj)
{
    IDsCaptureDriverImpl *This = impl_from_IDsCaptureDriver(iface);
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsCaptureDriver) ) {
        IDsCaptureDriver_AddRef(iface);
        *ppobj = This;
        return DS_OK;
    }

    FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );

    *ppobj = 0;

    return E_NOINTERFACE;
}

static ULONG WINAPI IDsCaptureDriverImpl_AddRef(PIDSCDRIVER iface)
{
    IDsCaptureDriverImpl *This = impl_from_IDsCaptureDriver(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref was %d\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsCaptureDriverImpl_Release(PIDSCDRIVER iface)
{
    IDsCaptureDriverImpl *This = impl_from_IDsCaptureDriver(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref was %d\n", This, refCount + 1);

    if (!refCount) {
        HeapFree(GetProcessHeap(),0,This);
        TRACE("(%p) released\n",This);
    }
    return refCount;
}

static HRESULT WINAPI IDsCaptureDriverImpl_GetDriverDesc(
    PIDSCDRIVER iface,
    PDSDRIVERDESC pDesc)
{
    IDsCaptureDriverImpl *This = impl_from_IDsCaptureDriver(iface);
    TRACE("(%p,%p)\n",This,pDesc);

    if (!pDesc) {
        TRACE("invalid parameter\n");
        return DSERR_INVALIDPARAM;
    }

    /* copy version from driver */
    *pDesc = WInDev[This->wDevID].ossdev.ds_desc;

    pDesc->dnDevNode            = WInDev[This->wDevID].waveDesc.dnDevNode;
    pDesc->wVxdId               = 0;
    pDesc->wReserved            = 0;
    pDesc->ulDeviceNum          = This->wDevID;
    pDesc->dwHeapType           = DSDHEAP_NOHEAP;
    pDesc->pvDirectDrawHeap     = NULL;
    pDesc->dwMemStartAddress    = 0;
    pDesc->dwMemEndAddress      = 0;
    pDesc->dwMemAllocExtra      = 0;
    pDesc->pvReserved1          = NULL;
    pDesc->pvReserved2          = NULL;
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverImpl_Open(PIDSCDRIVER iface)
{
    IDsCaptureDriverImpl *This = impl_from_IDsCaptureDriver(iface);
    TRACE("(%p)\n",This);
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverImpl_Close(PIDSCDRIVER iface)
{
    IDsCaptureDriverImpl *This = impl_from_IDsCaptureDriver(iface);
    TRACE("(%p)\n",This);
    if (This->capture_buffer) {
        ERR("problem with DirectSound: capture buffer not released\n");
        return DSERR_GENERIC;
    }
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverImpl_GetCaps(
    PIDSCDRIVER iface,
    PDSCDRIVERCAPS pCaps)
{
    IDsCaptureDriverImpl *This = impl_from_IDsCaptureDriver(iface);
    TRACE("(%p,%p)\n",This,pCaps);
    *pCaps = WInDev[This->wDevID].ossdev.dsc_caps;
    return DS_OK;
}

static void DSCDB_CheckEvent(
    IDsCaptureDriverBufferImpl *dscb,
    DWORD writepos,
    DWORD len,
    DWORD buflen)
{
    LPDSBPOSITIONNOTIFY event = dscb->notifies + dscb->notify_index;
    DWORD offset = event->dwOffset;
    TRACE("(%p,%d,%d,%d)\n", dscb, writepos, len, buflen);

    TRACE("(%p) buflen = %d, writeptr = %d\n",
        dscb, dscb->buflen, dscb->writeptr);
    TRACE("checking %d, position %d, event = %p\n",
        dscb->notify_index, offset, event->hEventNotify);

    if ((writepos + len) > offset) {
         TRACE("signalled event %p (%d) %d\n",
               event->hEventNotify, dscb->notify_index, offset);
         SetEvent(event->hEventNotify);
         dscb->notify_index = (dscb->notify_index + 1) % dscb->nrofnotifies;
         return;
    } else if ((writepos + len) > buflen) {
        writepos = writepos + len - buflen;
        if ((writepos + len) > offset) {
             TRACE("signalled event %p (%d) %d\n",
                   event->hEventNotify, dscb->notify_index, offset);
             SetEvent(event->hEventNotify);
             dscb->notify_index = (dscb->notify_index + 1) % dscb->nrofnotifies;
             return;
        }
    }

    return;
}

/* FIXME: using memcpy can cause strange crashes so use this fake one */
static void * my_memcpy(void * dst, const void * src, int length)
{
    int i;
    for (i = 0; i < length; i++)
        ((char *)dst)[i] = ((const char *)src)[i];
    return dst;
}

static DWORD CALLBACK DSCDB_Thread(LPVOID lpParameter)
{
    IDsCaptureDriverBufferImpl *This = lpParameter;
    struct pollfd poll_list[2];
    int retval;
    DWORD offset = 0;
    DWORD map_offset = 0;
    TRACE("(%p)\n", lpParameter);

    poll_list[0].fd = This->fd;                /* data available */
    poll_list[1].fd = This->pipe_fd[0];        /* message from parent process */
    poll_list[0].events = POLLIN;
    poll_list[1].events = POLLIN;

    /* let other process know we are running */
    SetEvent(This->hStartUpEvent);

    while (1) {
        /* wait for something to happen */
        retval = poll(poll_list,(unsigned long)2,-1);
        /* Retval will always be greater than 0 or -1 in this case.
         * Since we're doing it while blocking
         */
        if (retval < 0) {
            ERR("Error while polling: %s\n",strerror(errno));
            continue;
        }

        /* check for exit command */
        if ((poll_list[1].revents & POLLIN) == POLLIN) {
            TRACE("(%p) done\n", lpParameter);
            /* acknowledge command and exit */
            SetEvent(This->hExitEvent);
            ExitThread(0);
            return 0;
        }

        /* check for data */
        if ((poll_list[0].revents & POLLIN) == POLLIN) {
            count_info info;
            int fragsize, first, second;

            /* get the current DMA position */
            if (ioctl(This->fd, SNDCTL_DSP_GETIPTR, &info) < 0) {
                ERR("ioctl(%s, SNDCTL_DSP_GETIPTR) failed (%s)\n",
                    WInDev[This->drv->wDevID].ossdev.dev_name, strerror(errno));
                return DSERR_GENERIC;
            }

            if (This->is_direct_map) {
                offset = This->map_writepos;
                This->map_writepos = info.ptr;

                if (info.ptr < offset)
                    fragsize = info.ptr + This->maplen - offset;
                else
                    fragsize = info.ptr - offset;

                DSCDB_CheckEvent(This, offset, fragsize, This->maplen);
            } else {
                map_offset = This->map_writepos;
                offset = This->writeptr;

                /* test for mmap buffer wrap */
                if (info.ptr < map_offset) {
                    /* mmap buffer wrapped */
                    fragsize = info.ptr + This->maplen - map_offset;

                    /* check for user buffer wrap */
                    if ((offset + fragsize) > This->buflen) {
                        /* both buffers wrapped
                         * figure out which wrapped first
                         */
                        if ((This->maplen - map_offset) > (This->buflen - offset)) {
                            /* user buffer wrapped first */
                            first = This->buflen - offset;
                            second = (This->maplen - map_offset) - first;
                            my_memcpy(This->buffer + offset, This->mapping + map_offset, first);
                            my_memcpy(This->buffer, This->mapping + map_offset + first, second);
                            my_memcpy(This->buffer + second, This->mapping, fragsize - (first + second));
                        } else {
                            /* mmap buffer wrapped first */
                            first = This->maplen - map_offset;
                            second = (This->buflen - offset) - first;
                            my_memcpy(This->buffer + offset, This->mapping + map_offset, first);
                            my_memcpy(This->buffer + offset + first, This->mapping, second);
                            my_memcpy(This->buffer, This->mapping + second, fragsize - (first + second));
                        }
                    } else {
                        /* only mmap buffer wrapped */
                        first = This->maplen - map_offset;
                        my_memcpy(This->buffer + offset, This->mapping + map_offset, first);
                        my_memcpy(This->buffer + offset + first, This->mapping, fragsize - first);
                    }
                } else {
                    /* mmap buffer didn't wrap */
                    fragsize = info.ptr - map_offset;

                    /* check for user buffer wrap */
                    if ((offset + fragsize) > This->buflen) {
                        first = This->buflen - offset;
                        my_memcpy(This->buffer + offset, This->mapping + map_offset, first);
                        my_memcpy(This->buffer, This->mapping + map_offset + first, fragsize - first);
                    } else
                        my_memcpy(This->buffer + offset, This->mapping + map_offset, fragsize);
                }

                This->map_writepos = info.ptr;
                This->writeptr = (This->writeptr + fragsize) % This->buflen;
                DSCDB_CheckEvent(This, offset, fragsize, This->buflen);
            }
        }
    }
}

static HRESULT WINAPI IDsCaptureDriverImpl_CreateCaptureBuffer(
    PIDSCDRIVER iface,
    LPWAVEFORMATEX pwfx,
    DWORD dwFlags,
    DWORD dwCardAddress,
    LPDWORD pdwcbBufferSize,
    LPBYTE *ppbBuffer,
    LPVOID *ppvObj)
{
    IDsCaptureDriverImpl *This = impl_from_IDsCaptureDriver(iface);
    IDsCaptureDriverBufferImpl** ippdscdb = (IDsCaptureDriverBufferImpl**)ppvObj;
    HRESULT err;
    audio_buf_info info;
    int audio_fragment, fsize, shift, ret;
    BOOL bNewBuffer = FALSE;
    WINE_WAVEIN* wwi;
    TRACE("(%p,%p,%x,%x,%p,%p,%p)\n",This,pwfx,dwFlags,dwCardAddress,
          pdwcbBufferSize,ppbBuffer,ppvObj);

    if (This->capture_buffer) {
        TRACE("already allocated\n");
        return DSERR_ALLOCATED;
    }

    /* must be given a buffer size */
    if (pdwcbBufferSize == NULL || *pdwcbBufferSize == 0) {
       TRACE("invalid parameter: pdwcbBufferSize\n");
       return DSERR_INVALIDPARAM;
    }

    /* must be given a buffer pointer */
    if (ppbBuffer == NULL) {
       TRACE("invalid parameter: ppbBuffer\n");
       return DSERR_INVALIDPARAM;
    }

    /* may or may not be given a buffer */
    if (*ppbBuffer == NULL) {
        TRACE("creating buffer\n");
        bNewBuffer = TRUE;     /* not given a buffer so create one */
    } else
        TRACE("using supplied buffer\n");

    *ippdscdb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDsCaptureDriverBufferImpl));
    if (*ippdscdb == NULL) {
        TRACE("out of memory\n");
        return DSERR_OUTOFMEMORY;
    }

    (*ippdscdb)->IDsCaptureDriverBuffer_iface.lpVtbl = &dscdbvt;
    (*ippdscdb)->ref          = 1;
    (*ippdscdb)->drv          = This;
    (*ippdscdb)->notify       = NULL;
    (*ippdscdb)->notify_index = 0;
    (*ippdscdb)->notifies     = NULL;
    (*ippdscdb)->nrofnotifies = 0;
    (*ippdscdb)->property_set = NULL;
    (*ippdscdb)->is_capturing = FALSE;
    (*ippdscdb)->is_looping   = FALSE;
    (*ippdscdb)->wfx          = *pwfx;
    (*ippdscdb)->buflen       = *pdwcbBufferSize;

    if (bNewBuffer)
        (*ippdscdb)->buffer = NULL;
    else
        (*ippdscdb)->buffer = *ppbBuffer;

    wwi = &WInDev[This->wDevID];

    if (wwi->state == WINE_WS_CLOSED) {
        unsigned int frag_size;

        if (wwi->ossdev.open_count > 0) {
            /* opened already so use existing fragment size */
            audio_fragment = wwi->ossdev.audio_fragment;
        } else {
            /* calculate a fragment size */
            unsigned int mask = 0xffffffff;

            /* calculate largest fragment size less than 10 ms. */
            fsize = pwfx->nAvgBytesPerSec / 100;        /* 10 ms chunk */
            shift = 0;
            while ((1 << shift) <= fsize)
                shift++;
            shift--;
            fsize = 1 << shift;
            TRACE("shift = %d, fragment size = %d\n", shift, fsize);
            TRACE("BufferSize=%d(%08x)\n", *pdwcbBufferSize, *pdwcbBufferSize);

            /* See if we can directly map the buffer first.
             * (buffer length is multiple of a power of 2)
             */
            mask = (mask >> (32 - shift));
            TRACE("mask=%08x\n", mask);
            if (*pdwcbBufferSize & mask) {
                /* no so try a smaller fragment size greater than 1 ms */
                int new_shift = shift - 1;
                int min_shift = 0;
                int min_fsize = pwfx->nAvgBytesPerSec / 1000;
                BOOL found_one = FALSE;
                while ((1 << min_shift) <= min_fsize)
                    min_shift++;
                min_shift--;
                while (new_shift > min_shift) {
                    if (*pdwcbBufferSize & (-1 >> (32 - new_shift))) {
                        new_shift--;
                        continue;
                    } else {
                        found_one = TRUE;
                        break;
                    }
                }
                if (found_one) {
                    /* found a smaller one that will work */
                    audio_fragment = ((*pdwcbBufferSize >> new_shift) << 16) | new_shift;
                    (*ippdscdb)->is_direct_map = TRUE;
                    TRACE("new shift = %d, fragment size = %d\n",
                          new_shift, 1 << (audio_fragment & 0xffff));
                } else {
                    /* buffer can't be direct mapped */
                    audio_fragment = 0x00100000 + shift;        /* 16 fragments of 2^shift */
                    (*ippdscdb)->is_direct_map = FALSE;
                }
            } else {
                /* good fragment size */
                audio_fragment = ((*pdwcbBufferSize >> shift) << 16) | shift;
                (*ippdscdb)->is_direct_map = TRUE;
            }
        }
        frag_size = 1 << (audio_fragment & 0xffff);
        TRACE("is_direct_map = %s\n", (*ippdscdb)->is_direct_map ? "TRUE" : "FALSE");
        TRACE("requesting %d %d byte fragments (%d bytes) (%d ms/fragment)\n",
              audio_fragment >> 16, frag_size, frag_size * (audio_fragment >> 16),
              (frag_size * 1000) / pwfx->nAvgBytesPerSec);

        ret = OSS_OpenDevice(&wwi->ossdev, O_RDWR, &audio_fragment, 1,
                             pwfx->nSamplesPerSec,
                             (pwfx->nChannels > 1) ? 1 : 0,
                             (pwfx->wBitsPerSample == 16)
                             ? AFMT_S16_LE : AFMT_U8);

        if (ret != 0) {
            WARN("OSS_OpenDevice failed\n");
            HeapFree(GetProcessHeap(),0,*ippdscdb);
            *ippdscdb = NULL;
            return DSERR_GENERIC;
        }

        wwi->state = WINE_WS_STOPPED;

        /* find out what fragment and buffer sizes OSS gave us */
        if (ioctl(wwi->ossdev.fd, SNDCTL_DSP_GETISPACE, &info) < 0) {
             ERR("ioctl(%s, SNDCTL_DSP_GETISPACE) failed (%s)\n",
                 wwi->ossdev.dev_name, strerror(errno));
             OSS_CloseDevice(&wwi->ossdev);
             wwi->state = WINE_WS_CLOSED;
             HeapFree(GetProcessHeap(),0,*ippdscdb);
             *ippdscdb = NULL;
             return DSERR_GENERIC;
        }

        TRACE("got %d %d byte fragments (%d bytes) (%d ms/fragment)\n",
              info.fragstotal, info.fragsize, info.fragstotal * info.fragsize,
              info.fragsize * 1000 / pwfx->nAvgBytesPerSec);

        wwi->dwTotalRecorded = 0;
        memcpy(&wwi->waveFormat, pwfx, sizeof(PCMWAVEFORMAT));
        wwi->dwFragmentSize = info.fragsize;

        /* make sure we got what we asked for */
        if ((*ippdscdb)->buflen != info.fragstotal * info.fragsize) {
            TRACE("Couldn't create requested buffer\n");
            if ((*ippdscdb)->is_direct_map) {
                (*ippdscdb)->is_direct_map = FALSE;
                TRACE("is_direct_map = FALSE\n");
            }
        } else if (info.fragsize != frag_size) {
            TRACE("same buffer length but different fragment size\n");
        }
    }
    (*ippdscdb)->fd = WInDev[This->wDevID].ossdev.fd;

    if (pipe((*ippdscdb)->pipe_fd) < 0) {
        TRACE("pipe() failed (%s)\n", strerror(errno));
        OSS_CloseDevice(&wwi->ossdev);
        wwi->state = WINE_WS_CLOSED;
        HeapFree(GetProcessHeap(),0,*ippdscdb);
        *ippdscdb = NULL;
        return DSERR_GENERIC;
    }

    /* check how big the DMA buffer is now */
    if (ioctl(wwi->ossdev.fd, SNDCTL_DSP_GETISPACE, &info) < 0) {
        ERR("ioctl(%s, SNDCTL_DSP_GETISPACE) failed (%s)\n",
            wwi->ossdev.dev_name, strerror(errno));
        OSS_CloseDevice(&wwi->ossdev);
        wwi->state = WINE_WS_CLOSED;
        close((*ippdscdb)->pipe_fd[0]);
        close((*ippdscdb)->pipe_fd[1]);
        HeapFree(GetProcessHeap(),0,*ippdscdb);
        *ippdscdb = NULL;
        return DSERR_GENERIC;
    }

    (*ippdscdb)->maplen = info.fragstotal * info.fragsize;
    (*ippdscdb)->fragsize = info.fragsize;
    (*ippdscdb)->map_writepos = 0;
    (*ippdscdb)->map_readpos = 0;

    /* map the DMA buffer */
    err = DSCDB_MapBuffer(*ippdscdb);
    if (err != DS_OK) {
        OSS_CloseDevice(&wwi->ossdev);
        wwi->state = WINE_WS_CLOSED;
        close((*ippdscdb)->pipe_fd[0]);
        close((*ippdscdb)->pipe_fd[1]);
        HeapFree(GetProcessHeap(),0,*ippdscdb);
        *ippdscdb = NULL;
        return err;
    }

    /* create the buffer if necessary */
    if (!(*ippdscdb)->buffer)
        (*ippdscdb)->buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,(*ippdscdb)->buflen);

    if ((*ippdscdb)->buffer == NULL) {
        OSS_CloseDevice(&wwi->ossdev);
        wwi->state = WINE_WS_CLOSED;
        close((*ippdscdb)->pipe_fd[0]);
        close((*ippdscdb)->pipe_fd[1]);
        HeapFree(GetProcessHeap(),0,*ippdscdb);
        *ippdscdb = NULL;
        return DSERR_OUTOFMEMORY;
    }

    This->capture_buffer = *ippdscdb;

    (*ippdscdb)->hStartUpEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
    (*ippdscdb)->hExitEvent = CreateEventW(NULL, FALSE, FALSE, NULL);

    (*ippdscdb)->hThread = CreateThread(NULL, 0,  DSCDB_Thread, *ippdscdb, 0, &((*ippdscdb)->dwThreadID));
    WaitForSingleObject((*ippdscdb)->hStartUpEvent, INFINITE);
    CloseHandle((*ippdscdb)->hStartUpEvent);
    (*ippdscdb)->hStartUpEvent = INVALID_HANDLE_VALUE;

    return DS_OK;
}

static const IDsCaptureDriverVtbl dscdvt =
{
    IDsCaptureDriverImpl_QueryInterface,
    IDsCaptureDriverImpl_AddRef,
    IDsCaptureDriverImpl_Release,
    IDsCaptureDriverImpl_GetDriverDesc,
    IDsCaptureDriverImpl_Open,
    IDsCaptureDriverImpl_Close,
    IDsCaptureDriverImpl_GetCaps,
    IDsCaptureDriverImpl_CreateCaptureBuffer
};

static HRESULT IDsCaptureDriverPropertySetImpl_Create(
    IDsCaptureDriverBufferImpl * dscdb,
    IDsCaptureDriverPropertySetImpl **pdscdps)
{
    IDsCaptureDriverPropertySetImpl * dscdps;
    TRACE("(%p,%p)\n",dscdb,pdscdps);

    dscdps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dscdps));
    if (dscdps == NULL) {
        WARN("out of memory\n");
        return DSERR_OUTOFMEMORY;
    }

    dscdps->ref = 0;
    dscdps->IDsDriverPropertySet_iface.lpVtbl = &dscdpsvt;
    dscdps->capture_buffer = dscdb;
    dscdb->property_set = dscdps;
    IDsCaptureDriverBuffer_AddRef((PIDSCDRIVER)dscdb);

    *pdscdps = dscdps;
    return DS_OK;
}

static HRESULT IDsCaptureDriverNotifyImpl_Create(
    IDsCaptureDriverBufferImpl * dscdb,
    IDsCaptureDriverNotifyImpl **pdscdn)
{
    IDsCaptureDriverNotifyImpl * dscdn;
    TRACE("(%p,%p)\n",dscdb,pdscdn);

    dscdn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dscdn));
    if (dscdn == NULL) {
        WARN("out of memory\n");
        return DSERR_OUTOFMEMORY;
    }

    dscdn->ref = 0;
    dscdn->IDsDriverNotify_iface.lpVtbl = &dscdnvt;
    dscdn->capture_buffer = dscdb;
    dscdb->notify = dscdn;
    IDsCaptureDriverBuffer_AddRef((PIDSCDRIVER)dscdb);

    *pdscdn = dscdn;
    return DS_OK;
}

DWORD widDsCreate(UINT wDevID, PIDSCDRIVER* drv)
{
    IDsCaptureDriverImpl** idrv = (IDsCaptureDriverImpl**)drv;
    TRACE("(%d,%p)\n",wDevID,drv);

    /* the HAL isn't much better than the HEL if we can't do mmap() */
    if (!(WInDev[wDevID].ossdev.in_caps_support & WAVECAPS_DIRECTSOUND)) {
        ERR("DirectSoundCapture flag not set\n");
        MESSAGE("This sound card's driver does not support direct access\n");
        MESSAGE("The (slower) DirectSound HEL mode will be used instead.\n");
        return MMSYSERR_NOTSUPPORTED;
    }

    *idrv = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDsCaptureDriverImpl));
    if (!*idrv)
        return MMSYSERR_NOMEM;
    (*idrv)->IDsCaptureDriver_iface.lpVtbl = &dscdvt;
    (*idrv)->ref	= 1;

    (*idrv)->wDevID	= wDevID;
    (*idrv)->capture_buffer = NULL;
    return MMSYSERR_NOERROR;
}

DWORD widDsDesc(UINT wDevID, PDSDRIVERDESC desc)
{
    memcpy(desc, &(WInDev[wDevID].ossdev.ds_desc), sizeof(DSDRIVERDESC));
    return MMSYSERR_NOERROR;
}
