/*
 * Wine Driver for MCI wave forms
 *
 * Copyright 	1994 Martin Ayotte
 *		1999,2000,2005 Eric Pouech
 *              2000 Francois Jacques
 *		2009 Jörg Höhle
 *
 * 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 <assert.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "mmddk.h"
#include "wownt32.h"
#include "digitalv.h"
#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(mciwave);

typedef struct {
    UINT			wDevID;
    HANDLE			hWave;
    int				nUseCount;	/* Incremented for each shared open */
    HMMIO			hFile;  	/* mmio file handle open as Element */
    MCIDEVICEID			wNotifyDeviceID;	/* MCI device ID with a pending notification */
    HANDLE			hCallback;	/* Callback handle for pending notification */
    LPWSTR			lpFileName;	/* Name of file (if any)                     */
    WAVEFORMATEX		wfxRef;
    LPWAVEFORMATEX		lpWaveFormat;	/* Points to wfxRef until set by OPEN or RECORD */
    BOOL			fInput;		/* FALSE = Output, TRUE = Input */
    volatile WORD		dwStatus;	/* one from MCI_MODE_xxxx */
    DWORD			dwMciTimeFormat;/* One of the supported MCI_FORMAT_xxxx */
    DWORD			dwPosition;	/* position in bytes in chunk */
    HANDLE			hEvent;		/* for synchronization */
    LONG			dwEventCount;	/* for synchronization */
    MMCKINFO                   	ckMainRIFF;     /* main RIFF chunk */
    MMCKINFO                   	ckWaveData;     /* data chunk */
} WINE_MCIWAVE;

/* ===================================================================
 * ===================================================================
 * FIXME: should be using the new mmThreadXXXX functions from WINMM
 * instead of those
 * it would require to add a wine internal flag to mmThreadCreate
 * in order to pass a 32 bit function instead of a 16 bit one
 * ===================================================================
 * =================================================================== */

typedef DWORD (*async_cmd)(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE evt);

struct SCA {
    async_cmd   cmd;
    HANDLE      evt;
    UINT 	wDevID;
    DWORD_PTR   dwParam1;
    DWORD_PTR   dwParam2;
};

/**************************************************************************
 * 				MCI_SCAStarter			[internal]
 */
static DWORD CALLBACK	MCI_SCAStarter(LPVOID arg)
{
    struct SCA*	sca = (struct SCA*)arg;
    DWORD		ret;

    TRACE("In thread before async command (%08x,%08lx,%08lx)\n",
	  sca->wDevID, sca->dwParam1, sca->dwParam2);
    ret = sca->cmd(sca->wDevID, sca->dwParam1 | MCI_WAIT, sca->dwParam2, sca->evt);
    TRACE("In thread after async command (%08x,%08lx,%08lx)\n",
	  sca->wDevID, sca->dwParam1, sca->dwParam2);
    HeapFree(GetProcessHeap(), 0, sca);
    return ret;
}

/**************************************************************************
 * 				MCI_SendCommandAsync		[internal]
 */
static	DWORD MCI_SendCommandAsync(UINT wDevID, async_cmd cmd, DWORD_PTR dwParam1,
				   DWORD_PTR dwParam2, UINT size)
{
    HANDLE handles[2];
    struct SCA*	sca = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA) + size);

    if (sca == 0)
	return MCIERR_OUT_OF_MEMORY;

    sca->wDevID   = wDevID;
    sca->cmd      = cmd;
    sca->dwParam1 = dwParam1;

    if (size && dwParam2) {
	sca->dwParam2 = (DWORD_PTR)sca + sizeof(struct SCA);
	/* copy structure passed by program in dwParam2 to be sure
	 * we can still use it whatever the program does
	 */
	memcpy((LPVOID)sca->dwParam2, (LPVOID)dwParam2, size);
    } else {
	sca->dwParam2 = dwParam2;
    }

    if ((sca->evt = handles[1] = CreateEventW(NULL, FALSE, FALSE, NULL)) == NULL ||
        (handles[0] = CreateThread(NULL, 0, MCI_SCAStarter, sca, 0, NULL)) == 0) {
	WARN("Couldn't allocate thread for async command handling, sending synchronously\n");
        if (handles[1]) CloseHandle(handles[1]);
        sca->evt = NULL;
	return MCI_SCAStarter(&sca);
    }

    SetThreadPriority(handles[0], THREAD_PRIORITY_TIME_CRITICAL);
    /* wait until either:
     * - the thread has finished (handles[0], likely an error)
     * - init phase of async command is done (handles[1])
     */
    WaitForMultipleObjects(2, handles, FALSE, INFINITE);
    CloseHandle(handles[0]);
    CloseHandle(handles[1]);
    return 0;
}

/*======================================================================*
 *                  	    MCI WAVE implementation			*
 *======================================================================*/

static DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);

/**************************************************************************
 * 				MCIWAVE_drvOpen			[internal]
 */
static LRESULT WAVE_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
{
    WINE_MCIWAVE*	wmw;

    if (modp == NULL) return 0xFFFFFFFF;

    wmw = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIWAVE));

    if (!wmw)
	return 0;

    wmw->wDevID = modp->wDeviceID;
    mciSetDriverData(wmw->wDevID, (DWORD_PTR)wmw);
    modp->wCustomCommandTable = MCI_NO_COMMAND_TABLE;
    modp->wType = MCI_DEVTYPE_WAVEFORM_AUDIO;

    wmw->wfxRef.wFormatTag     	= WAVE_FORMAT_PCM;
    wmw->wfxRef.nChannels       = 1;      /* MONO */
    wmw->wfxRef.nSamplesPerSec  = 11025;
    wmw->wfxRef.nAvgBytesPerSec = 11025;
    wmw->wfxRef.nBlockAlign     = 1;
    wmw->wfxRef.wBitsPerSample  = 8;
    wmw->wfxRef.cbSize          = 0;      /* don't care */

    return modp->wDeviceID;
}

/**************************************************************************
 * 				MCIWAVE_drvClose		[internal]
 */
static LRESULT WAVE_drvClose(MCIDEVICEID dwDevID)
{
    WINE_MCIWAVE*  wmw = (WINE_MCIWAVE*)mciGetDriverData(dwDevID);

    if (wmw) {
	HeapFree(GetProcessHeap(), 0, wmw);
	mciSetDriverData(dwDevID, 0);
	return 1;
    }
    return (dwDevID == 0xFFFFFFFF) ? 1 : 0;
}

/**************************************************************************
 * 				WAVE_mciGetOpenDev		[internal]
 */
static WINE_MCIWAVE *WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
{
    WINE_MCIWAVE*	wmw = (WINE_MCIWAVE*)mciGetDriverData(wDevID);

    if (wmw == NULL || wmw->nUseCount == 0) {
	WARN("Invalid wDevID=%u\n", wDevID);
	return 0;
    }
    return wmw;
}

/**************************************************************************
 *				WAVE_mciNotify			[internal]
 *
 * Notifications in MCI work like a 1-element queue.
 * Each new notification request supersedes the previous one.
 * This affects Play and Record; other commands are immediate.
 */
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE* wmw, UINT wStatus)
{
    /* We simply save one parameter by not passing the wDevID local
     * to the command.  They are the same (via mciGetDriverData).
     */
    MCIDEVICEID wDevID = wmw->wNotifyDeviceID;
    HANDLE old = InterlockedExchangePointer(&wmw->hCallback, NULL);
    if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_SUPERSEDED);
    mciDriverNotify(HWND_32(LOWORD(hWndCallBack)), wDevID, wStatus);
}

/**************************************************************************
 * 				WAVE_ConvertByteToTimeFormat	[internal]
 */
static	DWORD 	WAVE_ConvertByteToTimeFormat(WINE_MCIWAVE* wmw, DWORD val, LPDWORD lpRet)
{
    DWORD	   ret = 0;

    switch (wmw->dwMciTimeFormat) {
    case MCI_FORMAT_MILLISECONDS:
	ret = MulDiv(val,1000,wmw->lpWaveFormat->nAvgBytesPerSec);
	break;
    case MCI_FORMAT_BYTES:
	ret = val;
	break;
    case MCI_FORMAT_SAMPLES:
	ret = MulDiv(val,wmw->lpWaveFormat->nSamplesPerSec,wmw->lpWaveFormat->nAvgBytesPerSec);
	break;
    default:
	WARN("Bad time format %u!\n", wmw->dwMciTimeFormat);
    }
    TRACE("val=%u=0x%08x [tf=%u] => ret=%u\n", val, val, wmw->dwMciTimeFormat, ret);
    *lpRet = 0;
    return ret;
}

/**************************************************************************
 * 				WAVE_ConvertTimeFormatToByte	[internal]
 */
