/*
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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

#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 "oss.h"
#include "wine/debug.h"

#include "audio.h"

WINE_DEFAULT_DEBUG_CHANNEL(dscapture);

#ifdef HAVE_OSS

/*======================================================================*
 *           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 */
    const IDsDriverPropertySetVtbl     *lpVtbl;
    LONG                                ref;

    IDsCaptureDriverBufferImpl*         capture_buffer;
};

struct IDsCaptureDriverNotifyImpl
{
    /* IUnknown fields */
    const IDsDriverNotifyVtbl          *lpVtbl;
    LONG                                ref;

    IDsCaptureDriverBufferImpl*         capture_buffer;
};

struct IDsCaptureDriverImpl
{
    /* IUnknown fields */
    const IDsCaptureDriverVtbl         *lpVtbl;
    LONG                                ref;

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

struct IDsCaptureDriverBufferImpl
{
    /* IUnknown fields */
    const IDsCaptureDriverBufferVtbl   *lpVtbl;
    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 HRESULT WINAPI IDsCaptureDriverPropertySetImpl_Create(
    IDsCaptureDriverBufferImpl * dscdb,
    IDsCaptureDriverPropertySetImpl **pdscdps);

static HRESULT WINAPI 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 = (IDsCaptureDriverPropertySetImpl *)iface;
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsDriverPropertySet) ) {
        IDsDriverPropertySet_AddRef(iface);
        *ppobj = (LPVOID)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 = (IDsCaptureDriverPropertySetImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

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

    return refCount;
}

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

    TRACE("(%p) ref was %ld\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 = (IDsCaptureDriverPropertySetImpl *)iface;
    FIXME("(%p,%p,%p,%lx,%p,%lx,%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 = (IDsCaptureDriverPropertySetImpl *)iface;
    FIXME("(%p,%p,%p,%lx,%p,%lx)\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 = (IDsCaptureDriverPropertySetImpl *)iface;
    FIXME("(%p,%s,%lx,%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 = (IDsCaptureDriverNotifyImpl *)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 = (IDsCaptureDriverNotifyImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

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

    return refCount;
}

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

    TRACE("(%p) ref was %ld\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 = (IDsCaptureDriverNotifyImpl *)iface;
    TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify);

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

    if (TRACE_ON(dscapture)) {
        int i;
        for (i=0;i<howmuch;i++)
            TRACE("notify at %ld to 0x%08lx\n",
                notify[i].dwOffset,(DWORD)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=%ld\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 = (IDsCaptureDriverBufferImpl *)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 = (LPVOID)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 = (LPVOID)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 = (LPVOID)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 = (IDsCaptureDriverBufferImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

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

    return refCount;
}

static ULONG WINAPI IDsCaptureDriverBufferImpl_Release(PIDSCDRIVERBUFFER iface)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);
    TRACE("(%p) ref was %ld\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 = (IDsCaptureDriverBufferImpl *)iface;
    TRACE("(%p,%p,%p,%p,%p,%ld,%ld,0x%08lx)\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 = (IDsCaptureDriverBufferImpl *)iface;
    TRACE("(%p,%p,%ld,%p,%ld)\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 = (IDsCaptureDriverBufferImpl *)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=%ld, readpos=%ld\n", lpdwCapture?*lpdwCapture:0,
          lpdwRead?*lpdwRead:0);
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_GetStatus(
    PIDSCDRIVERBUFFER iface,
    LPDWORD lpdwStatus)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)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 = (IDsCaptureDriverBufferImpl *)iface;
    int enable;
    TRACE("(%p,%lx)\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 = (IDsCaptureDriverBufferImpl *)iface;
    int enable;
    TRACE("(%p)\n",This);

    if (!This->is_capturing)
        return DS_OK;

    /* no more captureing */
    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 = (IDsCaptureDriverBufferImpl *)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 = (IDsCaptureDriverImpl *)iface;
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsCaptureDriver) ) {
        IDsCaptureDriver_AddRef(iface);
        *ppobj = (LPVOID)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 = (IDsCaptureDriverImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

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

    return refCount;
}

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

    TRACE("(%p) ref was %ld\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 = (IDsCaptureDriverImpl *)iface;
    TRACE("(%p,%p)\n",This,pDesc);

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

    /* copy version from driver */
    memcpy(pDesc, &(WInDev[This->wDevID].ossdev->ds_desc), sizeof(DSDRIVERDESC));

    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 = (IDsCaptureDriverImpl *)iface;
    TRACE("(%p)\n",This);
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverImpl_Close(PIDSCDRIVER iface)
{
    IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)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 = (IDsCaptureDriverImpl *)iface;
    TRACE("(%p,%p)\n",This,pCaps);
    memcpy(pCaps, &(WInDev[This->wDevID].ossdev->dsc_caps), sizeof(DSCDRIVERCAPS));
    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,%ld,%ld,%ld)\n", dscb, writepos, len, buflen);

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

    if ((writepos + len) > offset) {
         TRACE("signalled event %p (%d) %ld\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) %ld\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] = ((char *)src)[i];
    return dst;
}

static DWORD CALLBACK DSCDB_Thread(LPVOID lpParameter)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)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 = (IDsCaptureDriverImpl *)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,%lx,%lx,%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)->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=%ld(%08lx)\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) (%ld 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) (%ld 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, (LPVOID)(*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 WINAPI 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->lpVtbl = &dscdpsvt;
    dscdps->capture_buffer = dscdb;
    dscdb->property_set = dscdps;
    IDsCaptureDriverBuffer_AddRef((PIDSCDRIVER)dscdb);

    *pdscdps = dscdps;
    return DS_OK;
}

static HRESULT WINAPI 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->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)->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;
}

#endif /* HAVE_OSS */