static	DWORD 	WAVE_ConvertTimeFormatToByte(WINE_MCIWAVE* wmw, DWORD val)
{
    DWORD	ret = 0;

    switch (wmw->dwMciTimeFormat) {
    case MCI_FORMAT_MILLISECONDS:
	ret = MulDiv(val,wmw->lpWaveFormat->nAvgBytesPerSec,1000);
	break;
    case MCI_FORMAT_BYTES:
	ret = val;
	break;
    case MCI_FORMAT_SAMPLES:
	ret = MulDiv(val,wmw->lpWaveFormat->nAvgBytesPerSec,wmw->lpWaveFormat->nSamplesPerSec);
	break;
    default:
	WARN("Bad time format %u!\n", wmw->dwMciTimeFormat);
    }
    TRACE("val=%u=0x%08x [tf=%u] => ret=%u\n", val, val, wmw->dwMciTimeFormat, ret);
    return ret;
}

/**************************************************************************
 * 			WAVE_mciReadFmt	                        [internal]
 */
static	DWORD WAVE_mciReadFmt(WINE_MCIWAVE* wmw, const MMCKINFO* pckMainRIFF)
{
    MMCKINFO	mmckInfo;
    long	r;
    LPWAVEFORMATEX pwfx;

    mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
    if (mmioDescend(wmw->hFile, &mmckInfo, pckMainRIFF, MMIO_FINDCHUNK) != 0)
	return MCIERR_INVALID_FILE;
    TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08X\n",
	  (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);

    pwfx = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
    if (!pwfx) return MCIERR_OUT_OF_MEMORY;

    r = mmioRead(wmw->hFile, (HPSTR)pwfx, mmckInfo.cksize);
    if (r < sizeof(PCMWAVEFORMAT)) {
	HeapFree(GetProcessHeap(), 0, pwfx);
	return MCIERR_INVALID_FILE;
    }
    TRACE("wFormatTag=%04X !\n",   pwfx->wFormatTag);
    TRACE("nChannels=%d\n",        pwfx->nChannels);
    TRACE("nSamplesPerSec=%d\n",   pwfx->nSamplesPerSec);
    TRACE("nAvgBytesPerSec=%d\n",  pwfx->nAvgBytesPerSec);
    TRACE("nBlockAlign=%d\n",      pwfx->nBlockAlign);
    TRACE("wBitsPerSample=%u !\n", pwfx->wBitsPerSample);
    if (r >= (long)sizeof(WAVEFORMATEX))
	TRACE("cbSize=%u !\n",     pwfx->cbSize);
    if ((pwfx->wFormatTag != WAVE_FORMAT_PCM)
	&& (r < sizeof(WAVEFORMATEX) || (r < sizeof(WAVEFORMATEX) + pwfx->cbSize))) {
	HeapFree(GetProcessHeap(), 0, pwfx);
	return MCIERR_INVALID_FILE;
    }
    wmw->lpWaveFormat = pwfx;

    mmioAscend(wmw->hFile, &mmckInfo, 0);
    wmw->ckWaveData.ckid = mmioFOURCC('d', 'a', 't', 'a');
    if (mmioDescend(wmw->hFile, &wmw->ckWaveData, pckMainRIFF, MMIO_FINDCHUNK) != 0) {
	TRACE("can't find data chunk\n");
	return MCIERR_INVALID_FILE;
    }
    TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08X\n",
	  (LPSTR)&wmw->ckWaveData.ckid, (LPSTR)&wmw->ckWaveData.fccType, wmw->ckWaveData.cksize);
    return 0;
}

/**************************************************************************
 * 			WAVE_mciDefaultFmt			[internal]
 *
 * wmw->lpWaveFormat points to the default wave format at wmw->wfxRef
 * until either Open File or Record.  It becomes immutable afterwards,
 * i.e. Set wave format or channels etc. is subsequently refused.
 */
static void WAVE_mciDefaultFmt(WINE_MCIWAVE* wmw)
{
    wmw->lpWaveFormat = &wmw->wfxRef;
    wmw->lpWaveFormat->wFormatTag = WAVE_FORMAT_PCM;
    wmw->lpWaveFormat->nChannels = 1;
    wmw->lpWaveFormat->nSamplesPerSec = 11025;
    wmw->lpWaveFormat->nAvgBytesPerSec = 11025;
    wmw->lpWaveFormat->nBlockAlign = 1;
    wmw->lpWaveFormat->wBitsPerSample = 8;
    wmw->lpWaveFormat->cbSize = 0;
}

/**************************************************************************
 * 			WAVE_mciCreateRIFFSkeleton              [internal]
 */
static DWORD WAVE_mciCreateRIFFSkeleton(WINE_MCIWAVE* wmw)
{
   MMCKINFO     ckWaveFormat;
   LPMMCKINFO   lpckRIFF     = &(wmw->ckMainRIFF);
   LPMMCKINFO   lpckWaveData = &(wmw->ckWaveData);

   lpckRIFF->ckid    = FOURCC_RIFF;
   lpckRIFF->fccType = mmioFOURCC('W', 'A', 'V', 'E');
   lpckRIFF->cksize  = 0;

   if (MMSYSERR_NOERROR != mmioCreateChunk(wmw->hFile, lpckRIFF, MMIO_CREATERIFF))
	goto err;

   ckWaveFormat.fccType = 0;
   ckWaveFormat.ckid    = mmioFOURCC('f', 'm', 't', ' ');
   ckWaveFormat.cksize  = sizeof(PCMWAVEFORMAT);

   /* Set wave format accepts PCM only, however open an
    * existing ADPCM file, record into it and the MCI will
    * happily save back in that format. */
   if (wmw->lpWaveFormat->wFormatTag == WAVE_FORMAT_PCM) {
	if (wmw->lpWaveFormat->nBlockAlign !=
	    wmw->lpWaveFormat->nChannels * wmw->lpWaveFormat->wBitsPerSample/8) {
	    WORD size = wmw->lpWaveFormat->nChannels *
		wmw->lpWaveFormat->wBitsPerSample/8;
	    WARN("Incorrect nBlockAlign (%d), setting it to %d\n",
		wmw->lpWaveFormat->nBlockAlign, size);
	    wmw->lpWaveFormat->nBlockAlign = size;
	}
	if (wmw->lpWaveFormat->nAvgBytesPerSec !=
	    wmw->lpWaveFormat->nSamplesPerSec * wmw->lpWaveFormat->nBlockAlign) {
	    DWORD speed = wmw->lpWaveFormat->nSamplesPerSec *
		wmw->lpWaveFormat->nBlockAlign;
	    WARN("Incorrect nAvgBytesPerSec (%d), setting it to %d\n",
		wmw->lpWaveFormat->nAvgBytesPerSec, speed);
	    wmw->lpWaveFormat->nAvgBytesPerSec = speed;
	}
   }
   if (wmw->lpWaveFormat == &wmw->wfxRef) {
	LPWAVEFORMATEX pwfx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WAVEFORMATEX));
	if (!pwfx) return MCIERR_OUT_OF_MEMORY;
	/* Set wave format accepts PCM only so the size is known. */
	assert(wmw->wfxRef.wFormatTag == WAVE_FORMAT_PCM);
	*pwfx = wmw->wfxRef;
	wmw->lpWaveFormat = pwfx;
   }

   if (MMSYSERR_NOERROR != mmioCreateChunk(wmw->hFile, &ckWaveFormat, 0))
	goto err;

   if (-1 == mmioWrite(wmw->hFile, (HPCSTR)wmw->lpWaveFormat, (WAVE_FORMAT_PCM==wmw->lpWaveFormat->wFormatTag)
	? sizeof(PCMWAVEFORMAT) : sizeof(WAVEFORMATEX)+wmw->lpWaveFormat->cbSize))
	goto err;

   if (MMSYSERR_NOERROR != mmioAscend(wmw->hFile, &ckWaveFormat, 0))
	goto err;

   lpckWaveData->cksize  = 0;
   lpckWaveData->fccType = 0;
   lpckWaveData->ckid    = mmioFOURCC('d', 'a', 't', 'a');

   /* create data chunk */
   if (MMSYSERR_NOERROR != mmioCreateChunk(wmw->hFile, lpckWaveData, 0))
	goto err;

   return 0;

err:
   /* mciClose takes care of wmw->lpWaveFormat. */
   return MCIERR_INVALID_FILE;
}

static DWORD create_tmp_file(HMMIO* hFile, LPWSTR* pszTmpFileName)
{
    WCHAR       szTmpPath[MAX_PATH];
    WCHAR       szPrefix[4];
    DWORD       dwRet = MMSYSERR_NOERROR;

    szPrefix[0] = 'M';
    szPrefix[1] = 'C';
    szPrefix[2] = 'I';
    szPrefix[3] = '\0';

    if (!GetTempPathW(sizeof(szTmpPath)/sizeof(szTmpPath[0]), szTmpPath)) {
        WARN("can't retrieve temp path!\n");
        *pszTmpFileName = NULL;
        return MCIERR_FILE_NOT_FOUND;
    }

    *pszTmpFileName = HeapAlloc(GetProcessHeap(),
                                HEAP_ZERO_MEMORY,
                                MAX_PATH * sizeof(WCHAR));
    if (!GetTempFileNameW(szTmpPath, szPrefix, 0, *pszTmpFileName)) {
        WARN("can't retrieve temp file name!\n");
        HeapFree(GetProcessHeap(), 0, *pszTmpFileName);
        return MCIERR_FILE_NOT_FOUND;
    }

    TRACE("%s!\n", debugstr_w(*pszTmpFileName));

    if (*pszTmpFileName && (strlenW(*pszTmpFileName) > 0)) {

        *hFile = mmioOpenW(*pszTmpFileName, NULL,
                           MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE);

        if (*hFile == 0) {
            WARN("can't create file=%s!\n", debugstr_w(*pszTmpFileName));
            /* temporary file could not be created. clean filename. */
            HeapFree(GetProcessHeap(), 0, *pszTmpFileName);
            dwRet = MCIERR_FILE_NOT_FOUND;
        }
    }
    return dwRet;
}

static LRESULT WAVE_mciOpenFile(WINE_MCIWAVE* wmw, LPCWSTR filename)
{
    LRESULT dwRet = MMSYSERR_NOERROR;
    LPWSTR fn;

    fn = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
    if (!fn) return MCIERR_OUT_OF_MEMORY;
    strcpyW(fn, filename);
    HeapFree(GetProcessHeap(), 0, (void*)wmw->lpFileName);
    wmw->lpFileName = fn;

    if (strlenW(filename) > 0) {
        /* FIXME : what should be done if wmw->hFile is already != 0, or the driver is playin' */
        TRACE("MCI_OPEN_ELEMENT %s!\n", debugstr_w(filename));

        wmw->hFile = mmioOpenW((LPWSTR)filename, NULL,
                               MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READ);

        if (wmw->hFile == 0) {
            WARN("can't find file=%s!\n", debugstr_w(filename));
            dwRet = MCIERR_FILE_NOT_FOUND;
        }
        else
        {
            LPMMCKINFO          lpckMainRIFF = &wmw->ckMainRIFF;

            /* make sure we're are the beginning of the file */
            mmioSeek(wmw->hFile, 0, SEEK_SET);

            /* first reading of this file. read the waveformat chunk */
            if (mmioDescend(wmw->hFile, lpckMainRIFF, NULL, 0) != 0) {
                dwRet = MCIERR_INVALID_FILE;
            } else {
                TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n",
                      (LPSTR)&(lpckMainRIFF->ckid),
                      (LPSTR) &(lpckMainRIFF->fccType),
                      (lpckMainRIFF->cksize));

                if ((lpckMainRIFF->ckid != FOURCC_RIFF) ||
                    lpckMainRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E')) {
                    dwRet = MCIERR_INVALID_FILE;
                } else {
                    dwRet = WAVE_mciReadFmt(wmw, lpckMainRIFF);
                }
            }
        }
    }
    return dwRet;
}

/**************************************************************************
 * 			WAVE_mciOpen	                        [internal]
 */
static LRESULT WAVE_mciOpen(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMSW lpOpenParms)
{
    DWORD		dwRet = 0;
    WINE_MCIWAVE*	wmw = (WINE_MCIWAVE*)mciGetDriverData(wDevID);

    TRACE("(%04X, %08X, %p)\n", wDevID, dwFlags, lpOpenParms);
    if (lpOpenParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;
    if (wmw == NULL) 		return MCIERR_INVALID_DEVICE_ID;

    if (dwFlags & MCI_OPEN_SHAREABLE)
	return MCIERR_UNSUPPORTED_FUNCTION;

    if (wmw->nUseCount > 0) {
	/* The driver is already opened on this channel
	 * Wave driver cannot be shared
	 */
	return MCIERR_DEVICE_OPEN;
    }

    wmw->nUseCount++;

    wmw->fInput = FALSE;
    wmw->hWave = 0;
    wmw->dwStatus = MCI_MODE_NOT_READY;
    wmw->hFile = 0;
    wmw->lpFileName = NULL; /* will be set by WAVE_mciOpenFile */
    wmw->hCallback = NULL;
    WAVE_mciDefaultFmt(wmw);

    TRACE("wDevID=%04X (lpParams->wDeviceID=%08X)\n", wDevID, lpOpenParms->wDeviceID);
    /* Logs show the native winmm calls us with 0 still in lpOpenParms.wDeviceID */
    wmw->wNotifyDeviceID = wDevID;

    if (dwFlags & MCI_OPEN_ELEMENT) {
	if (dwFlags & MCI_OPEN_ELEMENT_ID) {
	    /* could it be that (DWORD)lpOpenParms->lpstrElementName
	     * contains the hFile value ?
	     */
	    dwRet = MCIERR_UNRECOGNIZED_COMMAND;
	} else {
            dwRet = WAVE_mciOpenFile(wmw, lpOpenParms->lpstrElementName);
	}
    }
    TRACE("hFile=%p\n", wmw->hFile);

    if (dwRet == 0) {
	wmw->dwPosition = 0;

	wmw->dwStatus = MCI_MODE_STOP;

	if (dwFlags & MCI_NOTIFY)
	    WAVE_mciNotify(lpOpenParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);
    } else {
	wmw->nUseCount--;
	if (wmw->hFile != 0)
	    mmioClose(wmw->hFile, 0);
	wmw->hFile = 0;
    }
    return dwRet;
}

/**************************************************************************
 *                               WAVE_mciCue             [internal]
 */
static DWORD WAVE_mciCue(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);

    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);

    /* Tests on systems without sound drivers show that Cue, like
     * Record and Play, opens winmm, returning MCIERR_WAVE_xyPUTSUNSUITABLE.
     * The first Cue Notify does not immediately return the
     * notification, as if a player or recorder thread is started.
     * PAUSE mode is reported when successful, but this mode is
     * different from the normal Pause, because a) Pause then returns
     * NONAPPLICABLE_FUNCTION instead of 0 and b) Set Channels etc. is
     * still accepted, returning the original notification as ABORTED.
     * I.e. Cue allows subsequent format changes, unlike Record or
     * Open file, closes winmm if the format changes and stops this
     * thread.
     * Wine creates one player or recorder thread per async. Play or
     * Record command.  Notification behaviour suggests that MS-W*
     * reuses a single thread to improve response times.  Having Cue
     * start this thread early helps to improve Play/Record's initial
     * response time.  In effect, Cue is a performance hint, which
     * justifies our almost no-op implementation.
     */

    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;
    if (wmw->dwStatus != MCI_MODE_STOP) return MCIERR_NONAPPLICABLE_FUNCTION;

    if ((dwFlags & MCI_NOTIFY) && lpParms)
	WAVE_mciNotify(lpParms->dwCallback,wmw,MCI_NOTIFY_SUCCESSFUL);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				WAVE_mciStop			[internal]
 */
static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
    DWORD 		dwRet = 0;
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);

    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);

    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;

    if (wmw->dwStatus != MCI_MODE_STOP) {
	HANDLE old = InterlockedExchangePointer(&wmw->hCallback, NULL);
	if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_ABORTED);
    }

    /* wait for playback thread (if any) to exit before processing further */
    switch (wmw->dwStatus) {
    case MCI_MODE_PAUSE:
    case MCI_MODE_PLAY:
    case MCI_MODE_RECORD:
	{
	    int oldStat = wmw->dwStatus;
	    wmw->dwStatus = MCI_MODE_NOT_READY;
	    if (oldStat == MCI_MODE_PAUSE)
		dwRet = (wmw->fInput) ? waveInReset(wmw->hWave) : waveOutReset(wmw->hWave);
	}
	while (wmw->dwStatus != MCI_MODE_STOP)
	    Sleep(10);
	break;
    }

    /* sanity resets */
    wmw->dwStatus = MCI_MODE_STOP;

    if ((dwFlags & MCI_NOTIFY) && lpParms && MMSYSERR_NOERROR==dwRet)
	WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);

    return dwRet;
}

/**************************************************************************
 *				WAVE_mciClose		[internal]
 */
static DWORD WAVE_mciClose(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
    DWORD		dwRet = 0;
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);

    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);

    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;

    if (wmw->dwStatus != MCI_MODE_STOP) {
        /* mciStop handles MCI_NOTIFY_ABORTED */
	dwRet = WAVE_mciStop(wDevID, MCI_WAIT, lpParms);
    }

    wmw->nUseCount--;

    if (wmw->nUseCount == 0) {
	if (wmw->hFile != 0) {
	    mmioClose(wmw->hFile, 0);
	    wmw->hFile = 0;
	}
    }

    if (wmw->lpWaveFormat != &wmw->wfxRef)
	HeapFree(GetProcessHeap(), 0, wmw->lpWaveFormat);
    wmw->lpWaveFormat = &wmw->wfxRef;
    HeapFree(GetProcessHeap(), 0, (void*)wmw->lpFileName);
    wmw->lpFileName = NULL;

    if ((dwFlags & MCI_NOTIFY) && lpParms) {
	WAVE_mciNotify(lpParms->dwCallback, wmw,
	    (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
    }

    return 0;
}

/**************************************************************************
 * 				WAVE_mciPlayCallback		[internal]
 */
static	void	CALLBACK WAVE_mciPlayCallback(HWAVEOUT hwo, UINT uMsg,
					      DWORD_PTR dwInstance,
					      LPARAM dwParam1, LPARAM dwParam2)
{
    WINE_MCIWAVE*	wmw = (WINE_MCIWAVE*)dwInstance;

    switch (uMsg) {
    case WOM_OPEN:
    case WOM_CLOSE:
	break;
    case WOM_DONE:
	InterlockedIncrement(&wmw->dwEventCount);
	TRACE("Returning waveHdr=%lx\n", dwParam1);
	SetEvent(wmw->hEvent);
	break;
    default:
	ERR("Unknown uMsg=%d\n", uMsg);
    }
}

/******************************************************************
 *			WAVE_mciPlayWaitDone		[internal]
 */
static void WAVE_mciPlayWaitDone(WINE_MCIWAVE* wmw)
{
    for (;;) {
	ResetEvent(wmw->hEvent);
	if (InterlockedDecrement(&wmw->dwEventCount) >= 0) {
	    break;
	}
	InterlockedIncrement(&wmw->dwEventCount);

	WaitForSingleObject(wmw->hEvent, INFINITE);
    }
}

/**************************************************************************
 * 				WAVE_mciPlay		[internal]
 */
static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
{
    LPMCI_PLAY_PARMS    lpParms = (void*)pmt;
    DWORD		end;
    LONG		bufsize, count, left;
    DWORD		dwRet;
    LPWAVEHDR		waveHdr = NULL;
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);
    HANDLE		oldcb;
    int			whidx;

    TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);

    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;
    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;

    if (wmw->hFile == 0) {
	WARN("Can't play: no file=%s!\n", debugstr_w(wmw->lpFileName));
	return MCIERR_FILE_NOT_FOUND;
    }

    if (wmw->dwStatus == MCI_MODE_PAUSE && !wmw->fInput) {
	/* FIXME: parameters (start/end) in lpParams may not be used */
	return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms);
    }

    /** This function will be called again by a thread when async is used.
     * We have to set MCI_MODE_PLAY before we do this so that the app can spin
     * on MCI_STATUS, so we have to allow it here if we're not going to start this thread.
     */
    if ((wmw->dwStatus != MCI_MODE_STOP) && ((wmw->dwStatus != MCI_MODE_PLAY) && (dwFlags & MCI_WAIT))) {
	return MCIERR_INTERNAL;
    }

    if (wmw->lpWaveFormat->wFormatTag == WAVE_FORMAT_PCM) {
        if (wmw->lpWaveFormat->nBlockAlign !=
            wmw->lpWaveFormat->nChannels * wmw->lpWaveFormat->wBitsPerSample/8) {
            WARN("Incorrect nBlockAlign (%d), setting it to %d\n",
                wmw->lpWaveFormat->nBlockAlign,
                wmw->lpWaveFormat->nChannels *
                 wmw->lpWaveFormat->wBitsPerSample/8);
            wmw->lpWaveFormat->nBlockAlign =
                wmw->lpWaveFormat->nChannels *
                wmw->lpWaveFormat->wBitsPerSample/8;
        }
        if (wmw->lpWaveFormat->nAvgBytesPerSec !=
            wmw->lpWaveFormat->nSamplesPerSec * wmw->lpWaveFormat->nBlockAlign) {
            WARN("Incorrect nAvgBytesPerSec (%d), setting it to %d\n",
                wmw->lpWaveFormat->nAvgBytesPerSec,
                wmw->lpWaveFormat->nSamplesPerSec *
                 wmw->lpWaveFormat->nBlockAlign);
            wmw->lpWaveFormat->nAvgBytesPerSec =
                wmw->lpWaveFormat->nSamplesPerSec *
                wmw->lpWaveFormat->nBlockAlign;
        }
    }

    end = wmw->ckWaveData.cksize;
    if (lpParms && (dwFlags & MCI_TO)) {
	DWORD position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
	if (position > end)		return MCIERR_OUTOFRANGE;
	end = position;
    }
    if (lpParms && (dwFlags & MCI_FROM)) {
	DWORD position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwFrom);
	if (position > end)		return MCIERR_OUTOFRANGE;
	/* Seek rounds down, so do we. */
	position /= wmw->lpWaveFormat->nBlockAlign;
	position *= wmw->lpWaveFormat->nBlockAlign;
	wmw->dwPosition = position;
    }
    if (end < wmw->dwPosition) return MCIERR_OUTOFRANGE;
    left = end - wmw->dwPosition;
    if (0==left) return MMSYSERR_NOERROR; /* FIXME: NOTIFY */

    wmw->fInput = FALSE; /* FIXME: waveInOpen may have been called. */
    wmw->dwStatus = MCI_MODE_PLAY;

    if (!(dwFlags & MCI_WAIT)) {
	return MCI_SendCommandAsync(wDevID, WAVE_mciPlay, dwFlags,
				    (DWORD_PTR)lpParms, sizeof(MCI_PLAY_PARMS));
    }

    TRACE("Playing from byte=%u to byte=%u\n", wmw->dwPosition, end);

    oldcb = InterlockedExchangePointer(&wmw->hCallback,
	(dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL);
    if (oldcb) mciDriverNotify(oldcb, wDevID, MCI_NOTIFY_ABORTED);
    oldcb = NULL;

#define	WAVE_ALIGN_ON_BLOCK(wmw,v) \
((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)

    /* go back to beginning of chunk plus the requested position */
    /* FIXME: I'm not sure this is correct, notably because some data linked to
     * the decompression state machine will not be correctly initialized.
     * try it this way (other way would be to decompress from 0 up to dwPosition
     * and to start sending to hWave when dwPosition is reached)
     */
    mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */

    /* FIXME: how to choose between several output channels ? here mapper is forced */
    dwRet = waveOutOpen((HWAVEOUT *)&wmw->hWave, WAVE_MAPPER, wmw->lpWaveFormat,
			(DWORD_PTR)WAVE_mciPlayCallback, (DWORD_PTR)wmw, CALLBACK_FUNCTION);

    if (dwRet != 0) {
	TRACE("Can't open low level audio device %d\n", dwRet);
	dwRet = MCIERR_DEVICE_OPEN;
	wmw->hWave = 0;
	goto cleanUp;
    }

    /* make it so that 3 buffers per second are needed */
    bufsize = WAVE_ALIGN_ON_BLOCK(wmw, wmw->lpWaveFormat->nAvgBytesPerSec / 3);

    waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
    waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
    waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
    waveHdr[0].dwUser         = waveHdr[1].dwUser         = 0L;
    waveHdr[0].dwLoops        = waveHdr[1].dwLoops        = 0L;
    waveHdr[0].dwFlags        = waveHdr[1].dwFlags        = 0L;
    waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
    if (waveOutPrepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
	waveOutPrepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
	dwRet = MCIERR_INTERNAL;
	goto cleanUp;
    }

    whidx = 0;
    wmw->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
    wmw->dwEventCount = 1L; /* for first buffer */

    TRACE("Playing (normalized) from byte=%u for %u bytes\n", wmw->dwPosition, left);
    if (hEvent) SetEvent(hEvent);

    /* FIXME: this doesn't work if wmw->dwPosition != 0 */
    while (left > 0 && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {
	count = mmioRead(wmw->hFile, waveHdr[whidx].lpData, min(bufsize, left));
	TRACE("mmioRead bufsize=%d count=%d\n", bufsize, count);
	if (count < 1)
	    break;
	/* count is always <= bufsize, so this is correct regarding the
	 * waveOutPrepareHeader function
	 */
	waveHdr[whidx].dwBufferLength = count;
	waveHdr[whidx].dwFlags &= ~WHDR_DONE;
	TRACE("before WODM_WRITE lpWaveHdr=%p dwBufferLength=%u\n",
	      &waveHdr[whidx], waveHdr[whidx].dwBufferLength);
	dwRet = waveOutWrite(wmw->hWave, &waveHdr[whidx], sizeof(WAVEHDR));
	if (dwRet) {
	    ERR("Aborting play loop, WODM_WRITE error %d\n", dwRet);
	    dwRet = MCIERR_HARDWARE;
	    break;
	}
	left -= count;
	wmw->dwPosition += count;
	TRACE("after WODM_WRITE dwPosition=%u\n", wmw->dwPosition);
	/* InterlockedDecrement if and only if waveOutWrite is successful */
	WAVE_mciPlayWaitDone(wmw);
	whidx ^= 1;
    }

    WAVE_mciPlayWaitDone(wmw); /* to balance first buffer */

    /* just to get rid of some race conditions between play, stop and pause */
    waveOutReset(wmw->hWave);

    waveOutUnprepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR));
    waveOutUnprepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR));

cleanUp:
    if (dwFlags & MCI_NOTIFY)
	oldcb = InterlockedExchangePointer(&wmw->hCallback, NULL);

    HeapFree(GetProcessHeap(), 0, waveHdr);

    if (wmw->hWave) {
	waveOutClose(wmw->hWave);
	wmw->hWave = 0;
    }
    CloseHandle(wmw->hEvent);

    wmw->dwStatus = MCI_MODE_STOP;

    /* Let the potentically asynchronous commands support FAILURE notification. */
    if (oldcb) mciDriverNotify(oldcb, wDevID,
	dwRet ? MCI_NOTIFY_FAILURE : MCI_NOTIFY_SUCCESSFUL);

    return dwRet;
}

/**************************************************************************
 * 				WAVE_mciRecordCallback		[internal]
 */
static	void	CALLBACK WAVE_mciRecordCallback(HWAVEOUT hwo, UINT uMsg,
                                                DWORD_PTR dwInstance,
                                                LPARAM dwParam1, LPARAM dwParam2)
{
    WINE_MCIWAVE*	wmw = (WINE_MCIWAVE*)dwInstance;
    LPWAVEHDR           lpWaveHdr;
    LONG                count = 0;

    switch (uMsg) {
    case WIM_OPEN:
    case WIM_CLOSE:
	break;
    case WIM_DATA:
	lpWaveHdr = (LPWAVEHDR) dwParam1;

	InterlockedIncrement(&wmw->dwEventCount);

	count = mmioWrite(wmw->hFile, lpWaveHdr->lpData, lpWaveHdr->dwBytesRecorded);

	lpWaveHdr->dwFlags &= ~WHDR_DONE;
        if (count > 0)
            wmw->dwPosition  += count;
        /* else error reporting ?? */
        if (wmw->dwStatus == MCI_MODE_RECORD)
        {
           /* Only queue up another buffer if we are recording.  We could receive this
              message also when waveInReset() is called, since it notifies on all wave
              buffers that are outstanding.  Queueing up more sometimes causes waveInClose
              to fail. */
           waveInAddBuffer(wmw->hWave, lpWaveHdr, sizeof(*lpWaveHdr));
           TRACE("after mmioWrite dwPosition=%u\n", wmw->dwPosition);
        }

	SetEvent(wmw->hEvent);
	break;
    default:
	ERR("Unknown uMsg=%d\n", uMsg);
    }
}

/******************************************************************
 *			WAVE_mciRecordWaitDone		[internal]
 */
static void WAVE_mciRecordWaitDone(WINE_MCIWAVE* wmw)
{
    for (;;) {
	ResetEvent(wmw->hEvent);
	if (InterlockedDecrement(&wmw->dwEventCount) >= 0) {
	    break;
	}
	InterlockedIncrement(&wmw->dwEventCount);

	WaitForSingleObject(wmw->hEvent, INFINITE);
    }
}

/**************************************************************************
 * 				WAVE_mciRecord			[internal]
 */
static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
{
    LPMCI_RECORD_PARMS  lpParms = (void*)pmt;
    DWORD		end;
    DWORD		dwRet = MMSYSERR_NOERROR;
    LONG		bufsize;
    LPWAVEHDR		waveHdr = NULL;
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);
    HANDLE		oldcb;

    TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);

    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;
    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;

    if (wmw->dwStatus == MCI_MODE_PAUSE && wmw->fInput) {
        /* FIXME: parameters (start/end) in lpParams may not be used */
        return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms);
    }

    /** This function will be called again by a thread when async is used.
     * We have to set MCI_MODE_RECORD before we do this so that the app can spin
     * on MCI_STATUS, so we have to allow it here if we're not going to start this thread.
     */
    if ((wmw->dwStatus != MCI_MODE_STOP) && ((wmw->dwStatus != MCI_MODE_RECORD) && (dwFlags & MCI_WAIT))) {
	return MCIERR_INTERNAL;
    }

    wmw->fInput = TRUE; /* FIXME: waveOutOpen may have been called. */
    wmw->dwStatus = MCI_MODE_RECORD;

    if (!(dwFlags & MCI_WAIT)) {
	return MCI_SendCommandAsync(wDevID, WAVE_mciRecord, dwFlags,
				    (DWORD_PTR)lpParms, sizeof(MCI_RECORD_PARMS));
    }

    /* FIXME: we only re-create the RIFF structure from an existing file (if any)
     * we don't modify the wave part of an existing file (ie. we always erase an
     * existing content, we don't overwrite)
     */
    HeapFree(GetProcessHeap(), 0, (void*)wmw->lpFileName);
    dwRet = create_tmp_file(&wmw->hFile, (WCHAR**)&wmw->lpFileName);
    if (dwRet != 0) return dwRet;

    /* new RIFF file, lpWaveFormat now valid */
    dwRet = WAVE_mciCreateRIFFSkeleton(wmw);
    if (dwRet != 0) return dwRet;

    if (lpParms && (dwFlags & MCI_TO)) {
	end = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
    } else end = 0xFFFFFFFF;
    if (lpParms && (dwFlags & MCI_FROM)) {
	DWORD position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwFrom);
	if (wmw->ckWaveData.cksize < position)	return MCIERR_OUTOFRANGE;
	/* Seek rounds down, so do we. */
	position /= wmw->lpWaveFormat->nBlockAlign;
	position *= wmw->lpWaveFormat->nBlockAlign;
	wmw->dwPosition = position;
    }
    if (end==wmw->dwPosition) return MMSYSERR_NOERROR; /* FIXME: NOTIFY */

    TRACE("Recording from byte=%u to byte=%u\n", wmw->dwPosition, end);

    oldcb = InterlockedExchangePointer(&wmw->hCallback,
	(dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL);
    if (oldcb) mciDriverNotify(oldcb, wDevID, MCI_NOTIFY_ABORTED);
    oldcb = NULL;

#define	WAVE_ALIGN_ON_BLOCK(wmw,v) \
((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)

    wmw->ckWaveData.cksize = WAVE_ALIGN_ON_BLOCK(wmw, wmw->ckWaveData.cksize);

    /* Go back to the beginning of the chunk plus the requested position */
    /* FIXME: I'm not sure this is correct, notably because some data linked to
     * the decompression state machine will not be correctly initialized.
     * Try it this way (other way would be to decompress from 0 up to dwPosition
     * and to start sending to hWave when dwPosition is reached).
     */
    mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */

    /* By default the device will be opened for output, the MCI_CUE function is there to
     * change from output to input and back
     */
    /* FIXME: how to choose between several output channels ? here mapper is forced */
    dwRet = waveInOpen((HWAVEIN*)&wmw->hWave, WAVE_MAPPER, wmw->lpWaveFormat,
			(DWORD_PTR)WAVE_mciRecordCallback, (DWORD_PTR)wmw, CALLBACK_FUNCTION);

    if (dwRet != MMSYSERR_NOERROR) {
	TRACE("Can't open low level audio device %d\n", dwRet);
	dwRet = MCIERR_DEVICE_OPEN;
	wmw->hWave = 0;
	goto cleanUp;
    }

    /* make it so that 3 buffers per second are needed */
    bufsize = WAVE_ALIGN_ON_BLOCK(wmw, wmw->lpWaveFormat->nAvgBytesPerSec / 3);

    waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
    waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
    waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
    waveHdr[0].dwUser         = waveHdr[1].dwUser         = 0L;
    waveHdr[0].dwLoops        = waveHdr[1].dwLoops        = 0L;
    waveHdr[0].dwFlags        = waveHdr[1].dwFlags        = 0L;
    waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;

    if (waveInPrepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
	waveInPrepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
	dwRet = MCIERR_INTERNAL;
	goto cleanUp;
    }

    if (waveInAddBuffer(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
	waveInAddBuffer(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
	dwRet = MCIERR_INTERNAL;
	goto cleanUp;
    }

    wmw->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
    wmw->dwEventCount = 1L; /* for first buffer */

    TRACE("Recording (normalized) from byte=%u for %u bytes\n", wmw->dwPosition, end - wmw->dwPosition);

    dwRet = waveInStart(wmw->hWave);

    if (hEvent) SetEvent(hEvent);

    while (wmw->dwPosition < end && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {
	WAVE_mciRecordWaitDone(wmw);
    }
    /* Grab callback before another thread kicks in after we change dwStatus. */
    if (dwFlags & MCI_NOTIFY) {
	oldcb = InterlockedExchangePointer(&wmw->hCallback, NULL);
	dwFlags &= ~MCI_NOTIFY;
    }
    /* needed so that the callback above won't add again the buffers returned by the reset */
    wmw->dwStatus = MCI_MODE_STOP;

    waveInReset(wmw->hWave);

    waveInUnprepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR));
    waveInUnprepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR));

    dwRet = 0;

cleanUp:
    if (dwFlags & MCI_NOTIFY)
	oldcb = InterlockedExchangePointer(&wmw->hCallback, NULL);

    HeapFree(GetProcessHeap(), 0, waveHdr);

    if (wmw->hWave) {
	waveInClose(wmw->hWave);
	wmw->hWave = 0;
    }
    CloseHandle(wmw->hEvent);

    wmw->dwStatus = MCI_MODE_STOP;

    if (oldcb) mciDriverNotify(oldcb, wDevID,
	dwRet ? MCI_NOTIFY_FAILURE : MCI_NOTIFY_SUCCESSFUL);

    return dwRet;

}

/**************************************************************************
 * 				WAVE_mciPause			[internal]
 */
static DWORD WAVE_mciPause(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
    DWORD 		dwRet;
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);

    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);

    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;

    switch (wmw->dwStatus) {
    case MCI_MODE_PLAY:
	dwRet = waveOutPause(wmw->hWave);
	if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_PAUSE;
	else { /* When playthread was not started yet, winmm not opened, error 5 MMSYSERR_INVALHANDLE */
	    ERR("waveOutPause error %d\n",dwRet);
	    dwRet = MCIERR_INTERNAL;
	}
	break;
    case MCI_MODE_RECORD:
	dwRet = waveInStop(wmw->hWave);
	if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_PAUSE;
	else {
	    ERR("waveInStop error %d\n",dwRet);
	    dwRet = MCIERR_INTERNAL;
	}
	break;
    case MCI_MODE_PAUSE:
	dwRet = MMSYSERR_NOERROR;
	break;
    default:
	dwRet = MCIERR_NONAPPLICABLE_FUNCTION;
    }
    if (MMSYSERR_NOERROR==dwRet && (dwFlags & MCI_NOTIFY) && lpParms)
	WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);
    return dwRet;
}

/**************************************************************************
 * 				WAVE_mciResume			[internal]
 */
static DWORD WAVE_mciResume(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);
    DWORD		dwRet;

    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);

    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;

    switch (wmw->dwStatus) {
    case MCI_MODE_PAUSE:
	/* Only update dwStatus if wave* succeeds and will exchange buffers buffers. */
	if (wmw->fInput) {
	    dwRet = waveInStart(wmw->hWave);
	    if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_RECORD;
	    else {
		ERR("waveInStart error %d\n",dwRet);
		dwRet = MCIERR_INTERNAL;
	    }
	} else {
	    dwRet = waveOutRestart(wmw->hWave);
	    if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_PLAY;
	    else {
		ERR("waveOutRestart error %d\n",dwRet);
		dwRet = MCIERR_INTERNAL;
	    }
	}
	break;
    case MCI_MODE_PLAY:
    case MCI_MODE_RECORD:
	dwRet = MMSYSERR_NOERROR;
	break;
    default:
	dwRet = MCIERR_NONAPPLICABLE_FUNCTION;
    }
    if (MMSYSERR_NOERROR==dwRet && (dwFlags & MCI_NOTIFY) && lpParms)
	WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);
    return dwRet;
}

/**************************************************************************
 * 				WAVE_mciSeek			[internal]
 */
static DWORD WAVE_mciSeek(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
{
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);
    DWORD		position, dwRet;

    TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);

    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;
    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;

    position = dwFlags & (MCI_SEEK_TO_START|MCI_SEEK_TO_END|MCI_TO);
    if (!position)		return MCIERR_MISSING_PARAMETER;
    if (position&(position-1))	return MCIERR_FLAGS_NOT_COMPATIBLE;

    /* Stop sends MCI_NOTIFY_ABORTED when needed */
    dwRet = WAVE_mciStop(wDevID, MCI_WAIT, 0);
    if (dwRet != MMSYSERR_NOERROR) return dwRet;

    if (dwFlags & MCI_TO) {
	position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
	if (position > wmw->ckWaveData.cksize)
	    return MCIERR_OUTOFRANGE;
    } else if (dwFlags & MCI_SEEK_TO_START) {
	position = 0;
    } else {
	position = wmw->ckWaveData.cksize;
    }
    /* Seek rounds down, unless at end */
    if (position != wmw->ckWaveData.cksize) {
	position /= wmw->lpWaveFormat->nBlockAlign;
	position *= wmw->lpWaveFormat->nBlockAlign;
    }
    wmw->dwPosition = position;
    TRACE("Seeking to position=%u bytes\n", position);

    if (dwFlags & MCI_NOTIFY)
	WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				WAVE_mciSet			[internal]
 */
static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
{
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);

    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);

    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;
    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;

    if (dwFlags & MCI_SET_TIME_FORMAT) {
	switch (lpParms->dwTimeFormat) {
	case MCI_FORMAT_MILLISECONDS:
	    TRACE("MCI_FORMAT_MILLISECONDS !\n");
	    wmw->dwMciTimeFormat = MCI_FORMAT_MILLISECONDS;
	    break;
	case MCI_FORMAT_BYTES:
	    TRACE("MCI_FORMAT_BYTES !\n");
	    wmw->dwMciTimeFormat = MCI_FORMAT_BYTES;
	    break;
	case MCI_FORMAT_SAMPLES:
	    TRACE("MCI_FORMAT_SAMPLES !\n");
	    wmw->dwMciTimeFormat = MCI_FORMAT_SAMPLES;
	    break;
	default:
            WARN("Bad time format %u!\n", lpParms->dwTimeFormat);
	    return MCIERR_BAD_TIME_FORMAT;
	}
    }
    if (dwFlags & MCI_SET_VIDEO) {
	TRACE("No support for video !\n");
	return MCIERR_UNSUPPORTED_FUNCTION;
    }
    if (dwFlags & MCI_SET_DOOR_OPEN) {
	TRACE("No support for door open !\n");
	return MCIERR_UNSUPPORTED_FUNCTION;
    }
    if (dwFlags & MCI_SET_DOOR_CLOSED) {
	TRACE("No support for door close !\n");
	return MCIERR_UNSUPPORTED_FUNCTION;
    }
    if (dwFlags & MCI_SET_AUDIO) {
	if (dwFlags & MCI_SET_ON) {
	    TRACE("MCI_SET_ON audio !\n");
	} else if (dwFlags & MCI_SET_OFF) {
	    TRACE("MCI_SET_OFF audio !\n");
	} else {
	    WARN("MCI_SET_AUDIO without SET_ON or SET_OFF\n");
	    return MCIERR_BAD_INTEGER;
	}

	switch (lpParms->dwAudio)
        {
        case MCI_SET_AUDIO_ALL:         TRACE("MCI_SET_AUDIO_ALL !\n"); break;
        case MCI_SET_AUDIO_LEFT:        TRACE("MCI_SET_AUDIO_LEFT !\n"); break;
        case MCI_SET_AUDIO_RIGHT:       TRACE("MCI_SET_AUDIO_RIGHT !\n"); break;
        default:                        WARN("Unknown audio channel %u\n", lpParms->dwAudio); break;
        }
    }
    if (dwFlags & MCI_WAVE_INPUT)
	TRACE("MCI_WAVE_INPUT !\n");
    if (dwFlags & MCI_WAVE_OUTPUT)
	TRACE("MCI_WAVE_OUTPUT !\n");
    if (dwFlags & MCI_WAVE_SET_ANYINPUT)
	TRACE("MCI_WAVE_SET_ANYINPUT !\n");
    if (dwFlags & MCI_WAVE_SET_ANYOUTPUT)
	TRACE("MCI_WAVE_SET_ANYOUTPUT !\n");
    /* Set wave format parameters is refused after Open or Record.*/
    if (dwFlags & MCI_WAVE_SET_FORMATTAG) {
	TRACE("MCI_WAVE_SET_FORMATTAG = %d\n", ((LPMCI_WAVE_SET_PARMS)lpParms)->wFormatTag);
	if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
	if (((LPMCI_WAVE_SET_PARMS)lpParms)->wFormatTag != WAVE_FORMAT_PCM)
	    return MCIERR_OUTOFRANGE;
    }
    if (dwFlags & MCI_WAVE_SET_AVGBYTESPERSEC) {
	if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
	wmw->wfxRef.nAvgBytesPerSec = ((LPMCI_WAVE_SET_PARMS)lpParms)->nAvgBytesPerSec;
	TRACE("MCI_WAVE_SET_AVGBYTESPERSEC = %d\n", wmw->wfxRef.nAvgBytesPerSec);
    }
    if (dwFlags & MCI_WAVE_SET_BITSPERSAMPLE) {
	if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
	wmw->wfxRef.wBitsPerSample = ((LPMCI_WAVE_SET_PARMS)lpParms)->wBitsPerSample;
	TRACE("MCI_WAVE_SET_BITSPERSAMPLE = %d\n", wmw->wfxRef.wBitsPerSample);
    }
    if (dwFlags & MCI_WAVE_SET_BLOCKALIGN) {
	if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
	wmw->wfxRef.nBlockAlign = ((LPMCI_WAVE_SET_PARMS)lpParms)->nBlockAlign;
	TRACE("MCI_WAVE_SET_BLOCKALIGN = %d\n", wmw->wfxRef.nBlockAlign);
    }
    if (dwFlags & MCI_WAVE_SET_CHANNELS) {
	if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
	wmw->wfxRef.nChannels = ((LPMCI_WAVE_SET_PARMS)lpParms)->nChannels;
	TRACE("MCI_WAVE_SET_CHANNELS = %d\n", wmw->wfxRef.nChannels);
    }
    if (dwFlags & MCI_WAVE_SET_SAMPLESPERSEC) {
	if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
	wmw->wfxRef.nSamplesPerSec = ((LPMCI_WAVE_SET_PARMS)lpParms)->nSamplesPerSec;
	TRACE("MCI_WAVE_SET_SAMPLESPERSEC = %d\n", wmw->wfxRef.nSamplesPerSec);
    }
    if (dwFlags & MCI_NOTIFY)
	WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);
    return 0;
}

/**************************************************************************
 *				WAVE_mciSave		[internal]
 */
static DWORD WAVE_mciSave(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SAVE_PARMSW lpParms)
{
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);
    DWORD		ret = MCIERR_FILE_NOT_SAVED, tmpRet;

    TRACE("%d, %08X, %p);\n", wDevID, dwFlags, lpParms);
    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;
    if (wmw     == NULL)	return MCIERR_INVALID_DEVICE_ID;

    if (dwFlags & MCI_WAIT)
    {
    	FIXME("MCI_WAIT not implemented\n");
    }
    WAVE_mciStop(wDevID, 0, NULL);

    ret = mmioAscend(wmw->hFile, &wmw->ckWaveData, 0);
    ret = mmioAscend(wmw->hFile, &wmw->ckMainRIFF, 0);

    ret = mmioClose(wmw->hFile, 0);
    wmw->hFile = 0;

    /*
      If the destination file already exists, it has to be overwritten.  (Behaviour
      verified in Windows (2000)).  If it doesn't overwrite, it is breaking one of
      my applications.  We are making use of mmioRename, which WILL NOT overwrite
      the destination file (which is what Windows does, also verified in Win2K)
      So, lets delete the destination file before calling mmioRename.  If the
      destination file DOESN'T exist, the delete will fail silently.  Let's also be
      careful not to lose our previous error code.
    */
    tmpRet = GetLastError();
    DeleteFileW (lpParms->lpfilename);
    SetLastError(tmpRet);

    /* FIXME: Open file.wav; Save; must not rename the original file.
     * Nor must Save a.wav; Save b.wav rename a. */
    if (0 == mmioRenameW(wmw->lpFileName, lpParms->lpfilename, 0, 0 )) {
	ret = MMSYSERR_NOERROR;
    }

    if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY))
	WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);

    if (ret == MMSYSERR_NOERROR)
        ret = WAVE_mciOpenFile(wmw, lpParms->lpfilename);

    return ret;
}

/**************************************************************************
 * 				WAVE_mciStatus		[internal]
 */
static DWORD WAVE_mciStatus(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
{
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);
    DWORD		ret = 0;

    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;
    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;

    if (dwFlags & MCI_STATUS_ITEM) {
	switch (lpParms->dwItem) {
	case MCI_STATUS_CURRENT_TRACK:
	    lpParms->dwReturn = 1;
            TRACE("MCI_STATUS_CURRENT_TRACK => %lu\n", lpParms->dwReturn);
	    break;
	case MCI_STATUS_LENGTH:
	    if (!wmw->hFile) {
		lpParms->dwReturn = 0;
		return MCIERR_UNSUPPORTED_FUNCTION;
	    }
	    /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
	    lpParms->dwReturn = WAVE_ConvertByteToTimeFormat(wmw, wmw->ckWaveData.cksize, &ret);
            TRACE("MCI_STATUS_LENGTH => %lu\n", lpParms->dwReturn);
	    break;
	case MCI_STATUS_MODE:
	    TRACE("MCI_STATUS_MODE => %u\n", wmw->dwStatus);
	    lpParms->dwReturn = MAKEMCIRESOURCE(wmw->dwStatus, wmw->dwStatus);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_STATUS_MEDIA_PRESENT:
	    TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE!\n");
	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_STATUS_NUMBER_OF_TRACKS:
	    /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
	    lpParms->dwReturn = 1;
            TRACE("MCI_STATUS_NUMBER_OF_TRACKS => %lu\n", lpParms->dwReturn);
	    break;
	case MCI_STATUS_POSITION:
	    if (!wmw->hFile) {
		lpParms->dwReturn = 0;
		return MCIERR_UNSUPPORTED_FUNCTION;
	    }
	    /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
	    lpParms->dwReturn = WAVE_ConvertByteToTimeFormat(wmw,
							     (dwFlags & MCI_STATUS_START) ? 0 : wmw->dwPosition,
							     &ret);
            TRACE("MCI_STATUS_POSITION %s => %lu\n",
		  (dwFlags & MCI_STATUS_START) ? "start" : "current", lpParms->dwReturn);
	    break;
	case MCI_STATUS_READY:
	    lpParms->dwReturn = (wmw->dwStatus == MCI_MODE_NOT_READY) ?
		MAKEMCIRESOURCE(FALSE, MCI_FALSE) : MAKEMCIRESOURCE(TRUE, MCI_TRUE);
	    TRACE("MCI_STATUS_READY => %u!\n", LOWORD(lpParms->dwReturn));
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_STATUS_TIME_FORMAT:
	    lpParms->dwReturn = MAKEMCIRESOURCE(wmw->dwMciTimeFormat, MCI_FORMAT_RETURN_BASE + wmw->dwMciTimeFormat);
            TRACE("MCI_STATUS_TIME_FORMAT => %lu\n", lpParms->dwReturn);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_WAVE_INPUT:
	    TRACE("MCI_WAVE_INPUT !\n");
	    lpParms->dwReturn = 0;
	    ret = MCIERR_WAVE_INPUTUNSPECIFIED;
	    break;
	case MCI_WAVE_OUTPUT:
	    TRACE("MCI_WAVE_OUTPUT !\n");
	    {
		UINT	id;
		if (waveOutGetID(wmw->hWave, &id) == MMSYSERR_NOERROR) {
		    lpParms->dwReturn = id;
		} else {
		    lpParms->dwReturn = 0;
		    ret = MCIERR_WAVE_OUTPUTUNSPECIFIED;
		}
	    }
	    break;
	/* It is always ok to query wave format parameters,
	 * except on auto-open yield MCIERR_UNSUPPORTED_FUNCTION. */
	case MCI_WAVE_STATUS_AVGBYTESPERSEC:
	    lpParms->dwReturn = wmw->lpWaveFormat->nAvgBytesPerSec;
	    TRACE("MCI_WAVE_STATUS_AVGBYTESPERSEC => %lu\n", lpParms->dwReturn);
	    break;
	case MCI_WAVE_STATUS_BITSPERSAMPLE:
	    lpParms->dwReturn = wmw->lpWaveFormat->wBitsPerSample;
	    TRACE("MCI_WAVE_STATUS_BITSPERSAMPLE => %lu\n", lpParms->dwReturn);
	    break;
	case MCI_WAVE_STATUS_BLOCKALIGN:
	    lpParms->dwReturn = wmw->lpWaveFormat->nBlockAlign;
	    TRACE("MCI_WAVE_STATUS_BLOCKALIGN => %lu\n", lpParms->dwReturn);
	    break;
	case MCI_WAVE_STATUS_CHANNELS:
	    lpParms->dwReturn = wmw->lpWaveFormat->nChannels;
	    TRACE("MCI_WAVE_STATUS_CHANNELS => %lu\n", lpParms->dwReturn);
	    break;
	case MCI_WAVE_STATUS_FORMATTAG:
	    lpParms->dwReturn = wmw->lpWaveFormat->wFormatTag;
	    TRACE("MCI_WAVE_FORMATTAG => %lu\n", lpParms->dwReturn);
	    break;
	case MCI_WAVE_STATUS_SAMPLESPERSEC:
	    lpParms->dwReturn = wmw->lpWaveFormat->nSamplesPerSec;
	    TRACE("MCI_WAVE_STATUS_SAMPLESPERSEC => %lu\n", lpParms->dwReturn);
	    break;
	case MCI_WAVE_STATUS_LEVEL:
	    TRACE("MCI_WAVE_STATUS_LEVEL !\n");
	    lpParms->dwReturn = 0xAAAA5555;
	    break;
	default:
            WARN("unknown command %08X !\n", lpParms->dwItem);
	    return MCIERR_UNRECOGNIZED_COMMAND;
	}
    }
    if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
	WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);
    return ret;
}

/**************************************************************************
 * 				WAVE_mciGetDevCaps		[internal]
 */
static DWORD WAVE_mciGetDevCaps(MCIDEVICEID wDevID, DWORD dwFlags,
				LPMCI_GETDEVCAPS_PARMS lpParms)
{
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);
    DWORD		ret = 0;

    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);

    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;
    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;

    if (dwFlags & MCI_GETDEVCAPS_ITEM) {
	switch(lpParms->dwItem) {
	case MCI_GETDEVCAPS_DEVICE_TYPE:
	    lpParms->dwReturn = MAKEMCIRESOURCE(MCI_DEVTYPE_WAVEFORM_AUDIO, MCI_DEVTYPE_WAVEFORM_AUDIO);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_GETDEVCAPS_HAS_AUDIO:
	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_GETDEVCAPS_HAS_VIDEO:
	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_GETDEVCAPS_USES_FILES:
	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_GETDEVCAPS_COMPOUND_DEVICE:
	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_GETDEVCAPS_CAN_RECORD:
	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_GETDEVCAPS_CAN_EJECT:
	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_GETDEVCAPS_CAN_PLAY:
	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_GETDEVCAPS_CAN_SAVE:
	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
	    ret = MCI_RESOURCE_RETURNED;
	    break;
	case MCI_WAVE_GETDEVCAPS_INPUTS:
	    lpParms->dwReturn = waveInGetNumDevs();
	    break;
	case MCI_WAVE_GETDEVCAPS_OUTPUTS:
	    lpParms->dwReturn = waveOutGetNumDevs();
	    break;
	default:
            FIXME("Unknown capability (%08x) !\n", lpParms->dwItem);
	    return MCIERR_UNRECOGNIZED_COMMAND;
	}
    } else {
	WARN("No GetDevCaps-Item !\n");
	return MCIERR_UNRECOGNIZED_COMMAND;
    }
    if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
	WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);
    return ret;
}

/**************************************************************************
 * 				WAVE_mciInfo			[internal]
 */
static DWORD WAVE_mciInfo(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
{
    DWORD		ret = 0;
    LPCWSTR		str = 0;
    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);

    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);

    if (!lpParms || !lpParms->lpstrReturn)
	return MCIERR_NULL_PARAMETER_BLOCK;

    if (wmw == NULL) {
	ret = MCIERR_INVALID_DEVICE_ID;
    } else {
        static const WCHAR wszAudio  [] = {'W','i','n','e','\'','s',' ','a','u','d','i','o',' ','p','l','a','y','e','r',0};
        static const WCHAR wszWaveIn [] = {'W','i','n','e',' ','W','a','v','e',' ','I','n',0};
        static const WCHAR wszWaveOut[] = {'W','i','n','e',' ','W','a','v','e',' ','O','u','t',0};

	TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize);

	switch (dwFlags & ~(MCI_WAIT|MCI_NOTIFY)) {
	case MCI_INFO_PRODUCT: str = wszAudio; break;
	case MCI_INFO_FILE:    str = wmw->lpFileName; break;
	case MCI_WAVE_INPUT:   str = wszWaveIn; break;
	case MCI_WAVE_OUTPUT:  str = wszWaveOut; break;
	default:
            WARN("Don't know this info command (%u)\n", dwFlags);
	    ret = MCIERR_UNRECOGNIZED_COMMAND;
	}
    }
    if (str) {
	if (strlenW(str) + 1 > lpParms->dwRetSize) {
	    ret = MCIERR_PARAM_OVERFLOW;
	} else {
	    lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize);
	}
    } else {
	lpParms->lpstrReturn[0] = 0;
    }
    if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY))
	WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);
    return ret;
}

/**************************************************************************
 * 				DriverProc (MCIWAVE.@)
 */
LRESULT CALLBACK MCIWAVE_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
                                    LPARAM dwParam1, LPARAM dwParam2)
{
    TRACE("(%08lX, %p, %08X, %08lX, %08lX)\n",
	  dwDevID, hDriv, wMsg, dwParam1, dwParam2);

    switch (wMsg) {
    case DRV_LOAD:		return 1;
    case DRV_FREE:		return 1;
    case DRV_OPEN:		return WAVE_drvOpen((LPCWSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSW)dwParam2);
    case DRV_CLOSE:		return WAVE_drvClose(dwDevID);
    case DRV_ENABLE:		return 1;
    case DRV_DISABLE:		return 1;
    case DRV_QUERYCONFIGURE:	return 1;
    case DRV_CONFIGURE:		MessageBoxA(0, "MCI waveaudio Driver !", "Wine Driver", MB_OK);	return 1;
    case DRV_INSTALL:		return DRVCNF_RESTART;
    case DRV_REMOVE:		return DRVCNF_RESTART;
    }

    if (dwDevID == 0xFFFFFFFF) return MCIERR_UNSUPPORTED_FUNCTION;

    switch (wMsg) {
    case MCI_OPEN_DRIVER:	return WAVE_mciOpen      (dwDevID, dwParam1, (LPMCI_WAVE_OPEN_PARMSW)  dwParam2);
    case MCI_CLOSE_DRIVER:	return WAVE_mciClose     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
    case MCI_CUE:		return WAVE_mciCue       (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
    case MCI_PLAY:		return WAVE_mciPlay      (dwDevID, dwParam1, dwParam2, NULL);
    case MCI_RECORD:		return WAVE_mciRecord    (dwDevID, dwParam1, dwParam2, NULL);
    case MCI_STOP:		return WAVE_mciStop      (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
    case MCI_SET:		return WAVE_mciSet       (dwDevID, dwParam1, (LPMCI_SET_PARMS)         dwParam2);
    case MCI_PAUSE:		return WAVE_mciPause     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
    case MCI_RESUME:		return WAVE_mciResume    (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
    case MCI_STATUS:		return WAVE_mciStatus    (dwDevID, dwParam1, (LPMCI_STATUS_PARMS)      dwParam2);
    case MCI_GETDEVCAPS:	return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)  dwParam2);
    case MCI_INFO:		return WAVE_mciInfo      (dwDevID, dwParam1, (LPMCI_INFO_PARMSW)       dwParam2);
    case MCI_SEEK:		return WAVE_mciSeek      (dwDevID, dwParam1, (LPMCI_SEEK_PARMS)        dwParam2);
    case MCI_SAVE:		return WAVE_mciSave	 (dwDevID, dwParam1, (LPMCI_SAVE_PARMSW)       dwParam2);
	/* commands that should be supported */
    case MCI_LOAD:
    case MCI_FREEZE:
    case MCI_PUT:
    case MCI_REALIZE:
    case MCI_UNFREEZE:
    case MCI_UPDATE:
    case MCI_WHERE:
    case MCI_STEP:
    case MCI_SPIN:
    case MCI_ESCAPE:
    case MCI_COPY:
    case MCI_CUT:
    case MCI_DELETE:
    case MCI_PASTE:
	FIXME("Unsupported yet command [%u]\n", wMsg);
	break;
    case MCI_WINDOW:
	TRACE("Unsupported command [%u]\n", wMsg);
	break;
	/* option which can be silenced */
    case MCI_CONFIGURE:
	return 0;
    case MCI_OPEN:
    case MCI_CLOSE:
	ERR("Shouldn't receive a MCI_OPEN or CLOSE message\n");
	break;
    default:
	FIXME("is probably wrong msg [%u]\n", wMsg);
	return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
    }
    return MCIERR_UNRECOGNIZED_COMMAND;
}
