/*
 * Copyright 1993      Martin Ayotte
 *           1998-2002 Eric Pouech
 *           2011 Andrew Eikum for CodeWeavers
 *
 * 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 <stdio.h>
#include <stdarg.h>
#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "mmsystem.h"
#include "mmreg.h"
#include "msacm.h"
#include "winuser.h"
#include "winnls.h"
#include "winternl.h"

#include "winemm.h"
#include "resource.h"

#include "ole2.h"
#include "initguid.h"
#include "devpkey.h"
#include "mmdeviceapi.h"
#include "audioclient.h"
#include "audiopolicy.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winmm);

/* HWAVE (and HMIXER) format:
 *
 * XXXX... 1FDD DDDD IIII IIII
 * X = unused (must be 0)
 * 1 = the bit is set to 1, to avoid all-zero HWAVEs
 * F = flow direction (0 = IN, 1 = OUT)
 * D = index into g_out_mmdevices, or all 1s for the MAPPER device
 * I = index in the mmdevice's devices array
 *
 * Two reasons that we don't just use pointers:
 *   - HWAVEs must fit into 16 bits for compatibility with old applications.
 *   - We must be able to identify bad devices without crashing.
 */

/* buffer size = 10 * 100000 (100 ns) = 0.1 seconds */
#define AC_BUFLEN (10 * 100000)
#define MAX_DEVICES 256
#define MAPPER_INDEX 0x3F

typedef struct _WINMM_CBInfo {
    DWORD_PTR callback;
    DWORD_PTR user;
    DWORD flags;
    HWAVE hwave;
} WINMM_CBInfo;

struct _WINMM_MMDevice;
typedef struct _WINMM_MMDevice WINMM_MMDevice;

typedef struct _WINMM_Device {
    WINMM_CBInfo cb_info;

    HWAVE handle;

    BOOL open;

    IMMDevice *device;
    IAudioClient *client;
    IAudioRenderClient *render;
    IAudioCaptureClient *capture;
    IAudioClock *clock;
    IAudioStreamVolume *volume;

    WAVEFORMATEX *orig_fmt;
    HACMSTREAM acm_handle;
    ACMSTREAMHEADER acm_hdr;
    UINT32 acm_offs;

    WAVEHDR *first, *last, *playing, *loop_start;

    BOOL stopped;
    DWORD loop_counter;
    UINT32 bytes_per_frame, samples_per_sec, ofs_bytes, played_frames;
    UINT32 remainder_frames; /* header chunk frames already played when a device switch occurred */

    /* stored in frames of sample rate, *not* AC::GetFrequency */
    UINT64 last_clock_pos;

    HANDLE event;
    CRITICAL_SECTION lock;

    WINMM_MMDevice *parent;
} WINMM_Device;

struct _WINMM_MMDevice {
    WAVEOUTCAPSW out_caps; /* must not be modified outside of WINMM_InitMMDevices*/
    WAVEINCAPSW in_caps; /* must not be modified outside of WINMM_InitMMDevices*/
    WCHAR *dev_id;
    EDataFlow dataflow;

    ISimpleAudioVolume *volume;

    GUID session;

    UINT index;

    /* HMIXER format is the same as the HWAVE format, but the I bits are
     * replaced by the value of this counter, to keep each HMIXER unique */
    UINT mixer_count;

    CRITICAL_SECTION lock;

    WINMM_Device *devices[MAX_DEVICES];
};

static WINMM_MMDevice *g_out_mmdevices;
static WINMM_MMDevice **g_out_map;
static UINT g_outmmdevices_count;
static WINMM_Device *g_out_mapper_devices[MAX_DEVICES];

static WINMM_MMDevice *g_in_mmdevices;
static WINMM_MMDevice **g_in_map;
static UINT g_inmmdevices_count;
static WINMM_Device *g_in_mapper_devices[MAX_DEVICES];

static IMMDeviceEnumerator *g_devenum;

static CRITICAL_SECTION g_devthread_lock;
static CRITICAL_SECTION_DEBUG g_devthread_lock_debug =
{
    0, 0, &g_devthread_lock,
    { &g_devthread_lock_debug.ProcessLocksList, &g_devthread_lock_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": g_devthread_lock") }
};
static CRITICAL_SECTION g_devthread_lock = { &g_devthread_lock_debug, -1, 0, 0, 0, 0 };
static LONG g_devthread_token;
static HANDLE g_devices_thread;
static HWND g_devices_hwnd;
static HMODULE g_devthread_module;

static UINT g_devhandle_count;
static HANDLE *g_device_handles;
static WINMM_Device **g_handle_devices;

typedef struct _WINMM_OpenInfo {
    HWAVE handle;
    UINT req_device;
    WAVEFORMATEX *format;
    DWORD_PTR callback;
    DWORD_PTR cb_user;
    DWORD flags;
    BOOL reset;
} WINMM_OpenInfo;

typedef struct _WINMM_ControlDetails {
    HMIXEROBJ hmix;
    MIXERCONTROLDETAILS *details;
    DWORD flags;
} WINMM_ControlDetails;

typedef struct _WINMM_QueryInterfaceInfo {
    BOOL is_out;
    UINT index;
    WCHAR *str;
    UINT *len_bytes;
} WINMM_QueryInterfaceInfo;

static LRESULT WOD_Open(WINMM_OpenInfo *info);
static LRESULT WOD_Close(HWAVEOUT hwave);
static LRESULT WID_Open(WINMM_OpenInfo *info);
static LRESULT WID_Close(HWAVEIN hwave);
static MMRESULT WINMM_BeginPlaying(WINMM_Device *device);

void WINMM_DeleteWaveform(void)
{
    UINT i, j;

    if(g_devices_thread)
        CloseHandle(g_devices_thread);

    for(i = 0; i < g_outmmdevices_count; ++i){
        WINMM_MMDevice *mmdevice = &g_out_mmdevices[i];

        for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){
            WINMM_Device *device = mmdevice->devices[j];
            if(device->handle)
                CloseHandle(device->handle);
            DeleteCriticalSection(&device->lock);
        }

        if(mmdevice->volume)
            ISimpleAudioVolume_Release(mmdevice->volume);
        CoTaskMemFree(mmdevice->dev_id);
        DeleteCriticalSection(&mmdevice->lock);
    }

    for(i = 0; i < g_inmmdevices_count; ++i){
        WINMM_MMDevice *mmdevice = &g_in_mmdevices[i];

        for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){
            WINMM_Device *device = mmdevice->devices[j];
            if(device->handle)
                CloseHandle(device->handle);
            DeleteCriticalSection(&device->lock);
        }

        if(mmdevice->volume)
            ISimpleAudioVolume_Release(mmdevice->volume);
        CoTaskMemFree(mmdevice->dev_id);
        DeleteCriticalSection(&mmdevice->lock);
    }

    HeapFree(GetProcessHeap(), 0, g_out_mmdevices);
    HeapFree(GetProcessHeap(), 0, g_in_mmdevices);

    HeapFree(GetProcessHeap(), 0, g_device_handles);
    HeapFree(GetProcessHeap(), 0, g_handle_devices);

    DeleteCriticalSection(&g_devthread_lock);
}

static inline HWAVE WINMM_MakeHWAVE(UINT mmdevice, BOOL is_out, UINT device)
{
    return ULongToHandle((1 << 15) | ((!!is_out) << 14) |
            (mmdevice << 8) | device);
}

static inline void WINMM_DecomposeHWAVE(HWAVE hwave, UINT *mmdevice_index,
        BOOL *is_out, UINT *device_index, UINT *junk)
{
    ULONG32 l = HandleToULong(hwave);
    *device_index = l & 0xFF;
    *mmdevice_index = (l >> 8) & 0x3F;
    *is_out = (l >> 14) & 0x1;
    *junk = l >> 15;
}

static void WINMM_InitDevice(WINMM_Device *device)
{
    InitializeCriticalSection(&device->lock);
    device->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": WINMM_Device.lock");
}

static inline WINMM_MMDevice *read_map(WINMM_MMDevice **map, UINT index)
{
    WINMM_MMDevice *ret;
    EnterCriticalSection(&g_devthread_lock);
    ret = map[index];
    LeaveCriticalSection(&g_devthread_lock);
    return ret;
}

/* finds the first unused Device, marks it as "open", and returns
 * a pointer to the device
 *
 * IMPORTANT: it is the caller's responsibility to release the device's lock
 * on success
 */
static WINMM_Device *WINMM_FindUnusedDevice(WINMM_Device **devices,
        WINMM_MMDevice *parent, UINT internal_index, BOOL is_out)
{
    UINT i;

    for(i = 0; i < MAX_DEVICES; ++i){
        WINMM_Device *device = devices[i];

        if(!device){
            device = devices[i] = HeapAlloc(GetProcessHeap(),
                    HEAP_ZERO_MEMORY, sizeof(WINMM_Device));
            if(!device)
                return NULL;

            WINMM_InitDevice(device);
            EnterCriticalSection(&device->lock);
        }else
            EnterCriticalSection(&device->lock);

        if(!device->open){
            device->handle = WINMM_MakeHWAVE(internal_index, is_out, i);
            device->parent = parent;
            device->open = TRUE;

            return device;
        }

        LeaveCriticalSection(&device->lock);
    }

    TRACE("All devices in use: mmdevice: %u\n", internal_index);

    return NULL;
}

static inline BOOL WINMM_ValidateAndLock(WINMM_Device *device)
{
    if(!device)
        return FALSE;

    EnterCriticalSection(&device->lock);

    if(!device->open){
        LeaveCriticalSection(&device->lock);
        return FALSE;
    }

    return TRUE;
}

static WINMM_Device *WINMM_GetDeviceFromHWAVE(HWAVE hwave)
{
    WINMM_MMDevice *mmdevice;
    WINMM_Device *device;
    UINT mmdevice_index, device_index, junk;
    BOOL is_out;

    WINMM_DecomposeHWAVE(hwave, &mmdevice_index, &is_out, &device_index, &junk);

    if(junk != 0x1)
        return NULL;

    if(mmdevice_index == MAPPER_INDEX){
        EnterCriticalSection(&g_devthread_lock);
        if(is_out)
            device = g_out_mapper_devices[device_index];
        else
            device = g_in_mapper_devices[device_index];
        LeaveCriticalSection(&g_devthread_lock);
        return device;
    }

    if(mmdevice_index >= (is_out ? g_outmmdevices_count : g_inmmdevices_count))
        return NULL;

    if(is_out)
        mmdevice = &g_out_mmdevices[mmdevice_index];
    else
        mmdevice = &g_in_mmdevices[mmdevice_index];

    EnterCriticalSection(&mmdevice->lock);

    device = mmdevice->devices[device_index];

    LeaveCriticalSection(&mmdevice->lock);

    return device;
}

/* Note: NotifyClient should never be called while holding the device lock
 * since the client may call wave* functions from within the callback. */
static inline void WINMM_NotifyClient(WINMM_CBInfo *info, WORD msg, DWORD_PTR param1,
        DWORD_PTR param2)
{
    DriverCallback(info->callback, info->flags, (HDRVR)info->hwave,
        msg, info->user, param1, param2);
}

static MMRESULT hr2mmr(HRESULT hr)
{
    switch(hr){
    case S_OK:
    case AUDCLNT_E_NOT_STOPPED:
        return MMSYSERR_NOERROR;
    case AUDCLNT_E_UNSUPPORTED_FORMAT:
        return WAVERR_BADFORMAT;
    case AUDCLNT_E_DEVICE_IN_USE:
        return MMSYSERR_ALLOCATED;
    case AUDCLNT_E_ENDPOINT_CREATE_FAILED:
        return MMSYSERR_NOTENABLED;
    case E_OUTOFMEMORY:
        return MMSYSERR_NOMEM;
    case E_POINTER:
    case E_INVALIDARG:
        return MMSYSERR_INVALPARAM;
    case AUDCLNT_E_DEVICE_INVALIDATED: /* DSERR_BUFFERLOST */
    default:
        return FAILED(hr) ? MMSYSERR_ERROR : MMSYSERR_NOERROR;
    }
}

static HRESULT WINMM_GetFriendlyName(IMMDevice *device, WCHAR *out,
        UINT outlen)
{
    IPropertyStore *ps;
    PROPVARIANT var;
    HRESULT hr;

    hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps);
    if(FAILED(hr))
        return hr;

    PropVariantInit(&var);

    hr = IPropertyStore_GetValue(ps,
            (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var);
    if(FAILED(hr)){
        IPropertyStore_Release(ps);
        return hr;
    }

    lstrcpynW(out, var.u.pwszVal, outlen);

    PropVariantClear(&var);

    IPropertyStore_Release(ps);

    return S_OK;
}

static HRESULT WINMM_TestFormat(IAudioClient *client, DWORD rate, DWORD depth,
        WORD channels)
{
    WAVEFORMATEX fmt, *junk;
    HRESULT hr;

    fmt.wFormatTag = WAVE_FORMAT_PCM;
    fmt.nChannels = channels;
    fmt.nSamplesPerSec = rate;
    fmt.wBitsPerSample = depth;
    fmt.nBlockAlign = (channels * depth) / 8;
    fmt.nAvgBytesPerSec = rate * fmt.nBlockAlign;
    fmt.cbSize = 0;

    hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED,
            &fmt, &junk);
    if(SUCCEEDED(hr))
        CoTaskMemFree(junk);

    return hr;
}

static struct _TestFormat {
    DWORD flag;
    DWORD rate;
    DWORD depth;
    WORD channels;
} formats_to_test[] = {
    { WAVE_FORMAT_1M08, 11025, 8, 1 },
    { WAVE_FORMAT_1M16, 11025, 16, 1 },
    { WAVE_FORMAT_1S08, 11025, 8, 2 },
    { WAVE_FORMAT_1S16, 11025, 16, 2 },
    { WAVE_FORMAT_2M08, 22050, 8, 1 },
    { WAVE_FORMAT_2M16, 22050, 16, 1 },
    { WAVE_FORMAT_2S08, 22050, 8, 2 },
    { WAVE_FORMAT_2S16, 22050, 16, 2 },
    { WAVE_FORMAT_4M08, 44100, 8, 1 },
    { WAVE_FORMAT_4M16, 44100, 16, 1 },
    { WAVE_FORMAT_4S08, 44100, 8, 2 },
    { WAVE_FORMAT_4S16, 44100, 16, 2 },
    { WAVE_FORMAT_48M08, 48000, 8, 1 },
    { WAVE_FORMAT_48M16, 48000, 16, 1 },
    { WAVE_FORMAT_48S08, 48000, 8, 2 },
    { WAVE_FORMAT_48S16, 48000, 16, 2 },
    { WAVE_FORMAT_96M08, 96000, 8, 1 },
    { WAVE_FORMAT_96M16, 96000, 16, 1 },
    { WAVE_FORMAT_96S08, 96000, 8, 2 },
    { WAVE_FORMAT_96S16, 96000, 16, 2 },
    {0}
};

static DWORD WINMM_GetSupportedFormats(IMMDevice *device)
{
    DWORD flags = 0;
    HRESULT hr;
    struct _TestFormat *fmt;
    IAudioClient *client;

    hr = IMMDevice_Activate(device, &IID_IAudioClient,
            CLSCTX_INPROC_SERVER, NULL, (void**)&client);
    if(FAILED(hr))
        return 0;

    for(fmt = formats_to_test; fmt->flag; ++fmt){
        hr = WINMM_TestFormat(client, fmt->rate, fmt->depth, fmt->channels);
        if(hr == S_OK)
            flags |= fmt->flag;
    }

    IAudioClient_Release(client);

    return flags;
}

static HRESULT WINMM_InitMMDevice(EDataFlow flow, IMMDevice *device,
        WINMM_MMDevice *dev, UINT index)
{
    HRESULT hr;

    dev->dataflow = flow;
    if(flow == eRender){
        dev->out_caps.wMid = 0xFF;
        dev->out_caps.wPid = 0xFF;
        dev->out_caps.vDriverVersion = 0x00010001;
        dev->out_caps.dwFormats = WINMM_GetSupportedFormats(device);
        dev->out_caps.wReserved1 = 0;
        dev->out_caps.dwSupport = WAVECAPS_LRVOLUME | WAVECAPS_VOLUME |
            WAVECAPS_SAMPLEACCURATE;
        dev->out_caps.wChannels = 2;
        dev->out_caps.szPname[0] = '\0';

        hr = WINMM_GetFriendlyName(device, dev->out_caps.szPname,
                sizeof(dev->out_caps.szPname) /
                sizeof(*dev->out_caps.szPname));
        if(FAILED(hr))
            return hr;
    }else{
        dev->in_caps.wMid = 0xFF;
        dev->in_caps.wPid = 0xFF;
        dev->in_caps.vDriverVersion = 0x00010001;
        dev->in_caps.dwFormats = WINMM_GetSupportedFormats(device);
        dev->in_caps.wReserved1 = 0;
        dev->in_caps.wChannels = 2;
        dev->in_caps.szPname[0] = '\0';

        hr = WINMM_GetFriendlyName(device, dev->in_caps.szPname,
                sizeof(dev->in_caps.szPname) /
                sizeof(*dev->in_caps.szPname));
        if(FAILED(hr))
            return hr;
    }

    hr = IMMDevice_GetId(device, &dev->dev_id);
    if(FAILED(hr))
        return hr;

    CoCreateGuid(&dev->session);

    dev->index = index;

    InitializeCriticalSection(&dev->lock);
    dev->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": WINMM_Device.lock");

    return S_OK;
}

static HRESULT WINMM_EnumDevices(WINMM_MMDevice **devices,
        WINMM_MMDevice ***map, UINT *devcount, EDataFlow flow,
        IMMDeviceEnumerator *devenum)
{
    IMMDeviceCollection *devcoll;
    HRESULT hr;

    hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
            DEVICE_STATE_ACTIVE, &devcoll);
    if(FAILED(hr))
        return hr;

    hr = IMMDeviceCollection_GetCount(devcoll, devcount);
    if(FAILED(hr)){
        IMMDeviceCollection_Release(devcoll);
        return hr;
    }

    if(*devcount > 0){
        UINT n, count = 1;
        IMMDevice *def_dev = NULL;

        *devices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                sizeof(WINMM_MMDevice) * (*devcount));
        if(!*devices){
            IMMDeviceCollection_Release(devcoll);
            return E_OUTOFMEMORY;
        }

        *map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                sizeof(WINMM_MMDevice *) * (*devcount));
        if(!*map){
            IMMDeviceCollection_Release(devcoll);
            HeapFree(GetProcessHeap(), 0, *devices);
            return E_OUTOFMEMORY;
        }

        /* make sure that device 0 is the default device */
        IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum,
                flow, eConsole, &def_dev);

        for(n = 0; n < *devcount; ++n){
            IMMDevice *device;

            hr = IMMDeviceCollection_Item(devcoll, n, &device);
            if(SUCCEEDED(hr)){
                WINMM_InitMMDevice(flow, device, &(*devices)[n], n);

                if(device == def_dev)
                    (*map)[0] = &(*devices)[n];
                else{
                    (*map)[count] = &(*devices)[n];
                    ++count;
                }

                IMMDevice_Release(device);
            }
        }

        IMMDevice_Release(def_dev);

        *devcount = count;
    }

    IMMDeviceCollection_Release(devcoll);

    return S_OK;
}

static HRESULT WINAPI notif_QueryInterface(IMMNotificationClient *iface,
        const GUID *riid, void **obj)
{
    ERR("Unexpected QueryInterface call: %s\n", wine_dbgstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI notif_AddRef(IMMNotificationClient *iface)
{
    return 2;
}

static ULONG WINAPI notif_Release(IMMNotificationClient *iface)
{
    return 1;
}

static HRESULT WINAPI notif_OnDeviceStateChanged(IMMNotificationClient *iface,
        const WCHAR *device_id, DWORD new_state)
{
    TRACE("Ignoring OnDeviceStateChanged callback\n");
    return S_OK;
}

static HRESULT WINAPI notif_OnDeviceAdded(IMMNotificationClient *iface,
        const WCHAR *device_id)
{
    TRACE("Ignoring OnDeviceAdded callback\n");
    return S_OK;
}

static HRESULT WINAPI notif_OnDeviceRemoved(IMMNotificationClient *iface,
        const WCHAR *device_id)
{
    TRACE("Ignoring OnDeviceRemoved callback\n");
    return S_OK;
}

static HRESULT update_mapping(WINMM_MMDevice ***map, UINT count,
        const WCHAR *default_id)
{
    WINMM_MMDevice *prev;
    UINT i;

    prev = (*map)[0];
    for(i = 0; i < count; ++i){
        WINMM_MMDevice *tmp;

        if(!lstrcmpW((*map)[i]->dev_id, default_id)){
            (*map)[0] = (*map)[i];
            (*map)[i] = prev;

            return S_OK;
        }

        tmp = (*map)[i];
        (*map)[i] = prev;
        prev = tmp;
    }

    WARN("Couldn't find new default device! Rearranged map for no reason.\n");
    (*map)[0] = prev;

    return S_FALSE;
}

static HRESULT reroute_mapper_device(WINMM_Device *device, BOOL is_out)
{
    WINMM_OpenInfo info;
    BOOL stopped;
    MMRESULT mr;
    HRESULT hr;
    UINT64 clock_freq, clock_pos;

    TRACE("rerouting device %p\n", device->handle);

    EnterCriticalSection(&device->lock);

    if(!device->open || device->acm_handle){
        /* Windows 7 doesn't re-route ACM devices, so we don't either.
         * Seems to be because of the data waveXxxPrepareHeader allocates. */
        LeaveCriticalSection(&device->lock);
        return S_FALSE;
    }

    stopped = device->stopped;

    info.handle = 0;
    info.req_device = WAVE_MAPPER;
    info.format = device->orig_fmt;
    info.callback = device->cb_info.callback;
    info.cb_user = device->cb_info.user;
    /* We have to use direct here so that we don't suddenly introduce ACM
     * into a playing stream that hasn't been Prepared for it */
    info.flags = (device->cb_info.flags << 16) | WAVE_FORMAT_DIRECT_QUERY;
    info.reset = FALSE;

    if(is_out)
        mr = WOD_Open(&info);
    else
        mr = WID_Open(&info);

    if(mr != MMSYSERR_NOERROR){
        TRACE("New default device doesn't support this stream: %p\n", device->handle);
        LeaveCriticalSection(&device->lock);
        return S_FALSE;
    }

    hr = IAudioClient_Stop(device->client);
    if(FAILED(hr))
        WARN("Stop failed: %08x\n", hr);

    hr = IAudioClock_GetFrequency(device->clock, &clock_freq);
    if(FAILED(hr)){
        WARN("GetFrequency failed: %08x\n", hr);
        LeaveCriticalSection(&device->lock);
        return hr;
    }

    hr = IAudioClock_GetPosition(device->clock, &clock_pos, NULL);
    if(FAILED(hr)){
        WARN("GetPosition failed: %08x\n", hr);
        LeaveCriticalSection(&device->lock);
        return hr;
    }

    device->remainder_frames = MulDiv(clock_pos, device->samples_per_sec, clock_freq) - device->last_clock_pos;

    info.handle = device->handle;
    info.flags = (device->cb_info.flags << 16) | WAVE_FORMAT_DIRECT;

    if(is_out){
        WOD_Close((HWAVEOUT)device->handle);
        device->parent = read_map(g_out_map, 0);
        mr = WOD_Open(&info);
    }else{
        WID_Close((HWAVEIN)device->handle);
        device->parent = read_map(g_in_map, 0);
        mr = WID_Open(&info);
    }

    if(mr != MMSYSERR_NOERROR){
        ERR("Opening new default device failed! %u\n", mr);
        LeaveCriticalSection(&device->lock);
        return E_FAIL;
    }

    HeapFree(GetProcessHeap(), 0, info.format);

    if(!stopped)
        WINMM_BeginPlaying(device);

    LeaveCriticalSection(&device->lock);

    return S_OK;
}

static HRESULT WINAPI notif_OnDefaultDeviceChanged(IMMNotificationClient *iface,
        EDataFlow flow, ERole role, const WCHAR *device_id)
{
    UINT i;

    TRACE("%u %u %s\n", flow, role, wine_dbgstr_w(device_id));

    if(role != eConsole)
        return S_OK;

    EnterCriticalSection(&g_devthread_lock);

    if(flow == eRender)
        update_mapping(&g_out_map, g_outmmdevices_count, device_id);
    else
        update_mapping(&g_in_map, g_inmmdevices_count, device_id);

    for(i = 0; i < MAX_DEVICES && g_out_mapper_devices[i]; ++i)
        reroute_mapper_device(g_out_mapper_devices[i], TRUE);

    for(i = 0; i < MAX_DEVICES && g_in_mapper_devices[i]; ++i)
        reroute_mapper_device(g_in_mapper_devices[i], FALSE);

    LeaveCriticalSection(&g_devthread_lock);

    return S_OK;
}

static HRESULT WINAPI notif_OnPropertyValueChanged(IMMNotificationClient *iface,
        const WCHAR *device_id, const PROPERTYKEY key)
{
    TRACE("Ignoring OnPropertyValueChanged callback\n");
    return S_OK;
}

static IMMNotificationClientVtbl g_notif_vtbl = {
    notif_QueryInterface,
    notif_AddRef,
    notif_Release,
    notif_OnDeviceStateChanged,
    notif_OnDeviceAdded,
    notif_OnDeviceRemoved,
    notif_OnDefaultDeviceChanged,
    notif_OnPropertyValueChanged
};

static IMMNotificationClient g_notif = { &g_notif_vtbl };

static HRESULT WINMM_InitMMDevices(void)
{
    HRESULT hr, init_hr;
    IMMDeviceEnumerator *devenum = NULL;

    if(g_outmmdevices_count || g_inmmdevices_count)
        return S_FALSE;

    init_hr = CoInitialize(NULL);

    hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
            CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&devenum);
    if(FAILED(hr))
        goto exit;

    hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(devenum, &g_notif);
    if(FAILED(hr))
        WARN("RegisterEndpointNotificationCallback failed: %08x\n", hr);

    hr = WINMM_EnumDevices(&g_out_mmdevices, &g_out_map, &g_outmmdevices_count,
            eRender, devenum);
    if(FAILED(hr)){
        g_outmmdevices_count = 0;
        g_inmmdevices_count = 0;
        goto exit;
    }

    hr = WINMM_EnumDevices(&g_in_mmdevices, &g_in_map, &g_inmmdevices_count,
            eCapture, devenum);
    if(FAILED(hr)){
        g_inmmdevices_count = 0;
        goto exit;
    }

exit:
    if(devenum)
        IMMDeviceEnumerator_Release(devenum);
    if(SUCCEEDED(init_hr))
        CoUninitialize();

    return hr;
}

static inline BOOL WINMM_IsMapper(UINT device)
{
    return (device == WAVE_MAPPER || device == (UINT16)WAVE_MAPPER);
}

static MMRESULT WINMM_TryDeviceMapping(WINMM_Device *device, WAVEFORMATEX *fmt,
        WORD channels, DWORD freq, DWORD bits_per_samp, BOOL is_query, BOOL is_out)
{
    WAVEFORMATEX target, *closer_fmt = NULL;
    HRESULT hr;
    MMRESULT mr;

    TRACE("format: %u, channels: %u, sample rate: %u, bit depth: %u\n",
            WAVE_FORMAT_PCM, channels, freq, bits_per_samp);

    target.wFormatTag = WAVE_FORMAT_PCM;
    target.nChannels = channels;
    target.nSamplesPerSec = freq;
    target.wBitsPerSample = bits_per_samp;
    target.nBlockAlign = (target.nChannels * target.wBitsPerSample) / 8;
    target.nAvgBytesPerSec = target.nSamplesPerSec * target.nBlockAlign;
    target.cbSize = 0;

    hr = IAudioClient_IsFormatSupported(device->client,
            AUDCLNT_SHAREMODE_SHARED, &target, &closer_fmt);
    if(closer_fmt)
        CoTaskMemFree(closer_fmt);
    if(hr != S_OK)
        return WAVERR_BADFORMAT;

    /* device supports our target format, so see if MSACM can
     * do the conversion */
    if(is_out)
        mr = acmStreamOpen(&device->acm_handle, NULL, fmt, &target, NULL,
                0, 0, 0);
    else
        mr = acmStreamOpen(&device->acm_handle, NULL, &target, fmt, NULL,
                0, 0, 0);
    if(mr != MMSYSERR_NOERROR)
        return mr;

    /* yes it can. initialize the audioclient and return success */
    if(is_query){
        acmStreamClose(device->acm_handle, 0);
        device->acm_handle = NULL;
        return MMSYSERR_NOERROR;
    }

    hr = IAudioClient_Initialize(device->client, AUDCLNT_SHAREMODE_SHARED,
            AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
            AC_BUFLEN, 0, &target, &device->parent->session);
    if(hr != S_OK){
        WARN("Initialize failed: %08x\n", hr);
        acmStreamClose(device->acm_handle, 0);
        device->acm_handle = NULL;
        return MMSYSERR_ERROR;
    }

    device->bytes_per_frame = target.nBlockAlign;
    device->samples_per_sec = target.nSamplesPerSec;

    TRACE("Success!\n");

    return MMSYSERR_NOERROR;
}

static MMRESULT WINMM_MapDevice(WINMM_Device *device, BOOL is_query, BOOL is_out)
{
    MMRESULT mr;
    WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)device->orig_fmt;

    TRACE("(%p, %u)\n", device, is_out);

    /* set up the ACM stream */
    if(device->orig_fmt->wFormatTag != WAVE_FORMAT_PCM &&
            !(device->orig_fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
              IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))){
        /* convert to PCM format if it's not already */
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt,
                device->orig_fmt->nChannels, device->orig_fmt->nSamplesPerSec,
                16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;

        mr = WINMM_TryDeviceMapping(device, device->orig_fmt,
                device->orig_fmt->nChannels, device->orig_fmt->nSamplesPerSec,
                8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
    }else{
        WORD channels;

        /* first try just changing bit depth and channels */
        channels = device->orig_fmt->nChannels;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels,
                device->orig_fmt->nSamplesPerSec, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels,
                device->orig_fmt->nSamplesPerSec, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;

        channels = (channels == 2) ? 1 : 2;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels,
                device->orig_fmt->nSamplesPerSec, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels,
                device->orig_fmt->nSamplesPerSec, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;

        /* that didn't work, so now try different sample rates */
        channels = device->orig_fmt->nChannels;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;

        channels = (channels == 2) ? 1 : 2;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 16, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;

        channels = device->orig_fmt->nChannels;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;

        channels = (channels == 2) ? 1 : 2;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
        mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 8, is_query, is_out);
        if(mr == MMSYSERR_NOERROR)
            return mr;
    }

    WARN("Unable to find compatible device!\n");
    return WAVERR_BADFORMAT;
}

static LRESULT WINMM_OpenDevice(WINMM_Device *device, WINMM_OpenInfo *info,
        BOOL is_out)
{
    LRESULT ret = MMSYSERR_NOMEM;
    HRESULT hr;

    hr = IMMDeviceEnumerator_GetDevice(g_devenum, device->parent->dev_id,
            &device->device);
    if(FAILED(hr)){
        WARN("Device %s (%s) unavailable: %08x\n",
                wine_dbgstr_w(device->parent->dev_id),
                wine_dbgstr_w(device->parent->out_caps.szPname), hr);
        ret = MMSYSERR_NODRIVER;
        goto error;
    }

    /* this is where winexyz.drv opens the audio device */
    hr = IMMDevice_Activate(device->device, &IID_IAudioClient,
            CLSCTX_INPROC_SERVER, NULL, (void**)&device->client);
    if(FAILED(hr)){
        WARN("Activate failed: %08x\n", hr);
        ret = hr2mmr(hr);
        if(ret == MMSYSERR_ERROR)
            ret = MMSYSERR_NOTENABLED;
        goto error;
    }

    if(info->format->wFormatTag == WAVE_FORMAT_PCM){
        /* we aren't guaranteed that the struct in lpFormat is a full
         * WAVEFORMATEX struct, which IAC::IsFormatSupported requires */
        device->orig_fmt = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEFORMATEX));
        memcpy(device->orig_fmt, info->format, sizeof(PCMWAVEFORMAT));
        device->orig_fmt->cbSize = 0;
        if(device->orig_fmt->wBitsPerSample % 8 != 0){
            WARN("Fixing bad wBitsPerSample (%u)\n", device->orig_fmt->wBitsPerSample);
            device->orig_fmt->wBitsPerSample = (device->orig_fmt->wBitsPerSample + 7) & ~7;
        }
        /* winmm ignores broken blockalign and avgbytes */
        if(device->orig_fmt->nBlockAlign != device->orig_fmt->nChannels * device->orig_fmt->wBitsPerSample/8){
            WARN("Fixing bad nBlockAlign (%u)\n", device->orig_fmt->nBlockAlign);
            device->orig_fmt->nBlockAlign  = device->orig_fmt->nChannels * device->orig_fmt->wBitsPerSample/8;
        }
        if (device->orig_fmt->nAvgBytesPerSec != device->orig_fmt->nSamplesPerSec * device->orig_fmt->nBlockAlign) {
            WARN("Fixing bad nAvgBytesPerSec (%u)\n", device->orig_fmt->nAvgBytesPerSec);
            device->orig_fmt->nAvgBytesPerSec  = device->orig_fmt->nSamplesPerSec * device->orig_fmt->nBlockAlign;
        }
    }else{
        device->orig_fmt = HeapAlloc(GetProcessHeap(), 0,
                sizeof(WAVEFORMATEX) + info->format->cbSize);
        memcpy(device->orig_fmt, info->format,
                sizeof(WAVEFORMATEX) + info->format->cbSize);
    }

    if(info->flags & WAVE_FORMAT_QUERY){
        WAVEFORMATEX *closer_fmt = NULL;

        hr = IAudioClient_IsFormatSupported(device->client,
                AUDCLNT_SHAREMODE_SHARED, device->orig_fmt, &closer_fmt);
        if(closer_fmt)
            CoTaskMemFree(closer_fmt);
        if((hr == S_FALSE || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !(info->flags & WAVE_FORMAT_DIRECT))
            ret = WINMM_MapDevice(device, TRUE, is_out);
        else
            ret = hr == S_FALSE ? WAVERR_BADFORMAT : hr2mmr(hr);
        goto error;
    }

    hr = IAudioClient_Initialize(device->client, AUDCLNT_SHAREMODE_SHARED,
            AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
            AC_BUFLEN, 0, device->orig_fmt, &device->parent->session);
    if(FAILED(hr)){
        if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && !(info->flags & WAVE_FORMAT_DIRECT)){
            ret = WINMM_MapDevice(device, FALSE, is_out);
            if(ret != MMSYSERR_NOERROR || info->flags & WAVE_FORMAT_QUERY)
                goto error;
        }else{
            WARN("Initialize failed: %08x\n", hr);
            ret = hr2mmr(hr);
            goto error;
        }
    }else{
        device->bytes_per_frame = device->orig_fmt->nBlockAlign;
        device->samples_per_sec = device->orig_fmt->nSamplesPerSec;
    }

    hr = IAudioClient_GetService(device->client, &IID_IAudioClock,
            (void**)&device->clock);
    if(FAILED(hr)){
        WARN("GetService failed: %08x\n", hr);
        goto error;
    }

    if(!device->event){
        device->event = CreateEventW(NULL, FALSE, FALSE, NULL);
        if(!device->event){
            WARN("CreateEvent failed: %08x\n", hr);
            goto error;
        }

        /* As the devices thread is waiting on g_device_handles, it can
         * only be modified from within this same thread. */
        if(g_device_handles){
            g_device_handles = HeapReAlloc(GetProcessHeap(), 0, g_device_handles,
                    sizeof(HANDLE) * (g_devhandle_count + 1));
            g_handle_devices = HeapReAlloc(GetProcessHeap(), 0, g_handle_devices,
                    sizeof(WINMM_Device *) * (g_devhandle_count + 1));
        }else{
            g_device_handles = HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLE));
            g_handle_devices = HeapAlloc(GetProcessHeap(), 0,
                    sizeof(WINMM_Device *));
        }
        g_device_handles[g_devhandle_count] = device->event;
        g_handle_devices[g_devhandle_count] = device;
        ++g_devhandle_count;
    }

    hr = IAudioClient_SetEventHandle(device->client, device->event);
    if(FAILED(hr)){
        WARN("SetEventHandle failed: %08x\n", hr);
        goto error;
    }

    if(info->reset){
        device->played_frames = 0;
        device->ofs_bytes = 0;
        device->loop_counter = 0;
        device->first = device->last = device->playing = device->loop_start = NULL;
    }

    device->stopped = TRUE;
    device->last_clock_pos = 0;

    device->cb_info.flags = HIWORD(info->flags & CALLBACK_TYPEMASK);
    device->cb_info.callback = info->callback;
    device->cb_info.user = info->cb_user;
    device->cb_info.hwave = device->handle;

    info->handle = device->handle;

    return MMSYSERR_NOERROR;

error:
    if(device->client){
        IAudioClient_Release(device->client);
        device->client = NULL;
    }
    if(device->device){
        IMMDevice_Release(device->device);
        device->device = NULL;
    }

    return ret;
}

static LRESULT WOD_Open(WINMM_OpenInfo *info)
{
    WINMM_Device *device;
    LRESULT ret = MMSYSERR_ERROR;
    HRESULT hr;

    if(info->handle != 0){
        device = WINMM_GetDeviceFromHWAVE(info->handle);
        if(!device){
            WARN("Unexpected! Invalid info->handle given: %p\n", info->handle);
            return MMSYSERR_ERROR;
        }

        EnterCriticalSection(&device->lock);

        device->open = TRUE;
    }else{
        CRITICAL_SECTION *lock;
        UINT internal_index;
        WINMM_Device **devices;
        WINMM_MMDevice *mmdevice;

        if(WINMM_IsMapper(info->req_device)){
            if (g_outmmdevices_count == 0)
                return MMSYSERR_BADDEVICEID;
            devices = g_out_mapper_devices;
            mmdevice = read_map(g_out_map, 0);
            lock = &g_devthread_lock;
            internal_index = MAPPER_INDEX;
        }else{
            if(info->req_device >= g_outmmdevices_count)
                return MMSYSERR_BADDEVICEID;

            mmdevice = read_map(g_out_map, info->req_device);

            if(!mmdevice->out_caps.szPname[0])
                return MMSYSERR_NOTENABLED;

            devices = mmdevice->devices;
            lock = &mmdevice->lock;
            internal_index = mmdevice->index;
        }

        EnterCriticalSection(lock);

        device = WINMM_FindUnusedDevice(devices, mmdevice,
                internal_index, TRUE);
        if(!device){
            LeaveCriticalSection(lock);
            return MMSYSERR_ALLOCATED;
        }

        LeaveCriticalSection(lock);
    }

    ret = WINMM_OpenDevice(device, info, TRUE);
    if((info->flags & WAVE_FORMAT_QUERY) || ret != MMSYSERR_NOERROR)
        goto error;
    ret = MMSYSERR_ERROR;

    hr = IAudioClient_GetService(device->client, &IID_IAudioRenderClient,
            (void**)&device->render);
    if(FAILED(hr)){
        ERR("GetService failed: %08x\n", hr);
        goto error;
    }

    hr = IAudioClient_GetService(device->client, &IID_IAudioStreamVolume,
            (void**)&device->volume);
    if(FAILED(hr)){
        ERR("GetService failed: %08x\n", hr);
        goto error;
    }

    LeaveCriticalSection(&device->lock);

    return MMSYSERR_NOERROR;

error:
    if(device->device){
        IMMDevice_Release(device->device);
        device->device = NULL;
    }
    if(device->client){
        IAudioClient_Release(device->client);
        device->client = NULL;
    }
    if(device->render){
        IAudioRenderClient_Release(device->render);
        device->render = NULL;
    }
    if(device->volume){
        IAudioStreamVolume_Release(device->volume);
        device->volume = NULL;
    }
    if(device->clock){
        IAudioClock_Release(device->clock);
        device->clock = NULL;
    }
    device->open = FALSE;
    LeaveCriticalSection(&device->lock);
    return ret;
}

static LRESULT WID_Open(WINMM_OpenInfo *info)
{
    WINMM_Device *device, **devices;
    WINMM_MMDevice *mmdevice;
    UINT internal_index;
    CRITICAL_SECTION *lock;
    LRESULT ret = MMSYSERR_ERROR;
    HRESULT hr;

    if(WINMM_IsMapper(info->req_device)){
        if (g_inmmdevices_count == 0)
            return MMSYSERR_BADDEVICEID;
        devices = g_in_mapper_devices;
        mmdevice = read_map(g_in_map, 0);
        lock = &g_devthread_lock;
        internal_index = MAPPER_INDEX;
    }else{
        if(info->req_device >= g_inmmdevices_count)
            return MMSYSERR_BADDEVICEID;

        mmdevice = read_map(g_in_map, info->req_device);

        if(!mmdevice->in_caps.szPname[0])
            return MMSYSERR_NOTENABLED;

        devices = mmdevice->devices;
        lock = &mmdevice->lock;
        internal_index = mmdevice->index;
    }

    EnterCriticalSection(lock);

    device = WINMM_FindUnusedDevice(devices, mmdevice, internal_index, FALSE);
    if(!device){
        LeaveCriticalSection(lock);
        return MMSYSERR_ALLOCATED;
    }

    LeaveCriticalSection(lock);

    ret = WINMM_OpenDevice(device, info, FALSE);
    if((info->flags & WAVE_FORMAT_QUERY) || ret != MMSYSERR_NOERROR)
        goto error;
    ret = MMSYSERR_ERROR;

    hr = IAudioClient_GetService(device->client, &IID_IAudioCaptureClient,
            (void**)&device->capture);
    if(FAILED(hr)){
        WARN("GetService failed: %08x\n", hr);
        goto error;
    }

    LeaveCriticalSection(&device->lock);

    return MMSYSERR_NOERROR;

error:
    if(device->device){
        IMMDevice_Release(device->device);
        device->device = NULL;
    }
    if(device->client){
        IAudioClient_Release(device->client);
        device->client = NULL;
    }
    if(device->capture){
        IAudioCaptureClient_Release(device->capture);
        device->capture = NULL;
    }
    if(device->clock){
        IAudioClock_Release(device->clock);
        device->clock = NULL;
    }
    device->open = FALSE;
    LeaveCriticalSection(&device->lock);
    return ret;
}

static HRESULT WINMM_CloseDevice(WINMM_Device *device)
{
    device->open = FALSE;

    if(!device->stopped){
        IAudioClient_Stop(device->client);
        device->stopped = TRUE;
    }

    if(device->acm_handle){
        acmStreamClose(device->acm_handle, 0);
        device->acm_handle = NULL;
    }

    IMMDevice_Release(device->device);
    device->device = NULL;

    IAudioClient_Release(device->client);
    device->client = NULL;

    IAudioClock_Release(device->clock);
    device->clock = NULL;

    return S_OK;
}

static LRESULT WOD_Close(HWAVEOUT hwave)
{
    WINMM_Device *device = WINMM_GetDeviceFromHWAVE((HWAVE)hwave);

    TRACE("(%p)\n", hwave);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    WINMM_CloseDevice(device);

    IAudioRenderClient_Release(device->render);
    device->render = NULL;

    IAudioStreamVolume_Release(device->volume);
    device->volume = NULL;

    LeaveCriticalSection(&device->lock);

    return MMSYSERR_NOERROR;
}

static LRESULT WID_Close(HWAVEIN hwave)
{
    WINMM_Device *device = WINMM_GetDeviceFromHWAVE((HWAVE)hwave);

    TRACE("(%p)\n", hwave);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    WINMM_CloseDevice(device);

    IAudioCaptureClient_Release(device->capture);
    device->capture = NULL;

    LeaveCriticalSection(&device->lock);

    return MMSYSERR_NOERROR;
}

static DWORD WINMM_FixedBufferLen(DWORD length, WINMM_Device *device)
{
    return length - length % device->bytes_per_frame;
}

static LRESULT WINMM_PrepareHeader(HWAVE hwave, WAVEHDR *header)
{
    WINMM_Device *device = WINMM_GetDeviceFromHWAVE(hwave);

    TRACE("(%p, %p)\n", hwave, header);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    if(device->render && device->acm_handle){
        ACMSTREAMHEADER *ash;
        DWORD size;
        MMRESULT mr;

        mr = acmStreamSize(device->acm_handle, header->dwBufferLength, &size,
                ACM_STREAMSIZEF_SOURCE);
        if(mr != MMSYSERR_NOERROR){
            LeaveCriticalSection(&device->lock);
            return mr;
        }

        ash = HeapAlloc(GetProcessHeap(), 0, sizeof(ACMSTREAMHEADER) + size);
        if(!ash){
            LeaveCriticalSection(&device->lock);
            return MMSYSERR_NOMEM;
        }

        ash->cbStruct = sizeof(*ash);
        ash->fdwStatus = 0;
        ash->dwUser = (DWORD_PTR)header;
        ash->pbSrc = (BYTE*)header->lpData;
        ash->cbSrcLength = header->dwBufferLength;
        ash->dwSrcUser = header->dwUser;
        ash->pbDst = (BYTE*)ash + sizeof(ACMSTREAMHEADER);
        ash->cbDstLength = size;
        ash->dwDstUser = 0;

        mr = acmStreamPrepareHeader(device->acm_handle, ash, 0);
        if(mr != MMSYSERR_NOERROR){
            HeapFree(GetProcessHeap(), 0, ash);
            LeaveCriticalSection(&device->lock);
            return mr;
        }

        header->reserved = (DWORD_PTR)ash;
    }

    LeaveCriticalSection(&device->lock);

    header->dwFlags |= WHDR_PREPARED;
    header->dwFlags &= ~(WHDR_DONE|WHDR_INQUEUE); /* flags cleared since w2k */

    return MMSYSERR_NOERROR;
}

static LRESULT WINMM_UnprepareHeader(HWAVE hwave, WAVEHDR *header)
{
    WINMM_Device *device = WINMM_GetDeviceFromHWAVE(hwave);

    TRACE("(%p, %p)\n", hwave, header);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    if(device->render && device->acm_handle){
        ACMSTREAMHEADER *ash = (ACMSTREAMHEADER*)header->reserved;

        acmStreamUnprepareHeader(device->acm_handle, ash, 0);

        HeapFree(GetProcessHeap(), 0, ash);
    }

    LeaveCriticalSection(&device->lock);

    header->dwFlags &= ~WHDR_PREPARED;

    return MMSYSERR_NOERROR;
}

static UINT32 WINMM_HeaderLenBytes(WINMM_Device *device, WAVEHDR *header)
{
    if(device->acm_handle){
        ACMSTREAMHEADER *ash = (ACMSTREAMHEADER*)header->reserved;
        return WINMM_FixedBufferLen(ash->cbDstLengthUsed, device);
    }

    return WINMM_FixedBufferLen(header->dwBufferLength, device);
}

static UINT32 WINMM_HeaderLenFrames(WINMM_Device *device, WAVEHDR *header)
{
    return WINMM_HeaderLenBytes(device, header) / device->bytes_per_frame;
}

static WAVEHDR *WOD_MarkDoneHeaders(WINMM_Device *device)
{
    HRESULT hr;
    WAVEHDR *first = device->first, *queue = first, *last = NULL;
    UINT64 clock_freq, clock_pos, clock_frames;
    UINT32 nloops, queue_frames = 0;

    hr = IAudioClock_GetFrequency(device->clock, &clock_freq);
    if(FAILED(hr)){
        WARN("GetFrequency failed: %08x\n", hr);
        return NULL;
    }

    hr = IAudioClock_GetPosition(device->clock, &clock_pos, NULL);
    if(FAILED(hr)){
        WARN("GetPosition failed: %08x\n", hr);
        return NULL;
    }

    clock_frames = (clock_pos * device->samples_per_sec) / clock_freq;

    nloops = device->loop_counter;
    while(queue &&
            (queue_frames += WINMM_HeaderLenFrames(device, queue)) <=
                clock_frames - device->last_clock_pos + device->remainder_frames){
        if(!nloops){
            last = queue;
            device->last_clock_pos += queue_frames;
            device->remainder_frames = 0;
            queue_frames = 0;
            queue = device->first = queue->lpNext;
        }else{
            if(queue->dwFlags & WHDR_BEGINLOOP){
                if(queue->dwFlags & WHDR_ENDLOOP)
                    --nloops;
                else
                    queue = queue->lpNext;
            }else if(queue->dwFlags & WHDR_ENDLOOP){
                queue = device->loop_start;
                --nloops;
            }
        }
    }

    if(last){
        last->lpNext = NULL;
        return first;
    }else
        return NULL;
}

static void WOD_PushData(WINMM_Device *device)
{
    WINMM_CBInfo cb_info;
    HRESULT hr;
    UINT32 pad, bufsize, avail_frames, queue_frames, written, ofs;
    UINT32 queue_bytes, nloops;
    BYTE *data;
    WAVEHDR *queue, *first = NULL;

    TRACE("(%p)\n", device->handle);

    EnterCriticalSection(&device->lock);

    if(!device->device)
        goto exit;

    if(!device->first){
        if (device->stopped)
            goto exit;
        device->stopped = TRUE;
        device->last_clock_pos = 0;
        IAudioClient_Stop(device->client);
        IAudioClient_Reset(device->client);
        goto exit;
    }

    hr = IAudioClient_GetBufferSize(device->client, &bufsize);
    if(FAILED(hr)){
        WARN("GetBufferSize failed: %08x\n", hr);
        goto exit;
    }

    hr = IAudioClient_GetCurrentPadding(device->client, &pad);
    if(FAILED(hr)){
        WARN("GetCurrentPadding failed: %08x\n", hr);
        goto exit;
    }

    first = WOD_MarkDoneHeaders(device);

    /* determine which is larger between the available buffer size and
     * the amount of data left in the queue */
    avail_frames = bufsize - pad;

    queue = device->playing;
    ofs = device->ofs_bytes;
    queue_frames = 0;
    nloops = 0;
    while(queue && queue_frames < avail_frames){
        queue_bytes = WINMM_HeaderLenBytes(device, queue);
        queue_frames += (queue_bytes - ofs) / device->bytes_per_frame;
        ofs = 0;

        if(queue->dwFlags & WHDR_ENDLOOP && nloops < device->loop_counter){
            queue = device->loop_start;
            ++nloops;
        }else
            queue = queue->lpNext;
    }

    if(queue_frames < avail_frames)
        avail_frames = queue_frames;
    if(avail_frames == 0)
        goto exit;

    hr = IAudioRenderClient_GetBuffer(device->render, avail_frames, &data);
    if(FAILED(hr)){
        WARN("GetBuffer failed: %08x\n", hr);
        goto exit;
    }

    written = 0;
    while(device->playing && written < avail_frames){
        UINT32 copy_frames, copy_bytes;
        BYTE *queue_data;

        queue = device->playing;

        queue_bytes = WINMM_HeaderLenBytes(device, queue);
        if(device->acm_handle)
            queue_data = ((ACMSTREAMHEADER*)queue->reserved)->pbDst;
        else
            queue_data = (BYTE*)queue->lpData;

        queue_frames = (queue_bytes - device->ofs_bytes) /
            device->bytes_per_frame;

        copy_frames = queue_frames < (avail_frames - written) ?
            queue_frames : avail_frames - written;
        copy_bytes = copy_frames * device->bytes_per_frame;

        memcpy(data, queue_data + device->ofs_bytes, copy_bytes);

        data += copy_bytes;
        written += copy_frames;
        device->ofs_bytes += copy_bytes;

        if(device->ofs_bytes >= queue_bytes){
            device->ofs_bytes = 0;

            if(!(queue->dwFlags & (WHDR_BEGINLOOP | WHDR_ENDLOOP)))
                device->playing = queue->lpNext;
            else{
                if(queue->dwFlags & WHDR_BEGINLOOP){
                    device->loop_start = device->playing;
                    device->playing = queue->lpNext;
                    device->loop_counter = queue->dwLoops;
                }
                if(queue->dwFlags & WHDR_ENDLOOP){
                    --device->loop_counter;
                    if(device->loop_counter)
                        device->playing = device->loop_start;
                    else
                        device->loop_start = device->playing = queue->lpNext;
                }
            }
        }
    }

    hr = IAudioRenderClient_ReleaseBuffer(device->render, avail_frames, 0);
    if(FAILED(hr)){
        WARN("ReleaseBuffer failed: %08x\n", hr);
        goto exit;
    }

    if(device->orig_fmt->nSamplesPerSec != device->samples_per_sec)
        device->played_frames += MulDiv(avail_frames, device->orig_fmt->nSamplesPerSec, device->samples_per_sec);
    else
        device->played_frames += avail_frames;

exit:
    cb_info = device->cb_info;

    LeaveCriticalSection(&device->lock);

    while(first){
        WAVEHDR *next = first->lpNext;
        first->dwFlags &= ~WHDR_INQUEUE;
        first->dwFlags |= WHDR_DONE;
        WINMM_NotifyClient(&cb_info, WOM_DONE, (DWORD_PTR)first, 0);
        first = next;
    }
}

static void WID_PullACMData(WINMM_Device *device)
{
    UINT32 packet, packet_bytes;
    DWORD flags;
    BYTE *data;
    WAVEHDR *queue;
    HRESULT hr;
    MMRESULT mr;

    if(device->acm_hdr.cbDstLength == 0){
        hr = IAudioCaptureClient_GetBuffer(device->capture, &data, &packet,
                &flags, NULL, NULL);
        if(hr != S_OK){
            if(FAILED(hr))
                WARN("GetBuffer failed: %08x\n", hr);
            return;
        }

        acmStreamSize(device->acm_handle, packet * device->bytes_per_frame,
                &packet_bytes, ACM_STREAMSIZEF_SOURCE);

        device->acm_offs = 0;

        device->acm_hdr.cbStruct = sizeof(device->acm_hdr);
        device->acm_hdr.fdwStatus = 0;
        device->acm_hdr.dwUser = 0;
        device->acm_hdr.pbSrc = data;
        device->acm_hdr.cbSrcLength = packet * device->bytes_per_frame;
        device->acm_hdr.cbSrcLengthUsed = 0;
        device->acm_hdr.dwSrcUser = 0;
        device->acm_hdr.pbDst = HeapAlloc(GetProcessHeap(), 0, packet_bytes);
        device->acm_hdr.cbDstLength = packet_bytes;
        device->acm_hdr.cbDstLengthUsed = 0;
        device->acm_hdr.dwDstUser = 0;

        mr = acmStreamPrepareHeader(device->acm_handle, &device->acm_hdr, 0);
        if(mr != MMSYSERR_NOERROR){
            WARN("acmStreamPrepareHeader failed: %d\n", mr);
            return;
        }

        mr = acmStreamConvert(device->acm_handle, &device->acm_hdr, 0);
        if(mr != MMSYSERR_NOERROR){
            WARN("acmStreamConvert failed: %d\n", mr);
            return;
        }

        hr = IAudioCaptureClient_ReleaseBuffer(device->capture, packet);
        if(FAILED(hr))
            WARN("ReleaseBuffer failed: %08x\n", hr);

        device->played_frames += packet;
    }

    queue = device->first;
    while(queue){
        UINT32 to_copy_bytes;

        to_copy_bytes = min(WINMM_FixedBufferLen(queue->dwBufferLength, device) - queue->dwBytesRecorded,
                WINMM_FixedBufferLen(device->acm_hdr.cbDstLengthUsed, device) - device->acm_offs);

        memcpy(queue->lpData + queue->dwBytesRecorded,
                device->acm_hdr.pbDst + device->acm_offs, to_copy_bytes);

        queue->dwBytesRecorded += to_copy_bytes;
        device->acm_offs += to_copy_bytes;

        if(queue->dwBufferLength - queue->dwBytesRecorded <
                device->bytes_per_frame){
            queue->dwFlags &= ~WHDR_INQUEUE;
            queue->dwFlags |= WHDR_DONE;
            device->first = queue = queue->lpNext;
        }

        if(device->acm_offs >= WINMM_FixedBufferLen(device->acm_hdr.cbDstLengthUsed, device)){
            acmStreamUnprepareHeader(device->acm_handle, &device->acm_hdr, 0);
            HeapFree(GetProcessHeap(), 0, device->acm_hdr.pbDst);
            device->acm_hdr.cbDstLength = 0;
            device->acm_hdr.cbDstLengthUsed = 0;

            /* done with this ACM Header, so try to pull more data */
            WID_PullACMData(device);
            return;
        }
    }

    /* out of WAVEHDRs to write into, so toss the rest of this packet */
    acmStreamUnprepareHeader(device->acm_handle, &device->acm_hdr, 0);
    HeapFree(GetProcessHeap(), 0, device->acm_hdr.pbDst);
    device->acm_hdr.cbDstLength = 0;
    device->acm_hdr.cbDstLengthUsed = 0;
}

static void WID_PullData(WINMM_Device *device)
{
    WINMM_CBInfo cb_info;
    WAVEHDR *queue, *first = NULL, *last = NULL;
    HRESULT hr;

    TRACE("(%p)\n", device->handle);

    EnterCriticalSection(&device->lock);

    if(!device->device || !device->first)
        goto exit;

    first = device->first;

    if(device->acm_handle){
        WID_PullACMData(device);
        goto exit;
    }

    while(device->first){
        BYTE *data;
        UINT32 packet_len, packet;
        DWORD flags;

        hr = IAudioCaptureClient_GetBuffer(device->capture, &data, &packet_len,
                &flags, NULL, NULL);
        if(hr != S_OK){
            if(FAILED(hr))
                WARN("GetBuffer failed: %08x\n", hr);
            else /* AUDCLNT_S_BUFFER_EMPTY success code */
                IAudioCaptureClient_ReleaseBuffer(device->capture, 0);
            goto exit;
        }

        packet = packet_len;
        queue = device->first;
        while(queue && packet > 0){
            UINT32 to_copy_bytes;

            to_copy_bytes = min(packet * device->bytes_per_frame,
                    WINMM_FixedBufferLen(queue->dwBufferLength, device) - queue->dwBytesRecorded);

            memcpy(queue->lpData + queue->dwBytesRecorded,
                    data + (packet_len - packet) * device->bytes_per_frame,
                    to_copy_bytes);

            queue->dwBytesRecorded += to_copy_bytes;

            if(queue->dwBufferLength - queue->dwBytesRecorded <
                    device->bytes_per_frame){
                last = queue;
                device->first = queue = queue->lpNext;
            }

            packet -= to_copy_bytes / device->bytes_per_frame;
        }

        hr = IAudioCaptureClient_ReleaseBuffer(device->capture, packet_len);
        if(FAILED(hr))
            WARN("ReleaseBuffer failed: %08x\n", hr);

        if(packet > 0)
            WARN("losing %u frames\n", packet);
        device->played_frames += packet_len - packet;
    }

exit:
    cb_info = device->cb_info;

    LeaveCriticalSection(&device->lock);

    if(last){
        last->lpNext = NULL;
        while(first){
            WAVEHDR *next = first->lpNext;
            first->dwFlags &= ~WHDR_INQUEUE;
            first->dwFlags |= WHDR_DONE;
            WINMM_NotifyClient(&cb_info, WIM_DATA, (DWORD_PTR)first, 0);
            first = next;
        }
    }
}

static MMRESULT WINMM_BeginPlaying(WINMM_Device *device)
{
    HRESULT hr;

    TRACE("(%p)\n", device->handle);

    if(device->render)
        /* prebuffer data before starting */
        WOD_PushData(device);

    if(device->stopped){
        device->stopped = FALSE;

        hr = IAudioClient_Start(device->client);
        if(FAILED(hr) && hr != AUDCLNT_E_NOT_STOPPED){
            device->stopped = TRUE;
            WARN("Start failed: %08x\n", hr);
            return MMSYSERR_ERROR;
        }
    }

    return MMSYSERR_NOERROR;
}

static LRESULT WINMM_Pause(HWAVE hwave)
{
    WINMM_Device *device = WINMM_GetDeviceFromHWAVE(hwave);
    HRESULT hr;

    TRACE("(%p)\n", hwave);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    hr = IAudioClient_Stop(device->client);
    if(FAILED(hr)){
        LeaveCriticalSection(&device->lock);
        WARN("Stop failed: %08x\n", hr);
        return MMSYSERR_ERROR;
    }

    device->stopped = FALSE;

    LeaveCriticalSection(&device->lock);

    return MMSYSERR_NOERROR;
}

static LRESULT WINMM_Reset(HWAVE hwave)
{
    WINMM_CBInfo cb_info;
    WINMM_Device *device = WINMM_GetDeviceFromHWAVE(hwave);
    BOOL is_out;
    WAVEHDR *first;
    HRESULT hr;

    TRACE("(%p)\n", hwave);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    hr = IAudioClient_Stop(device->client);
    if(FAILED(hr)){
        LeaveCriticalSection(&device->lock);
        WARN("Stop failed: %08x\n", hr);
        return MMSYSERR_ERROR;
    }
    device->stopped = TRUE;

    first = device->first;
    device->first = device->last = device->playing = NULL;
    device->ofs_bytes = 0;
    device->played_frames = 0;
    device->loop_counter = 0;
    device->last_clock_pos = 0;
    IAudioClient_Reset(device->client);

    cb_info = device->cb_info;
    is_out = device->render != NULL;

    LeaveCriticalSection(&device->lock);

    while(first){
        WAVEHDR *next = first->lpNext;
        first->dwFlags &= ~WHDR_INQUEUE;
        first->dwFlags |= WHDR_DONE;
        if(is_out)
            WINMM_NotifyClient(&cb_info, WOM_DONE, (DWORD_PTR)first, 0);
        else
            WINMM_NotifyClient(&cb_info, WIM_DATA, (DWORD_PTR)first, 0);
        first = next;
    }

    return MMSYSERR_NOERROR;
}

static MMRESULT WINMM_FramesToMMTime(MMTIME *time, UINT32 played_frames,
        UINT32 sample_rate, UINT32 bytes_per_sec)
{
    switch(time->wType){
    case TIME_SAMPLES:
        time->u.sample = played_frames;
        return MMSYSERR_NOERROR;
    case TIME_MS:
        time->u.ms = (UINT64)played_frames * 1000 / sample_rate;
        return MMSYSERR_NOERROR;
    case TIME_SMPTE:
        time->u.smpte.fps = 30;
        played_frames += sample_rate / time->u.smpte.fps - 1; /* round up */
        time->u.smpte.frame = (played_frames % sample_rate) * time->u.smpte.fps / sample_rate;
        played_frames /= sample_rate; /* yields seconds */
        time->u.smpte.sec = played_frames % 60;
        played_frames /= 60;
        time->u.smpte.min = played_frames % 60;
        time->u.smpte.hour= played_frames / 60;
        return MMSYSERR_NOERROR;
    default:
        time->wType = TIME_BYTES;
        /* fall through */
    case TIME_BYTES:
        time->u.cb = MulDiv(played_frames, bytes_per_sec, sample_rate);
        return MMSYSERR_NOERROR;
    }
}

static LRESULT WINMM_GetPosition(HWAVE hwave, MMTIME *time)
{
    WINMM_Device *device = WINMM_GetDeviceFromHWAVE(hwave);
    UINT32 played_frames, sample_rate, bytes_per_sec;

    TRACE("(%p, %p)\n", hwave, time);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    played_frames = device->played_frames;
    sample_rate = device->orig_fmt->nSamplesPerSec;
    bytes_per_sec = device->orig_fmt->nAvgBytesPerSec;

    LeaveCriticalSection(&device->lock);

    return WINMM_FramesToMMTime(time, played_frames, sample_rate, bytes_per_sec);
}

static WINMM_MMDevice *WINMM_GetMixerMMDevice(HMIXEROBJ hmix, DWORD flags,
        UINT *mmdev_index)
{
    UINT mmdev, dev, junk, *out;
    BOOL is_out;

    if(!mmdev_index)
        out = &mmdev;
    else
        out = mmdev_index;

    switch(flags & 0xF0000000){
    case MIXER_OBJECTF_MIXER: /* == 0 */
        *out = HandleToULong(hmix);
        if(*out < g_outmmdevices_count)
            return read_map(g_out_map, *out);
        if(*out - g_outmmdevices_count < g_inmmdevices_count){
            *out -= g_outmmdevices_count;
            return read_map(g_in_map, *out);
        }
        /* fall through -- if it's not a valid mixer device, then
         * it could be a valid mixer handle. windows seems to do
         * this as well. */
    case MIXER_OBJECTF_HMIXER:
    case MIXER_OBJECTF_HWAVEOUT:
    case MIXER_OBJECTF_HWAVEIN:
        WINMM_DecomposeHWAVE((HWAVE)hmix, out, &is_out, &dev, &junk);
        if(junk != 0x1 || (is_out && *out >= g_outmmdevices_count) ||
               (!is_out && *out >= g_inmmdevices_count))
            return NULL;
        if(is_out)
            return read_map(g_out_map, *out);
        return read_map(g_in_map, *out);
    case MIXER_OBJECTF_WAVEOUT:
        *out = HandleToULong(hmix);
        if(*out < g_outmmdevices_count)
            return read_map(g_out_map, *out);
        return NULL;
    case MIXER_OBJECTF_WAVEIN:
        *out = HandleToULong(hmix);
        if(*out < g_inmmdevices_count)
            return read_map(g_in_map, *out);
        return NULL;
    }

    return NULL;
}

static MMRESULT WINMM_SetupMMDeviceVolume(WINMM_MMDevice *mmdevice)
{
    IAudioSessionManager *sesman;
    IMMDevice *device;
    HRESULT hr;

    hr = IMMDeviceEnumerator_GetDevice(g_devenum, mmdevice->dev_id, &device);
    if(FAILED(hr)){
        WARN("Device %s (%s) unavailable: %08x\n",
                wine_dbgstr_w(mmdevice->dev_id),
                wine_dbgstr_w(mmdevice->out_caps.szPname), hr);
        return MMSYSERR_ERROR;
    }

    hr = IMMDevice_Activate(device, &IID_IAudioSessionManager,
            CLSCTX_INPROC_SERVER, NULL, (void**)&sesman);
    if(FAILED(hr)){
        WARN("Activate failed: %08x\n", hr);
        IMMDevice_Release(device);
        return MMSYSERR_ERROR;
    }

    IMMDevice_Release(device);

    hr = IAudioSessionManager_GetSimpleAudioVolume(sesman, &mmdevice->session,
            FALSE, &mmdevice->volume);
    IAudioSessionManager_Release(sesman);
    if(FAILED(hr)){
        WARN("GetSimpleAudioVolume failed: %08x\n", hr);
        return MMSYSERR_ERROR;
    }

    return MMSYSERR_NOERROR;
}

static LRESULT MXD_GetControlDetails(WINMM_ControlDetails *details)
{
    WINMM_MMDevice *mmdevice;
    MIXERCONTROLDETAILS *control = details->details;
    HRESULT hr;

    TRACE("(%p)\n", details->hmix);

    mmdevice = WINMM_GetMixerMMDevice(details->hmix, details->flags, NULL);
    if(!mmdevice)
        return MMSYSERR_INVALHANDLE;

    EnterCriticalSection(&mmdevice->lock);

    if(!mmdevice->volume){
        MMRESULT mr;

        mr = WINMM_SetupMMDeviceVolume(mmdevice);
        if(mr != MMSYSERR_NOERROR){
            LeaveCriticalSection(&mmdevice->lock);
            return mr;
        }
    }

    if(control->dwControlID == 0){
        float vol;
        MIXERCONTROLDETAILS_UNSIGNED *udet;

        if(!control->paDetails ||
                control->cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED)){
            LeaveCriticalSection(&mmdevice->lock);
            return MMSYSERR_INVALPARAM;
        }

        hr = ISimpleAudioVolume_GetMasterVolume(mmdevice->volume, &vol);
        if(FAILED(hr)){
            WARN("GetMasterVolume failed: %08x\n", hr);
            LeaveCriticalSection(&mmdevice->lock);
            return MMSYSERR_ERROR;
        }

        udet = (MIXERCONTROLDETAILS_UNSIGNED*)control->paDetails;
        udet->dwValue = vol * ((unsigned int)0xFFFF);
    }else if(control->dwControlID == 1){
        BOOL mute;
        MIXERCONTROLDETAILS_BOOLEAN *bdet;

        if(!control->paDetails ||
                control->cbDetails < sizeof(MIXERCONTROLDETAILS_BOOLEAN)){
            LeaveCriticalSection(&mmdevice->lock);
            return MMSYSERR_INVALPARAM;
        }

        hr = ISimpleAudioVolume_GetMute(mmdevice->volume, &mute);
        if(FAILED(hr)){
            WARN("GetMute failed: %08x\n", hr);
            LeaveCriticalSection(&mmdevice->lock);
            return MMSYSERR_ERROR;
        }

        bdet = (MIXERCONTROLDETAILS_BOOLEAN*)control->paDetails;
        bdet->fValue = mute;
    }else if(control->dwControlID == 2 || control->dwControlID == 3){
        FIXME("What should the sw-side mixer controls map to?\n");
    }else{
        LeaveCriticalSection(&mmdevice->lock);
        return MIXERR_INVALCONTROL;
    }

    LeaveCriticalSection(&mmdevice->lock);

    return MMSYSERR_NOERROR;
}

static LRESULT MXD_SetControlDetails(WINMM_ControlDetails *details)
{
    WINMM_MMDevice *mmdevice;
    MIXERCONTROLDETAILS *control = details->details;
    HRESULT hr;

    TRACE("(%p)\n", details->hmix);

    mmdevice = WINMM_GetMixerMMDevice(details->hmix, details->flags, NULL);
    if(!mmdevice)
        return MMSYSERR_INVALHANDLE;

    EnterCriticalSection(&mmdevice->lock);

    if(!mmdevice->volume){
        MMRESULT mr;

        mr = WINMM_SetupMMDeviceVolume(mmdevice);
        if(mr != MMSYSERR_NOERROR){
            LeaveCriticalSection(&mmdevice->lock);
            return mr;
        }
    }

    if(control->dwControlID == 0){
        float vol;
        MIXERCONTROLDETAILS_UNSIGNED *udet;

        if(!control->paDetails ||
                control->cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED)){
            LeaveCriticalSection(&mmdevice->lock);
            return MMSYSERR_INVALPARAM;
        }

        udet = (MIXERCONTROLDETAILS_UNSIGNED*)control->paDetails;

        if(udet->dwValue > 65535){
            LeaveCriticalSection(&mmdevice->lock);
            return MMSYSERR_INVALPARAM;
        }

        vol = udet->dwValue / 65535.f;

        hr = ISimpleAudioVolume_SetMasterVolume(mmdevice->volume, vol, NULL);
        if(FAILED(hr)){
            WARN("SetMasterVolume failed: %08x\n", hr);
            LeaveCriticalSection(&mmdevice->lock);
            return MMSYSERR_ERROR;
        }
    }else if(control->dwControlID == 1){
        BOOL mute;
        MIXERCONTROLDETAILS_BOOLEAN *bdet;

        if(!control->paDetails ||
                control->cbDetails < sizeof(MIXERCONTROLDETAILS_BOOLEAN)){
            LeaveCriticalSection(&mmdevice->lock);
            return MMSYSERR_INVALPARAM;
        }

        bdet = (MIXERCONTROLDETAILS_BOOLEAN*)control->paDetails;
        mute = bdet->fValue;

        hr = ISimpleAudioVolume_SetMute(mmdevice->volume, mute, NULL);
        if(FAILED(hr)){
            WARN("SetMute failed: %08x\n", hr);
            LeaveCriticalSection(&mmdevice->lock);
            return MMSYSERR_ERROR;
        }
    }else if(control->dwControlID == 2 || control->dwControlID == 3){
        FIXME("What should the sw-side mixer controls map to?\n");
    }else{
        LeaveCriticalSection(&mmdevice->lock);
        return MIXERR_INVALCONTROL;
    }

    LeaveCriticalSection(&mmdevice->lock);

    return MMSYSERR_NOERROR;
}

static LRESULT DRV_QueryDeviceInterface(WINMM_QueryInterfaceInfo *info)
{
    WINMM_MMDevice *mmdevice;
    IMMDevice *device;
    IPropertyStore *ps;
    PROPVARIANT pv;
    DWORD len_bytes;
    HRESULT hr;

    static const PROPERTYKEY deviceinterface_key = {
        {0x233164c8, 0x1b2c, 0x4c7d, {0xbc, 0x68, 0xb6, 0x71, 0x68, 0x7a, 0x25, 0x67}}, 1
    };

    if(WINMM_IsMapper(info->index)){
        if(info->str){
            if(*info->len_bytes < sizeof(WCHAR))
                return MMSYSERR_INVALPARAM;
            *info->str = 0;
        }else
            *info->len_bytes = sizeof(WCHAR);
        return MMSYSERR_NOERROR;
    }

    if(info->is_out){
        if(info->index >= g_outmmdevices_count)
            return MMSYSERR_INVALHANDLE;

        mmdevice = &g_out_mmdevices[info->index];
    }else{
        if(info->index >= g_inmmdevices_count)
            return MMSYSERR_INVALHANDLE;

        mmdevice = &g_in_mmdevices[info->index];
    }

    hr = IMMDeviceEnumerator_GetDevice(g_devenum, mmdevice->dev_id,
            &device);
    if(FAILED(hr)){
        WARN("Device %s unavailable: %08x\n", wine_dbgstr_w(mmdevice->dev_id), hr);
        return MMSYSERR_ERROR;
    }

    hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps);
    if(FAILED(hr)){
        WARN("OpenPropertyStore failed: %08x\n", hr);
        IMMDevice_Release(device);
        return MMSYSERR_ERROR;
    }

    PropVariantInit(&pv);
    hr = IPropertyStore_GetValue(ps, &deviceinterface_key, &pv);
    if(FAILED(hr)){
        WARN("GetValue failed: %08x\n", hr);
        IPropertyStore_Release(ps);
        IMMDevice_Release(device);
        return MMSYSERR_ERROR;
    }
    if(pv.vt != VT_LPWSTR){
        WARN("Got unexpected property type: %u\n", pv.vt);
        PropVariantClear(&pv);
        IPropertyStore_Release(ps);
        IMMDevice_Release(device);
        return MMSYSERR_ERROR;
    }

    len_bytes = (lstrlenW(pv.u.pwszVal) + 1) * sizeof(WCHAR);

    if(info->str){
        if(len_bytes > *info->len_bytes){
            PropVariantClear(&pv);
            IPropertyStore_Release(ps);
            IMMDevice_Release(device);
            return MMSYSERR_INVALPARAM;
        }

        memcpy(info->str, pv.u.pwszVal, len_bytes);
    }else
        *info->len_bytes = len_bytes;

    PropVariantClear(&pv);
    IPropertyStore_Release(ps);
    IMMDevice_Release(device);

    return MMSYSERR_NOERROR;
}

static LRESULT CALLBACK WINMM_DevicesMsgProc(HWND hwnd, UINT msg, WPARAM wparam,
        LPARAM lparam)
{
    switch(msg){
    case WODM_OPEN:
        return WOD_Open((WINMM_OpenInfo*)wparam);
    case WODM_CLOSE:
        return WOD_Close((HWAVEOUT)wparam);
    case WIDM_OPEN:
        return WID_Open((WINMM_OpenInfo*)wparam);
    case WIDM_CLOSE:
        return WID_Close((HWAVEIN)wparam);
    case MXDM_GETCONTROLDETAILS:
        return MXD_GetControlDetails((WINMM_ControlDetails*)wparam);
    case MXDM_SETCONTROLDETAILS:
        return MXD_SetControlDetails((WINMM_ControlDetails*)wparam);
    case DRV_QUERYDEVICEINTERFACESIZE:
    case DRV_QUERYDEVICEINTERFACE:
        return DRV_QueryDeviceInterface((WINMM_QueryInterfaceInfo*)wparam);
    }
    return DefWindowProcW(hwnd, msg, wparam, lparam);
}

static BOOL WINMM_DevicesThreadDone(void)
{
    UINT i;

    EnterCriticalSection(&g_devthread_lock);

    if(g_devthread_token > 0){
        LeaveCriticalSection(&g_devthread_lock);
        return FALSE;
    }

    for(i = 0; i < g_devhandle_count; ++i){
        if(g_handle_devices[i]->open){
            LeaveCriticalSection(&g_devthread_lock);
            return FALSE;
        }
    }

    DestroyWindow(g_devices_hwnd);
    g_devices_hwnd = NULL;
    IMMDeviceEnumerator_Release(g_devenum);
    g_devenum = NULL;
    CoUninitialize();

    LeaveCriticalSection(&g_devthread_lock);

    return TRUE;
}

static DWORD WINAPI WINMM_DevicesThreadProc(void *arg)
{
    HANDLE evt = arg;
    HRESULT hr;
    static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0};

    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if(FAILED(hr)){
        WARN("CoInitializeEx failed: %08x\n", hr);
        FreeLibraryAndExitThread(g_devthread_module, 1);
    }

    hr = WINMM_InitMMDevices();
    if(FAILED(hr)){
        CoUninitialize();
        FreeLibraryAndExitThread(g_devthread_module, 1);
    }

    hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
            CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&g_devenum);
    if(FAILED(hr)){
        WARN("CoCreateInstance failed: %08x\n", hr);
        CoUninitialize();
        FreeLibraryAndExitThread(g_devthread_module, 1);
    }

    g_devices_hwnd = CreateWindowW(messageW, NULL, 0, 0, 0, 0, 0,
            HWND_MESSAGE, NULL, NULL, NULL);
    if(!g_devices_hwnd){
        WARN("CreateWindow failed: %d\n", GetLastError());
        CoUninitialize();
        FreeLibraryAndExitThread(g_devthread_module, 1);
    }

    SetWindowLongPtrW(g_devices_hwnd, GWLP_WNDPROC,
            (LONG_PTR)WINMM_DevicesMsgProc);

    /* inform caller that the thread is ready to process messages */
    SetEvent(evt);
    evt = NULL; /* do not use after this point */

    while(1){
        DWORD wait;
        wait = MsgWaitForMultipleObjects(g_devhandle_count, g_device_handles,
                FALSE, INFINITE, QS_ALLINPUT);
        if(wait == g_devhandle_count + WAIT_OBJECT_0){
            MSG msg;
            if(PeekMessageW(&msg, g_devices_hwnd, 0, 0, PM_REMOVE))
                WARN("Unexpected message: 0x%x\n", msg.message);
            if(!g_devices_hwnd)
                break;
        }else if(wait < g_devhandle_count + WAIT_OBJECT_0){
            WINMM_Device *device = g_handle_devices[wait - WAIT_OBJECT_0];
            if(device->render)
                WOD_PushData(device);
            else
                WID_PullData(device);
        }else
            WARN("Unexpected MsgWait result 0x%x, GLE: %d\n", wait,
                    GetLastError());
        if(WINMM_DevicesThreadDone()){
            TRACE("Quitting devices thread\n");
            FreeLibraryAndExitThread(g_devthread_module, 0);
        }
    }

    FreeLibraryAndExitThread(g_devthread_module, 0);
}

/* on success, increments g_devthread_token to prevent
 * device thread shutdown. caller must decrement. */
static BOOL WINMM_StartDevicesThread(void)
{
    HANDLE events[2];
    DWORD wait;

    EnterCriticalSection(&g_devthread_lock);

    if(g_devices_hwnd){
        wait = WaitForSingleObject(g_devices_thread, 0);
        if(wait == WAIT_TIMEOUT){
            /* thread still running */
            InterlockedIncrement(&g_devthread_token);
            LeaveCriticalSection(&g_devthread_lock);
            return TRUE;
        }
        if(wait != WAIT_OBJECT_0){
            /* error */
            LeaveCriticalSection(&g_devthread_lock);
            return FALSE;
        }
        TRACE("Devices thread left dangling message window?\n");
        g_devices_hwnd = NULL;
        CloseHandle(g_devices_thread);
        g_devices_thread = NULL;
    }else if(g_devices_thread){
        WaitForSingleObject(g_devices_thread, INFINITE);
        CloseHandle(g_devices_thread);
        g_devices_thread = NULL;
    }

    TRACE("Starting up devices thread\n");

    /* The devices thread holds a reference to the winmm module
     * to prevent it from unloading while it's running. */
    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
            (const WCHAR *)WINMM_StartDevicesThread, &g_devthread_module);

    events[0] = CreateEventW(NULL, FALSE, FALSE, NULL);

    g_devices_thread = CreateThread(NULL, 0, WINMM_DevicesThreadProc,
            events[0], 0, NULL);
    if(!g_devices_thread){
        LeaveCriticalSection(&g_devthread_lock);
        CloseHandle(events[0]);
        FreeLibrary(g_devthread_module);
        return FALSE;
    }

    events[1] = g_devices_thread;
    wait = WaitForMultipleObjects(2, events, FALSE, INFINITE);
    CloseHandle(events[0]);
    if(wait != WAIT_OBJECT_0){
        if(wait == 1 + WAIT_OBJECT_0){
            CloseHandle(g_devices_thread);
            g_devices_thread = NULL;
            g_devices_hwnd = NULL;
        }
        LeaveCriticalSection(&g_devthread_lock);
        return FALSE;
    }

    InterlockedIncrement(&g_devthread_token);

    LeaveCriticalSection(&g_devthread_lock);

    return TRUE;
}

/**************************************************************************
 * 				waveOutGetNumDevs		[WINMM.@]
 */
UINT WINAPI waveOutGetNumDevs(void)
{
    HRESULT hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return 0;

    TRACE("count: %u\n", g_outmmdevices_count);

    return g_outmmdevices_count;
}

/**************************************************************************
 * 				waveOutGetDevCapsA		[WINMM.@]
 */
UINT WINAPI waveOutGetDevCapsA(UINT_PTR uDeviceID, LPWAVEOUTCAPSA lpCaps,
			       UINT uSize)
{
    WAVEOUTCAPSW	wocW;
    UINT 		ret;

    TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);

    if(!lpCaps)
        return MMSYSERR_INVALPARAM;

    ret = waveOutGetDevCapsW(uDeviceID, &wocW, sizeof(wocW));

    if (ret == MMSYSERR_NOERROR) {
	WAVEOUTCAPSA wocA;
	wocA.wMid           = wocW.wMid;
	wocA.wPid           = wocW.wPid;
	wocA.vDriverVersion = wocW.vDriverVersion;
        WideCharToMultiByte( CP_ACP, 0, wocW.szPname, -1, wocA.szPname,
                             sizeof(wocA.szPname), NULL, NULL );
	wocA.dwFormats      = wocW.dwFormats;
	wocA.wChannels      = wocW.wChannels;
	wocA.dwSupport      = wocW.dwSupport;
	memcpy(lpCaps, &wocA, min(uSize, sizeof(wocA)));
    }
    return ret;
}

/**************************************************************************
 * 				waveOutGetDevCapsW		[WINMM.@]
 */
UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps,
			       UINT uSize)
{
    WAVEOUTCAPSW mapper_caps, *caps;
    HRESULT hr;

    TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);

    hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return MMSYSERR_NODRIVER;

    if (lpCaps == NULL)	return MMSYSERR_INVALPARAM;

    if(WINMM_IsMapper(uDeviceID)){
        mapper_caps.wMid = 0xFF;
        mapper_caps.wPid = 0xFF;
        mapper_caps.vDriverVersion = 0x00010001;
        mapper_caps.dwFormats = 0xFFFFFFFF;
        mapper_caps.wReserved1 = 0;
        mapper_caps.dwSupport = WAVECAPS_LRVOLUME | WAVECAPS_VOLUME |
            WAVECAPS_SAMPLEACCURATE;
        mapper_caps.wChannels = 2;
        LoadStringW(hWinMM32Instance, IDS_MAPPER_NAME, mapper_caps.szPname, MAXPNAMELEN);

        caps = &mapper_caps;
    }else{
        if(uDeviceID >= g_outmmdevices_count)
            return MMSYSERR_BADDEVICEID;

        caps = &read_map(g_out_map, uDeviceID)->out_caps;
    }

    memcpy(lpCaps, caps, min(uSize, sizeof(*lpCaps)));

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				waveOutGetErrorTextA 	[WINMM.@]
 * 				waveInGetErrorTextA 	[WINMM.@]
 */
UINT WINAPI waveOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
{
    UINT	ret;

    if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
    else if (uSize == 0) ret = MMSYSERR_NOERROR;
    else
    {
        LPWSTR	xstr = HeapAlloc(GetProcessHeap(), 0, uSize * sizeof(WCHAR));
        if (!xstr) ret = MMSYSERR_NOMEM;
        else
        {
            ret = waveOutGetErrorTextW(uError, xstr, uSize);
            if (ret == MMSYSERR_NOERROR)
                WideCharToMultiByte(CP_ACP, 0, xstr, -1, lpText, uSize, NULL, NULL);
            HeapFree(GetProcessHeap(), 0, xstr);
        }
    }
    return ret;
}

/**************************************************************************
 * 				waveOutGetErrorTextW 	[WINMM.@]
 * 				waveInGetErrorTextW 	[WINMM.@]
 */
UINT WINAPI waveOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
{
    UINT        ret = MMSYSERR_BADERRNUM;

    if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
    else if (uSize == 0) ret = MMSYSERR_NOERROR;
    else if (
	       /* test has been removed because MMSYSERR_BASE is 0, and gcc did emit
		* a warning for the test was always true */
	       (/*uError >= MMSYSERR_BASE && */ uError <= MMSYSERR_LASTERROR) ||
	       (uError >= WAVERR_BASE  && uError <= WAVERR_LASTERROR)) {
	if (LoadStringW(hWinMM32Instance,
			uError, lpText, uSize) > 0) {
	    ret = MMSYSERR_NOERROR;
	}
    }
    return ret;
}

/**************************************************************************
 *			waveOutOpen			[WINMM.@]
 * All the args/structs have the same layout as the win16 equivalents
 */
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID,
                       LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback,
                       DWORD_PTR dwInstance, DWORD dwFlags)
{
    LRESULT res;
    WINMM_OpenInfo info;
    WINMM_CBInfo cb_info;

    TRACE("(%p, %u, %p, %lx, %lx, %08x)\n", lphWaveOut, uDeviceID, lpFormat,
            dwCallback, dwInstance, dwFlags);

    if(!lphWaveOut && !(dwFlags & WAVE_FORMAT_QUERY))
        return MMSYSERR_INVALPARAM;

    res = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
    if(res != MMSYSERR_NOERROR)
        return res;

    if(!WINMM_StartDevicesThread())
        return MMSYSERR_NODRIVER;

    info.handle = 0;
    info.format = (WAVEFORMATEX*)lpFormat;
    info.callback = dwCallback;
    info.cb_user = dwInstance;
    info.req_device = uDeviceID;
    info.flags = dwFlags;
    info.reset = TRUE;

    res = SendMessageW(g_devices_hwnd, WODM_OPEN, (DWORD_PTR)&info, 0);
    InterlockedDecrement(&g_devthread_token);
    if(res != MMSYSERR_NOERROR || (dwFlags & WAVE_FORMAT_QUERY))
        return res;

    if(lphWaveOut)
        *lphWaveOut = (HWAVEOUT)info.handle;

    cb_info.flags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
    cb_info.callback = dwCallback;
    cb_info.user = dwInstance;
    cb_info.hwave = info.handle;

    WINMM_NotifyClient(&cb_info, WOM_OPEN, 0, 0);

    return res;
}

/**************************************************************************
 * 				waveOutClose		[WINMM.@]
 */
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
{
    UINT res;
    WINMM_Device *device;
    WINMM_CBInfo cb_info;

    TRACE("(%p)\n", hWaveOut);

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveOut);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    cb_info = device->cb_info;

    LeaveCriticalSection(&device->lock);

    res = SendMessageW(g_devices_hwnd, WODM_CLOSE, (WPARAM)hWaveOut, 0);

    if(res == MMSYSERR_NOERROR)
        WINMM_NotifyClient(&cb_info, WOM_CLOSE, 0, 0);

    return res;
}

/**************************************************************************
 * 				waveOutPrepareHeader	[WINMM.@]
 */
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut,
				 WAVEHDR* lpWaveOutHdr, UINT uSize)
{
    TRACE("(%p, %p, %u)\n", hWaveOut, lpWaveOutHdr, uSize);

    if(!lpWaveOutHdr || uSize < sizeof(WAVEHDR))
        return MMSYSERR_INVALPARAM;

    if(lpWaveOutHdr->dwFlags & WHDR_PREPARED)
        return MMSYSERR_NOERROR;

    return WINMM_PrepareHeader((HWAVE)hWaveOut, lpWaveOutHdr);
}

/**************************************************************************
 * 				waveOutUnprepareHeader	[WINMM.@]
 */
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut,
				   LPWAVEHDR lpWaveOutHdr, UINT uSize)
{
    TRACE("(%p, %p, %u)\n", hWaveOut, lpWaveOutHdr, uSize);

    if(!lpWaveOutHdr || uSize < sizeof(WAVEHDR))
        return MMSYSERR_INVALPARAM;

    if(lpWaveOutHdr->dwFlags & WHDR_INQUEUE)
        return WAVERR_STILLPLAYING;

    if(!(lpWaveOutHdr->dwFlags & WHDR_PREPARED))
        return MMSYSERR_NOERROR;

    return WINMM_UnprepareHeader((HWAVE)hWaveOut, lpWaveOutHdr);
}

/**************************************************************************
 * 				waveOutWrite		[WINMM.@]
 */
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, WAVEHDR *header, UINT uSize)
{
    WINMM_Device *device;
    MMRESULT mr;

    TRACE("(%p, %p, %u)\n", hWaveOut, header, uSize);

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveOut);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    if(!header->lpData || !(header->dwFlags & WHDR_PREPARED)){
        LeaveCriticalSection(&device->lock);
        return WAVERR_UNPREPARED;
    }

    if(header->dwFlags & WHDR_INQUEUE){
        LeaveCriticalSection(&device->lock);
        return WAVERR_STILLPLAYING;
    }

    TRACE("dwBufferLength: %u\n", header->dwBufferLength);

    if(device->acm_handle){
        ACMSTREAMHEADER *ash = (ACMSTREAMHEADER*)header->reserved;

        ash->cbSrcLength = header->dwBufferLength;
        mr = acmStreamConvert(device->acm_handle, ash, 0);
        if(mr != MMSYSERR_NOERROR){
            LeaveCriticalSection(&device->lock);
            return mr;
        }
    }

    if(device->first){
        device->last->lpNext = header;
        device->last = header;
        if(!device->playing)
            device->playing = header;
    }else{
        device->playing = device->first = device->last = header;
        if(header->dwFlags & WHDR_BEGINLOOP){
            device->loop_counter = header->dwLoops;
            device->loop_start = header;
        }
    }

    header->lpNext = NULL;
    header->dwFlags &= ~WHDR_DONE;
    header->dwFlags |= WHDR_INQUEUE;

    mr = WINMM_BeginPlaying(device);

    LeaveCriticalSection(&device->lock);

    return mr;
}

/**************************************************************************
 * 				waveOutBreakLoop	[WINMM.@]
 */
UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut)
{
    WINMM_Device *device;

    TRACE("(%p)\n", hWaveOut);

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveOut);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    device->loop_counter = 0;

    LeaveCriticalSection(&device->lock);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				waveOutPause		[WINMM.@]
 */
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
{
    TRACE("(%p)\n", hWaveOut);

    return WINMM_Pause((HWAVE)hWaveOut);
}

/**************************************************************************
 * 				waveOutReset		[WINMM.@]
 */
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
{
    TRACE("(%p)\n", hWaveOut);

    return WINMM_Reset((HWAVE)hWaveOut);
}

/**************************************************************************
 * 				waveOutRestart		[WINMM.@]
 */
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
{
    WINMM_Device *device;
    MMRESULT mr;

    TRACE("(%p)\n", hWaveOut);

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveOut);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    device->stopped = TRUE;

    mr = WINMM_BeginPlaying(device);

    LeaveCriticalSection(&device->lock);

    return mr;
}

/**************************************************************************
 * 				waveOutGetPosition	[WINMM.@]
 */
UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, LPMMTIME lpTime,
			       UINT uSize)
{
    TRACE("(%p, %p, %u)\n", hWaveOut, lpTime, uSize);

    if(!uSize || !lpTime)
        return MMSYSERR_INVALPARAM;

    if(uSize < sizeof(MMTIME))
        return MMSYSERR_ERROR;

    return WINMM_GetPosition((HWAVE)hWaveOut, lpTime);
}

/**************************************************************************
 * 				waveOutGetPitch		[WINMM.@]
 */
UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, LPDWORD lpdw)
{
    TRACE("(%p, %p)\n", hWaveOut, lpdw);
    return MMSYSERR_NOTSUPPORTED;
}

/**************************************************************************
 * 				waveOutSetPitch		[WINMM.@]
 */
UINT WINAPI waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dw)
{
    TRACE("(%p, %08x)\n", hWaveOut, dw);

    return MMSYSERR_NOTSUPPORTED;
}

/**************************************************************************
 * 				waveOutGetPlaybackRate	[WINMM.@]
 */
UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, LPDWORD lpdw)
{
    TRACE("(%p, %p)\n", hWaveOut, lpdw);

    return MMSYSERR_NOTSUPPORTED;
}

/**************************************************************************
 * 				waveOutSetPlaybackRate	[WINMM.@]
 */
UINT WINAPI waveOutSetPlaybackRate(HWAVEOUT hWaveOut, DWORD dw)
{
    TRACE("(%p, %08x)\n", hWaveOut, dw);

    return MMSYSERR_NOTSUPPORTED;
}

/**************************************************************************
 * 				waveOutGetVolume	[WINMM.@]
 */
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, DWORD *out)
{
    WINMM_Device *device;
    UINT32 channels;
    float *vols;
    HRESULT hr;

    TRACE("(%p, %p)\n", hWaveOut, out);

    if(!out)
        return MMSYSERR_INVALPARAM;

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveOut);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    hr = IAudioStreamVolume_GetChannelCount(device->volume, &channels);
    if(FAILED(hr)){
        LeaveCriticalSection(&device->lock);
        WARN("GetChannelCount failed: %08x\n", hr);
        return MMSYSERR_ERROR;
    }

    vols = HeapAlloc(GetProcessHeap(), 0, sizeof(float) * channels);
    if(!vols){
        LeaveCriticalSection(&device->lock);
        return MMSYSERR_NOMEM;
    }

    hr = IAudioStreamVolume_GetAllVolumes(device->volume, channels, vols);
    if(FAILED(hr)){
        LeaveCriticalSection(&device->lock);
        HeapFree(GetProcessHeap(), 0, vols);
        WARN("GetAllVolumes failed: %08x\n", hr);
        return MMSYSERR_ERROR;
    }

    LeaveCriticalSection(&device->lock);

    *out = ((UINT16)(vols[0] * (DWORD)0xFFFF));
    if(channels > 1)
        *out |= ((UINT16)(vols[1] * (DWORD)0xFFFF)) << 16;

    HeapFree(GetProcessHeap(), 0, vols);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				waveOutSetVolume	[WINMM.@]
 */
UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD in)
{
    WINMM_Device *device;
    UINT32 channels;
    float *vols;
    HRESULT hr;

    TRACE("(%p, %08x)\n", hWaveOut, in);

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveOut);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    hr = IAudioStreamVolume_GetChannelCount(device->volume, &channels);
    if(FAILED(hr)){
        LeaveCriticalSection(&device->lock);
        WARN("GetChannelCount failed: %08x\n", hr);
        return MMSYSERR_ERROR;
    }

    vols = HeapAlloc(GetProcessHeap(), 0, sizeof(float) * channels);
    if(!vols){
        LeaveCriticalSection(&device->lock);
        return MMSYSERR_NOMEM;
    }

    hr = IAudioStreamVolume_GetAllVolumes(device->volume, channels, vols);
    if(FAILED(hr)){
        LeaveCriticalSection(&device->lock);
        HeapFree(GetProcessHeap(), 0, vols);
        WARN("GetAllVolumes failed: %08x\n", hr);
        return MMSYSERR_ERROR;
    }

    vols[0] = (float)((DWORD)(in & 0xFFFF) / (float)0xFFFF);
    if(channels > 1)
        vols[1] = (float)((DWORD)(in >> 16) / (float)0xFFFF);

    hr = IAudioStreamVolume_SetAllVolumes(device->volume, channels, vols);
    if(FAILED(hr)){
        LeaveCriticalSection(&device->lock);
        HeapFree(GetProcessHeap(), 0, vols);
        WARN("SetAllVolumes failed: %08x\n", hr);
        return MMSYSERR_ERROR;
    }

    LeaveCriticalSection(&device->lock);

    HeapFree(GetProcessHeap(), 0, vols);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				waveOutGetID		[WINMM.@]
 */
UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT* lpuDeviceID)
{
    WINMM_Device *device;
    UINT dev, junk;
    BOOL is_out;

    TRACE("(%p, %p)\n", hWaveOut, lpuDeviceID);

    if(!lpuDeviceID)
        return MMSYSERR_INVALPARAM;

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveOut);
    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    LeaveCriticalSection(&device->lock);

    WINMM_DecomposeHWAVE((HWAVE)hWaveOut, lpuDeviceID, &is_out, &dev, &junk);

    return MMSYSERR_NOERROR;
}

static UINT WINMM_QueryInstanceIDSize(UINT device, DWORD_PTR *len, BOOL is_out)
{
    UINT count;
    WINMM_MMDevice **devices;

    TRACE("(%u, %p, %d)\n", device, len, is_out);

    if(is_out){
        count = g_outmmdevices_count;
        devices = g_out_map;
    }else{
        count = g_inmmdevices_count;
        devices = g_in_map;
    }

    if(device >= count)
        return MMSYSERR_INVALHANDLE;

    EnterCriticalSection(&g_devthread_lock);
    *len = (lstrlenW(devices[device]->dev_id) + 1) * sizeof(WCHAR);
    LeaveCriticalSection(&g_devthread_lock);

    return MMSYSERR_NOERROR;
}

static UINT WINMM_QueryInstanceID(UINT device, WCHAR *str, DWORD_PTR len,
        BOOL is_out)
{
    UINT count, id_len;
    WINMM_MMDevice **devices;

    TRACE("(%u, %p, %d)\n", device, str, is_out);

    if(is_out){
        count = g_outmmdevices_count;
        devices = g_out_map;
    }else{
        count = g_inmmdevices_count;
        devices = g_in_map;
    }

    if(device >= count)
        return MMSYSERR_INVALHANDLE;

    EnterCriticalSection(&g_devthread_lock);
    id_len = (lstrlenW(devices[device]->dev_id) + 1) * sizeof(WCHAR);
    if(len < id_len){
        LeaveCriticalSection(&g_devthread_lock);
        return MMSYSERR_ERROR;
    }

    memcpy(str, devices[device]->dev_id, id_len);
    LeaveCriticalSection(&g_devthread_lock);

    return MMSYSERR_NOERROR;
}

static UINT get_device_interface(UINT msg, BOOL is_out, UINT index, WCHAR *out, ULONG *out_len)
{
    WINMM_QueryInterfaceInfo info;
    UINT ret;

    if(!WINMM_StartDevicesThread())
        return MMSYSERR_NODRIVER;

    info.is_out = is_out;
    info.index = index;
    info.str = out;
    info.len_bytes = out_len;

    ret = SendMessageW(g_devices_hwnd, msg, (DWORD_PTR)&info, 0);
    InterlockedDecrement(&g_devthread_token);
    return ret;
}

/**************************************************************************
 * 				waveOutMessage 		[WINMM.@]
 */
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage,
                           DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
    TRACE("(%p, %u, %lx, %lx)\n", hWaveOut, uMessage, dwParam1, dwParam2);

    switch(uMessage){
    case DRV_QUERYFUNCTIONINSTANCEIDSIZE:
        return WINMM_QueryInstanceIDSize(HandleToULong(hWaveOut),
                (DWORD_PTR*)dwParam1, TRUE);
    case DRV_QUERYFUNCTIONINSTANCEID:
        return WINMM_QueryInstanceID(HandleToULong(hWaveOut), (WCHAR*)dwParam1, dwParam2, TRUE);
    case DRV_QUERYDEVICEINTERFACESIZE:
        return get_device_interface(DRV_QUERYDEVICEINTERFACESIZE, TRUE, HandleToULong(hWaveOut),
                NULL, (ULONG*)dwParam1);
    case DRV_QUERYDEVICEINTERFACE:
        {
            ULONG size = dwParam2;
            return get_device_interface(DRV_QUERYDEVICEINTERFACE, TRUE, HandleToULong(hWaveOut),
                    (WCHAR*)dwParam1, &size);
        }
    case DRV_QUERYMAPPABLE:
        return MMSYSERR_NOERROR;
    case DRVM_MAPPER_PREFERRED_GET:
        if(dwParam1) {
            if(g_outmmdevices_count > 0)
                /* Device 0 is always the default device */
                *(DWORD *)dwParam1 = 0;
            else
                *(DWORD *)dwParam1 = -1;
        }

        if(dwParam2)
            /* Status flags */
            *(DWORD *)dwParam2 = 0;

        return MMSYSERR_NOERROR;
    }

    TRACE("Message not supported: %u\n", uMessage);

    return MMSYSERR_NOTSUPPORTED;
}

/**************************************************************************
 * 				waveInGetNumDevs 		[WINMM.@]
 */
UINT WINAPI waveInGetNumDevs(void)
{
    HRESULT hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return 0;

    TRACE("count: %u\n", g_inmmdevices_count);

    return g_inmmdevices_count;
}

/**************************************************************************
 * 				waveInGetDevCapsW 		[WINMM.@]
 */
UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
{
    WAVEINCAPSW mapper_caps, *caps;
    HRESULT hr;

    TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);

    hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return MMSYSERR_NODRIVER;

    if(!lpCaps)
        return MMSYSERR_INVALPARAM;

    if(WINMM_IsMapper(uDeviceID)){
        mapper_caps.wMid = 0xFF;
        mapper_caps.wPid = 0xFF;
        mapper_caps.vDriverVersion = 0x00010001;
        mapper_caps.dwFormats = 0xFFFFFFFF;
        mapper_caps.wReserved1 = 0;
        mapper_caps.wChannels = 2;
        LoadStringW(hWinMM32Instance, IDS_MAPPER_NAME, mapper_caps.szPname, MAXPNAMELEN);

        caps = &mapper_caps;
    }else{
        if(uDeviceID >= g_inmmdevices_count)
            return MMSYSERR_BADDEVICEID;

        caps = &read_map(g_in_map, uDeviceID)->in_caps;
    }

    memcpy(lpCaps, caps, min(uSize, sizeof(*lpCaps)));

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				waveInGetDevCapsA 		[WINMM.@]
 */
UINT WINAPI waveInGetDevCapsA(UINT_PTR uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSize)
{
    UINT ret;
    WAVEINCAPSW wicW;

    TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);

    if(!lpCaps)
        return MMSYSERR_INVALPARAM;

    ret = waveInGetDevCapsW(uDeviceID, &wicW, sizeof(wicW));

    if (ret == MMSYSERR_NOERROR) {
	WAVEINCAPSA wicA;
	wicA.wMid           = wicW.wMid;
	wicA.wPid           = wicW.wPid;
	wicA.vDriverVersion = wicW.vDriverVersion;
        WideCharToMultiByte( CP_ACP, 0, wicW.szPname, -1, wicA.szPname,
                             sizeof(wicA.szPname), NULL, NULL );
	wicA.dwFormats      = wicW.dwFormats;
	wicA.wChannels      = wicW.wChannels;
	memcpy(lpCaps, &wicA, min(uSize, sizeof(wicA)));
    }
    return ret;
}

/**************************************************************************
 * 				waveInOpen			[WINMM.@]
 */
MMRESULT WINAPI waveInOpen(HWAVEIN* lphWaveIn, UINT uDeviceID,
                           LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback,
                           DWORD_PTR dwInstance, DWORD dwFlags)
{
    LRESULT res;
    WINMM_OpenInfo info;
    WINMM_CBInfo cb_info;

    TRACE("(%p, %x, %p, %lx, %lx, %08x)\n", lphWaveIn, uDeviceID, lpFormat,
            dwCallback, dwInstance, dwFlags);

    if(!lphWaveIn && !(dwFlags & WAVE_FORMAT_QUERY))
        return MMSYSERR_INVALPARAM;

    res = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
    if(res != MMSYSERR_NOERROR)
        return res;

    if(!WINMM_StartDevicesThread())
        return MMSYSERR_NODRIVER;

    info.handle = 0;
    info.format = (WAVEFORMATEX*)lpFormat;
    info.callback = dwCallback;
    info.cb_user = dwInstance;
    info.req_device = uDeviceID;
    info.flags = dwFlags;
    info.reset = TRUE;

    res = SendMessageW(g_devices_hwnd, WIDM_OPEN, (DWORD_PTR)&info, 0);
    InterlockedDecrement(&g_devthread_token);
    if(res != MMSYSERR_NOERROR || (dwFlags & WAVE_FORMAT_QUERY))
        return res;

    if(lphWaveIn)
        *lphWaveIn = (HWAVEIN)info.handle;

    cb_info.flags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
    cb_info.callback = dwCallback;
    cb_info.user = dwInstance;
    cb_info.hwave = info.handle;

    WINMM_NotifyClient(&cb_info, WIM_OPEN, 0, 0);

    return res;
}

/**************************************************************************
 * 				waveInClose			[WINMM.@]
 */
UINT WINAPI waveInClose(HWAVEIN hWaveIn)
{
    WINMM_Device *device;
    WINMM_CBInfo cb_info;
    UINT res;

    TRACE("(%p)\n", hWaveIn);

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveIn);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    cb_info = device->cb_info;

    LeaveCriticalSection(&device->lock);

    res = SendMessageW(g_devices_hwnd, WIDM_CLOSE, (WPARAM)hWaveIn, 0);

    if(res == MMSYSERR_NOERROR)
        WINMM_NotifyClient(&cb_info, WIM_CLOSE, 0, 0);

    return res;
}

/**************************************************************************
 * 				waveInPrepareHeader		[WINMM.@]
 */
UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
				UINT uSize)
{
    TRACE("(%p, %p, %u)\n", hWaveIn, lpWaveInHdr, uSize);

    if(!lpWaveInHdr || uSize < sizeof(WAVEHDR))
        return MMSYSERR_INVALPARAM;

    if(lpWaveInHdr->dwFlags & WHDR_PREPARED)
        return MMSYSERR_NOERROR;

    return WINMM_PrepareHeader((HWAVE)hWaveIn, lpWaveInHdr);
}

/**************************************************************************
 * 				waveInUnprepareHeader	[WINMM.@]
 */
UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
				  UINT uSize)
{
    TRACE("(%p, %p, %u)\n", hWaveIn, lpWaveInHdr, uSize);

    if(!lpWaveInHdr || uSize < sizeof(WAVEHDR))
        return MMSYSERR_INVALPARAM;

    if(lpWaveInHdr->dwFlags & WHDR_INQUEUE)
        return WAVERR_STILLPLAYING;

    if(!(lpWaveInHdr->dwFlags & WHDR_PREPARED))
        return MMSYSERR_NOERROR;

    return WINMM_UnprepareHeader((HWAVE)hWaveIn, lpWaveInHdr);
}

/**************************************************************************
 * 				waveInAddBuffer		[WINMM.@]
 */
UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn, WAVEHDR *header, UINT uSize)
{
    WINMM_Device *device;

    TRACE("(%p, %p, %u)\n", hWaveIn, header, uSize);

    if(!header || uSize < sizeof(WAVEHDR))
        return MMSYSERR_INVALPARAM;

    if(!(header->dwFlags & WHDR_PREPARED))
        return WAVERR_UNPREPARED;

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveIn);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    if(!device->first)
        device->first = device->last = header;
    else{
        device->last->lpNext = header;
        device->last = header;
    }

    header->dwBytesRecorded = 0;
    header->lpNext = NULL;
    header->dwFlags &= ~WHDR_DONE;
    header->dwFlags |= WHDR_INQUEUE;

    LeaveCriticalSection(&device->lock);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				waveInReset		[WINMM.@]
 */
UINT WINAPI waveInReset(HWAVEIN hWaveIn)
{
    TRACE("(%p)\n", hWaveIn);

    return WINMM_Reset((HWAVE)hWaveIn);
}

/**************************************************************************
 * 				waveInStart		[WINMM.@]
 */
UINT WINAPI waveInStart(HWAVEIN hWaveIn)
{
    WINMM_Device *device;
    MMRESULT mr;

    TRACE("(%p)\n", hWaveIn);

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveIn);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    mr = WINMM_BeginPlaying(device);

    LeaveCriticalSection(&device->lock);

    return mr;
}

/**************************************************************************
 * 				waveInStop		[WINMM.@]
 */
UINT WINAPI waveInStop(HWAVEIN hWaveIn)
{
    WINMM_CBInfo cb_info;
    WINMM_Device *device;
    WAVEHDR *buf;
    HRESULT hr;

    TRACE("(%p)\n", hWaveIn);

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveIn);

    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    hr = WINMM_Pause((HWAVE)hWaveIn);
    if(FAILED(hr)){
        LeaveCriticalSection(&device->lock);
        return MMSYSERR_ERROR;
    }
    device->stopped = TRUE;

    buf = device->first;
    if(buf && buf->dwBytesRecorded > 0){
        device->first = buf->lpNext;
    }else
        buf = NULL;

    cb_info = device->cb_info;

    LeaveCriticalSection(&device->lock);

    if(buf){
        buf->dwFlags &= ~WHDR_INQUEUE;
        buf->dwFlags |= WHDR_DONE;
        WINMM_NotifyClient(&cb_info, WIM_DATA, (DWORD_PTR)buf, 0);
    }

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				waveInGetPosition	[WINMM.@]
 */
UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, LPMMTIME lpTime,
			      UINT uSize)
{
    TRACE("(%p, %p, %u)\n", hWaveIn, lpTime, uSize);

    if(!uSize || !lpTime)
        return MMSYSERR_INVALPARAM;

    if(uSize < sizeof(MMTIME))
        return MMSYSERR_ERROR;

    return WINMM_GetPosition((HWAVE)hWaveIn, lpTime);
}

/**************************************************************************
 * 				waveInGetID			[WINMM.@]
 */
UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT* lpuDeviceID)
{
    UINT dev, junk;
    BOOL is_out;
    WINMM_Device *device;

    TRACE("(%p, %p)\n", hWaveIn, lpuDeviceID);

    if(!lpuDeviceID)
        return MMSYSERR_INVALPARAM;

    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveIn);
    if(!WINMM_ValidateAndLock(device))
        return MMSYSERR_INVALHANDLE;

    LeaveCriticalSection(&device->lock);

    WINMM_DecomposeHWAVE((HWAVE)hWaveIn, lpuDeviceID, &is_out, &dev, &junk);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				waveInMessage 		[WINMM.@]
 */
UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage,
                          DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
    TRACE("(%p, %u, %ld, %ld)\n", hWaveIn, uMessage, dwParam1, dwParam2);

    switch(uMessage){
    case DRV_QUERYFUNCTIONINSTANCEIDSIZE:
        return WINMM_QueryInstanceIDSize(HandleToULong(hWaveIn),
                (DWORD_PTR*)dwParam1, FALSE);
    case DRV_QUERYFUNCTIONINSTANCEID:
        return WINMM_QueryInstanceID(HandleToULong(hWaveIn), (WCHAR*)dwParam1, dwParam2, FALSE);
    case DRV_QUERYDEVICEINTERFACESIZE:
        return get_device_interface(DRV_QUERYDEVICEINTERFACESIZE, FALSE, HandleToULong(hWaveIn),
                NULL, (ULONG*)dwParam1);
    case DRV_QUERYDEVICEINTERFACE:
        {
            ULONG size = dwParam2;
            return get_device_interface(DRV_QUERYDEVICEINTERFACE, FALSE, HandleToULong(hWaveIn),
                    (WCHAR*)dwParam1, &size);
        }
    case DRV_QUERYMAPPABLE:
        return MMSYSERR_NOERROR;
    case DRVM_MAPPER_PREFERRED_GET:
        if(dwParam1) {
            if(g_inmmdevices_count > 0)
                /* Device 0 is always the default device */
                *(DWORD *)dwParam1 = 0;
            else
                *(DWORD *)dwParam1 = -1;
        }

        if(dwParam2)
            /* Status flags */
            *(DWORD *)dwParam2 = 0;

        return MMSYSERR_NOERROR;
    }

    TRACE("Message not supported: %u\n", uMessage);

    return MMSYSERR_NOTSUPPORTED;
}

UINT WINAPI mixerGetNumDevs(void)
{
    HRESULT hr;

    TRACE("\n");

    hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return 0;

    return g_outmmdevices_count + g_inmmdevices_count;
}

/**************************************************************************
 * 				mixerGetDevCapsA		[WINMM.@]
 */
UINT WINAPI mixerGetDevCapsA(UINT_PTR uDeviceID, LPMIXERCAPSA lpCaps, UINT uSize)
{
    MIXERCAPSW micW;
    UINT       ret;

    TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);

    if(!lpCaps)
        return MMSYSERR_INVALPARAM;

    ret = mixerGetDevCapsW(uDeviceID, &micW, sizeof(micW));

    if (ret == MMSYSERR_NOERROR) {
        MIXERCAPSA micA;
        micA.wMid           = micW.wMid;
        micA.wPid           = micW.wPid;
        micA.vDriverVersion = micW.vDriverVersion;
        WideCharToMultiByte( CP_ACP, 0, micW.szPname, -1, micA.szPname,
                             sizeof(micA.szPname), NULL, NULL );
        micA.fdwSupport     = micW.fdwSupport;
        micA.cDestinations  = micW.cDestinations;
        memcpy(lpCaps, &micA, min(uSize, sizeof(micA)));
    }
    return ret;
}

/**************************************************************************
 * 				mixerGetDevCapsW		[WINMM.@]
 */
UINT WINAPI mixerGetDevCapsW(UINT_PTR uDeviceID, LPMIXERCAPSW lpCaps, UINT uSize)
{
    WINMM_MMDevice *mmdevice;
    MIXERCAPSW caps;
    HRESULT hr;

    TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);

    hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return MMSYSERR_NODRIVER;

    if(!lpCaps)
        return MMSYSERR_INVALPARAM;

    if(!uSize)
        return MMSYSERR_NOERROR;

    if(uDeviceID >= g_outmmdevices_count + g_inmmdevices_count)
        mmdevice = WINMM_GetMixerMMDevice((HMIXEROBJ)uDeviceID,
                MIXER_OBJECTF_MIXER, NULL);
    else if(uDeviceID < g_outmmdevices_count)
        mmdevice = read_map(g_out_map, uDeviceID);
    else
        mmdevice = read_map(g_in_map, uDeviceID - g_outmmdevices_count);

    if(!mmdevice)
        return MMSYSERR_BADDEVICEID;

    if(mmdevice->dataflow == eRender)
        memcpy(caps.szPname, mmdevice->out_caps.szPname, sizeof(caps.szPname));
    else
        memcpy(caps.szPname, mmdevice->in_caps.szPname, sizeof(caps.szPname));

    caps.wMid = 0xFF;
    caps.wPid = 0xFF;
    caps.vDriverVersion = 0x00010001;
    caps.fdwSupport = 0;
    caps.cDestinations = 1;

    memcpy(lpCaps, &caps, uSize);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mixerOpen			[WINMM.@]
 */
UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback,
                      DWORD_PTR dwInstance, DWORD fdwOpen)
{
    WINMM_MMDevice *mmdevice;
    MMRESULT mr;
    HRESULT hr;

    TRACE("(%p, %d, %lx, %lx, %x)\n", lphMix, uDeviceID, dwCallback,
            dwInstance, fdwOpen);

    hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return MMSYSERR_NODRIVER;

    if(!lphMix)
        return MMSYSERR_INVALPARAM;

    mr = WINMM_CheckCallback(dwCallback, fdwOpen, TRUE);
    if(mr != MMSYSERR_NOERROR)
        return mr;

    if(uDeviceID >= g_outmmdevices_count + g_inmmdevices_count)
        return MMSYSERR_BADDEVICEID;

    if(uDeviceID < g_outmmdevices_count){
        mmdevice = read_map(g_out_map, uDeviceID);
        *lphMix = (HMIXER)WINMM_MakeHWAVE(uDeviceID, TRUE,
                mmdevice->mixer_count);
    }else{
        mmdevice = read_map(g_in_map, uDeviceID - g_outmmdevices_count);
        *lphMix = (HMIXER)WINMM_MakeHWAVE(uDeviceID - g_outmmdevices_count,
                FALSE, mmdevice->mixer_count);
    }

    ++mmdevice->mixer_count;

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mixerClose			[WINMM.@]
 */
UINT WINAPI mixerClose(HMIXER hMix)
{
    TRACE("(%p)\n", hMix);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mixerGetID			[WINMM.@]
 */
UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID)
{
    WINMM_MMDevice *mmdevice;
    HRESULT hr;

    TRACE("(%p, %p, %x)\n", hmix, lpid, fdwID);

    hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return MMSYSERR_NODRIVER;

    if(!lpid)
        return MMSYSERR_INVALPARAM;

    mmdevice = WINMM_GetMixerMMDevice(hmix, fdwID, lpid);
    if(!mmdevice)
        return MMSYSERR_INVALHANDLE;

    if(mmdevice->in_caps.szPname[0] != '\0')
        *lpid += g_outmmdevices_count;

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mixerGetControlDetailsW		[WINMM.@]
 */
UINT WINAPI mixerGetControlDetailsW(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdW,
				    DWORD fdwDetails)
{
    WINMM_ControlDetails details;

    TRACE("(%p, %p, %x)\n", hmix, lpmcdW, fdwDetails);

    if(!WINMM_StartDevicesThread())
        return MMSYSERR_NODRIVER;

    if(!lpmcdW || !lpmcdW->paDetails)
        return MMSYSERR_INVALPARAM;

    TRACE("dwControlID: %u\n", lpmcdW->dwControlID);

    details.hmix = hmix;
    details.details = lpmcdW;
    details.flags = fdwDetails;

    return SendMessageW(g_devices_hwnd, MXDM_GETCONTROLDETAILS,
            (DWORD_PTR)&details, 0);
}

/**************************************************************************
 * 				mixerGetControlDetailsA	[WINMM.@]
 */
UINT WINAPI mixerGetControlDetailsA(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA,
                                    DWORD fdwDetails)
{
    UINT ret = MMSYSERR_NOTSUPPORTED;

    TRACE("(%p, %p, %08x)\n", hmix, lpmcdA, fdwDetails);

    if (lpmcdA == NULL || lpmcdA->cbStruct != sizeof(*lpmcdA))
	return MMSYSERR_INVALPARAM;

    switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
    case MIXER_GETCONTROLDETAILSF_VALUE:
	/* can safely use A structure as it is, no string inside */
	ret = mixerGetControlDetailsW(hmix, lpmcdA, fdwDetails);
	break;
    case MIXER_GETCONTROLDETAILSF_LISTTEXT:
	{
            MIXERCONTROLDETAILS_LISTTEXTA *pDetailsA = lpmcdA->paDetails;
            MIXERCONTROLDETAILS_LISTTEXTW *pDetailsW;
	    int size = max(1, lpmcdA->cChannels) * sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
            unsigned int i;

	    if (lpmcdA->u.cMultipleItems != 0) {
		size *= lpmcdA->u.cMultipleItems;
	    }
	    pDetailsW = HeapAlloc(GetProcessHeap(), 0, size);
            lpmcdA->paDetails = pDetailsW;
            lpmcdA->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
	    /* set up lpmcd->paDetails */
	    ret = mixerGetControlDetailsW(hmix, lpmcdA, fdwDetails);
	    /* copy from lpmcd->paDetails back to paDetailsW; */
            if (ret == MMSYSERR_NOERROR) {
                for (i = 0; i < lpmcdA->u.cMultipleItems * lpmcdA->cChannels; i++) {
                    pDetailsA->dwParam1 = pDetailsW->dwParam1;
                    pDetailsA->dwParam2 = pDetailsW->dwParam2;
                    WideCharToMultiByte( CP_ACP, 0, pDetailsW->szName, -1,
                                         pDetailsA->szName,
                                         sizeof(pDetailsA->szName), NULL, NULL );
                    pDetailsA++;
                    pDetailsW++;
                }
                pDetailsA -= lpmcdA->u.cMultipleItems * lpmcdA->cChannels;
                pDetailsW -= lpmcdA->u.cMultipleItems * lpmcdA->cChannels;
            }
	    HeapFree(GetProcessHeap(), 0, pDetailsW);
	    lpmcdA->paDetails = pDetailsA;
            lpmcdA->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
	}
	break;
    default:
	WARN("Unsupported fdwDetails=0x%08x\n", fdwDetails);
    }

    return ret;
}

/**************************************************************************
 * 				mixerGetLineControlsA	[WINMM.@]
 */
UINT WINAPI mixerGetLineControlsA(HMIXEROBJ hmix, LPMIXERLINECONTROLSA lpmlcA,
				  DWORD fdwControls)
{
    MIXERLINECONTROLSW	mlcW;
    DWORD		ret;
    unsigned int	i;

    TRACE("(%p, %p, %x)\n", hmix, lpmlcA, fdwControls);

    if (lpmlcA == NULL || lpmlcA->cbStruct != sizeof(*lpmlcA) ||
	lpmlcA->cbmxctrl != sizeof(MIXERCONTROLA))
	return MMSYSERR_INVALPARAM;

    mlcW.cbStruct = sizeof(mlcW);
    mlcW.dwLineID = lpmlcA->dwLineID;
    mlcW.u.dwControlID = lpmlcA->u.dwControlID;
    mlcW.u.dwControlType = lpmlcA->u.dwControlType;

    /* Debugging on Windows shows for MIXER_GETLINECONTROLSF_ONEBYTYPE only,
       the control count is assumed to be 1 - This is relied upon by a game,
       "Dynomite Deluze"                                                    */
    if (MIXER_GETLINECONTROLSF_ONEBYTYPE == (fdwControls & MIXER_GETLINECONTROLSF_QUERYMASK)) {
        mlcW.cControls = 1;
    } else {
        mlcW.cControls = lpmlcA->cControls;
    }
    mlcW.cbmxctrl = sizeof(MIXERCONTROLW);
    mlcW.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
			      mlcW.cControls * mlcW.cbmxctrl);

    ret = mixerGetLineControlsW(hmix, &mlcW, fdwControls);

    if (ret == MMSYSERR_NOERROR) {
	lpmlcA->dwLineID = mlcW.dwLineID;
	lpmlcA->u.dwControlID = mlcW.u.dwControlID;
	lpmlcA->u.dwControlType = mlcW.u.dwControlType;

	for (i = 0; i < mlcW.cControls; i++) {
	    lpmlcA->pamxctrl[i].cbStruct = sizeof(MIXERCONTROLA);
	    lpmlcA->pamxctrl[i].dwControlID = mlcW.pamxctrl[i].dwControlID;
	    lpmlcA->pamxctrl[i].dwControlType = mlcW.pamxctrl[i].dwControlType;
	    lpmlcA->pamxctrl[i].fdwControl = mlcW.pamxctrl[i].fdwControl;
	    lpmlcA->pamxctrl[i].cMultipleItems = mlcW.pamxctrl[i].cMultipleItems;
            WideCharToMultiByte( CP_ACP, 0, mlcW.pamxctrl[i].szShortName, -1,
                                 lpmlcA->pamxctrl[i].szShortName,
                                 sizeof(lpmlcA->pamxctrl[i].szShortName), NULL, NULL );
            WideCharToMultiByte( CP_ACP, 0, mlcW.pamxctrl[i].szName, -1,
                                 lpmlcA->pamxctrl[i].szName,
                                 sizeof(lpmlcA->pamxctrl[i].szName), NULL, NULL );
	    /* sizeof(lpmlcA->pamxctrl[i].Bounds) ==
	     * sizeof(mlcW.pamxctrl[i].Bounds) */
	    memcpy(&lpmlcA->pamxctrl[i].Bounds, &mlcW.pamxctrl[i].Bounds,
		   sizeof(mlcW.pamxctrl[i].Bounds));
	    /* sizeof(lpmlcA->pamxctrl[i].Metrics) ==
	     * sizeof(mlcW.pamxctrl[i].Metrics) */
	    memcpy(&lpmlcA->pamxctrl[i].Metrics, &mlcW.pamxctrl[i].Metrics,
		   sizeof(mlcW.pamxctrl[i].Metrics));
	}
    }

    HeapFree(GetProcessHeap(), 0, mlcW.pamxctrl);

    return ret;
}

static UINT WINMM_GetVolumeLineControl(WINMM_MMDevice *mmdevice, DWORD line,
        MIXERCONTROLW *ctl, DWORD flags)
{
    ctl->dwControlID = (line == 0xFFFF0000) ? 0 : 2;
    ctl->dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
    ctl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM;
    ctl->cMultipleItems = 0;
    LoadStringW(hWinMM32Instance, IDS_VOLUME, ctl->szShortName, MIXER_SHORT_NAME_CHARS);
    LoadStringW(hWinMM32Instance, IDS_VOLUME, ctl->szName, MIXER_LONG_NAME_CHARS);
    ctl->Bounds.s1.dwMinimum = 0;
    ctl->Bounds.s1.dwMaximum = 0xFFFF;
    ctl->Metrics.cSteps = 192;

    return MMSYSERR_NOERROR;
}

static UINT WINMM_GetMuteLineControl(WINMM_MMDevice *mmdevice, DWORD line,
        MIXERCONTROLW *ctl, DWORD flags)
{
    ctl->dwControlID = (line == 0xFFFF0000) ? 1 : 3;
    ctl->dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
    ctl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM;
    ctl->cMultipleItems = 0;
    LoadStringW(hWinMM32Instance, IDS_MUTE, ctl->szShortName, MIXER_SHORT_NAME_CHARS);
    LoadStringW(hWinMM32Instance, IDS_MUTE, ctl->szName, MIXER_LONG_NAME_CHARS);
    ctl->Bounds.s1.dwMinimum = 0;
    ctl->Bounds.s1.dwMaximum = 1;
    ctl->Metrics.cSteps = 0;

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mixerGetLineControlsW		[WINMM.@]
 */
UINT WINAPI mixerGetLineControlsW(HMIXEROBJ hmix, LPMIXERLINECONTROLSW lpmlcW,
				  DWORD fdwControls)
{
    WINMM_MMDevice *mmdevice;
    HRESULT hr;

    TRACE("(%p, %p, %08x)\n", hmix, lpmlcW, fdwControls);

    hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return MMSYSERR_NODRIVER;

    if(fdwControls & ~(MIXER_GETLINECONTROLSF_ALL |
                MIXER_GETLINECONTROLSF_ONEBYID |
                MIXER_GETLINECONTROLSF_ONEBYTYPE |
                MIXER_OBJECTF_HMIXER |
                MIXER_OBJECTF_MIXER)){
        WARN("Unknown GetLineControls flag: %x\n", fdwControls);
        return MMSYSERR_INVALFLAG;
    }

    if(!lpmlcW || lpmlcW->cbStruct < sizeof(*lpmlcW) || !lpmlcW->pamxctrl)
        return MMSYSERR_INVALPARAM;

    TRACE("dwLineID: %u\n", lpmlcW->dwLineID);
    TRACE("dwControl: %x\n", lpmlcW->u.dwControlID);
    TRACE("cControls: %u\n", lpmlcW->cControls);

    mmdevice = WINMM_GetMixerMMDevice(hmix, fdwControls, NULL);
    if(!mmdevice)
        return MMSYSERR_INVALHANDLE;

    switch(fdwControls & MIXER_GETLINECONTROLSF_QUERYMASK){
    case MIXER_GETLINECONTROLSF_ALL:
        if(lpmlcW->cControls != 2)
            return MMSYSERR_INVALPARAM;
        if(lpmlcW->cbmxctrl < sizeof(MIXERCONTROLW))
            return MMSYSERR_INVALPARAM;
        if(lpmlcW->dwLineID != 0 && lpmlcW->dwLineID != 0xFFFF0000)
            return MIXERR_INVALLINE;
        WINMM_GetVolumeLineControl(mmdevice, lpmlcW->dwLineID,
                &lpmlcW->pamxctrl[0], fdwControls);
        WINMM_GetMuteLineControl(mmdevice, lpmlcW->dwLineID,
                &lpmlcW->pamxctrl[1], fdwControls);
        return MMSYSERR_NOERROR;
    case MIXER_GETLINECONTROLSF_ONEBYID:
        if(lpmlcW->cControls != 1)
            return MMSYSERR_INVALPARAM;
        if(lpmlcW->cbmxctrl < sizeof(MIXERCONTROLW))
            return MMSYSERR_INVALPARAM;
        if(lpmlcW->dwLineID != 0 && lpmlcW->dwLineID != 0xFFFF0000)
            return MIXERR_INVALLINE;
        if(lpmlcW->u.dwControlID == 0)
            return WINMM_GetVolumeLineControl(mmdevice, lpmlcW->dwLineID,
                    lpmlcW->pamxctrl, fdwControls);
        if(lpmlcW->u.dwControlID == 1)
            return WINMM_GetMuteLineControl(mmdevice, lpmlcW->dwLineID,
                    lpmlcW->pamxctrl, fdwControls);
        return MMSYSERR_NOTSUPPORTED;
    case MIXER_GETLINECONTROLSF_ONEBYTYPE:
        if(lpmlcW->cControls != 1)
            return MMSYSERR_INVALPARAM;
        if(lpmlcW->cbmxctrl < sizeof(MIXERCONTROLW))
            return MMSYSERR_INVALPARAM;
        if(lpmlcW->dwLineID != 0 && lpmlcW->dwLineID != 0xFFFF0000)
            return MIXERR_INVALLINE;
        if(lpmlcW->u.dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
            return WINMM_GetVolumeLineControl(mmdevice, lpmlcW->dwLineID,
                    lpmlcW->pamxctrl, fdwControls);
        if(lpmlcW->u.dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
            return WINMM_GetMuteLineControl(mmdevice, lpmlcW->dwLineID,
                    lpmlcW->pamxctrl, fdwControls);
        return MMSYSERR_NOTSUPPORTED;
    }

    return MMSYSERR_NOTSUPPORTED;
}

static UINT WINMM_GetSourceLineInfo(WINMM_MMDevice *mmdevice, UINT mmdev_index,
        MIXERLINEW *info, DWORD flags)
{
    BOOL is_out = TRUE;
    if(mmdevice->in_caps.szPname[0] != '\0')
        is_out = FALSE;

    if(info->dwSource != 0)
        return MIXERR_INVALLINE;

    info->dwDestination = 0;
    info->dwLineID = 0;
    info->fdwLine = MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE;
    info->cConnections = 0;
    info->cControls = 2;
    /* volume & mute always affect all channels, so claim 1 channel */
    info->cChannels = 1;
    info->Target.dwDeviceID = mmdev_index;
    info->Target.wMid = ~0;
    info->Target.wPid = ~0;
    info->Target.vDriverVersion = 0;

    LoadStringW(hWinMM32Instance, IDS_VOLUME, info->szShortName, MIXER_SHORT_NAME_CHARS);
    LoadStringW(hWinMM32Instance, IDS_MASTER_VOLUME, info->szName, MIXER_LONG_NAME_CHARS);

    if(is_out){
        info->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
        info->Target.dwType = MIXERLINE_TARGETTYPE_WAVEOUT;
        memcpy(info->Target.szPname, mmdevice->out_caps.szPname,
                sizeof(info->Target.szPname));
    }else{
        info->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
        info->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
        info->Target.szPname[0] = '\0';
    }

    return MMSYSERR_NOERROR;
}

static UINT WINMM_GetDestinationLineInfo(WINMM_MMDevice *mmdevice,
        UINT mmdev_index, MIXERLINEW *info, DWORD flags)
{
    BOOL is_out = TRUE;
    if(mmdevice->in_caps.szPname[0] != '\0')
        is_out = FALSE;

    if(info->dwDestination != 0)
        return MIXERR_INVALLINE;

    info->dwSource = 0xFFFFFFFF;
    info->dwLineID = 0xFFFF0000;
    info->fdwLine = MIXERLINE_LINEF_ACTIVE;
    info->cConnections = 1;
    info->cControls = 2;

    LoadStringW(hWinMM32Instance, IDS_VOLUME, info->szShortName, MIXER_SHORT_NAME_CHARS);
    LoadStringW(hWinMM32Instance, IDS_MASTER_VOLUME, info->szName, MIXER_LONG_NAME_CHARS);

    info->Target.dwDeviceID = mmdev_index;
    info->Target.wMid = ~0;
    info->Target.wPid = ~0;
    info->Target.vDriverVersion = 0;

    if(is_out){
        info->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
        info->cChannels = mmdevice->out_caps.wChannels;
        info->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
        info->Target.szPname[0] = '\0';
    }else{
        info->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
        info->cChannels = mmdevice->in_caps.wChannels;
        info->Target.dwType = MIXERLINE_TARGETTYPE_WAVEIN;
        memcpy(info->Target.szPname, mmdevice->in_caps.szPname,
                sizeof(info->Target.szPname));
    }

    return MMSYSERR_NOERROR;
}

static UINT WINMM_GetComponentTypeLineInfo(WINMM_MMDevice *mmdevice,
        UINT mmdev_index, MIXERLINEW *info, DWORD flags)
{
    BOOL is_out = TRUE;
    if(mmdevice->in_caps.szPname[0] != '\0')
        is_out = FALSE;

    if(info->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_WAVEIN){
        if(is_out)
            return MIXERR_INVALLINE;
        info->dwDestination = 0;
        return WINMM_GetDestinationLineInfo(mmdevice, mmdev_index, info, flags);
    }

    if(info->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS){
        if(!is_out)
            return MIXERR_INVALLINE;
        info->dwDestination = 0;
        return WINMM_GetDestinationLineInfo(mmdevice, mmdev_index, info, flags);
    }

    if(info->dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE){
        if(is_out)
            return MIXERR_INVALLINE;
        info->dwSource = 0;
        return WINMM_GetSourceLineInfo(mmdevice, mmdev_index, info, flags);
    }

    if(info->dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT){
        if(!is_out)
            return MIXERR_INVALLINE;
        info->dwSource = 0;
        return WINMM_GetSourceLineInfo(mmdevice, mmdev_index, info, flags);
    }

    TRACE("Returning INVALLINE on this component type: %u\n",
            info->dwComponentType);

    return MIXERR_INVALLINE;
}

static UINT WINMM_GetLineIDLineInfo(WINMM_MMDevice *mmdevice,
        UINT mmdev_index, MIXERLINEW *info, DWORD flags)
{
    if(info->dwLineID == 0xFFFF0000){
        info->dwDestination = 0;
        return WINMM_GetDestinationLineInfo(mmdevice, mmdev_index, info, flags);
    }

    if(info->dwLineID == 0){
        info->dwSource = 0;
        return WINMM_GetSourceLineInfo(mmdevice, mmdev_index, info, flags);
    }

    TRACE("Returning INVALLINE on this dwLineID: %u\n", info->dwLineID);
    return MIXERR_INVALLINE;
}

/**************************************************************************
 * 				mixerGetLineInfoW		[WINMM.@]
 */
UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW, DWORD fdwInfo)
{
    UINT mmdev_index;
    WINMM_MMDevice *mmdevice;
    HRESULT hr;

    TRACE("(%p, %p, %x)\n", hmix, lpmliW, fdwInfo);

    hr = WINMM_InitMMDevices();
    if(FAILED(hr))
        return MMSYSERR_NODRIVER;

    if(!lpmliW || lpmliW->cbStruct < sizeof(MIXERLINEW))
        return MMSYSERR_INVALPARAM;

    TRACE("dwDestination: %u\n", lpmliW->dwDestination);
    TRACE("dwSource: %u\n", lpmliW->dwSource);
    TRACE("dwLineID: %u\n", lpmliW->dwLineID);
    TRACE("fdwLine: 0x%x\n", lpmliW->fdwLine);
    TRACE("dwComponentType: 0x%x\n", lpmliW->dwComponentType);

    if(fdwInfo & ~(MIXER_GETLINEINFOF_COMPONENTTYPE |
                MIXER_GETLINEINFOF_DESTINATION |
                MIXER_GETLINEINFOF_LINEID |
                MIXER_GETLINEINFOF_SOURCE |
                MIXER_GETLINEINFOF_TARGETTYPE |
                MIXER_OBJECTF_HMIXER |
                MIXER_OBJECTF_MIXER)){
        WARN("Unknown GetLineInfo flag: %x\n", fdwInfo);
        return MMSYSERR_INVALFLAG;
    }

    mmdevice = WINMM_GetMixerMMDevice(hmix, fdwInfo, &mmdev_index);
    if(!mmdevice)
        return MMSYSERR_INVALHANDLE;

    switch(fdwInfo & MIXER_GETLINEINFOF_QUERYMASK){
    case MIXER_GETLINEINFOF_DESTINATION:
        return WINMM_GetDestinationLineInfo(mmdevice, mmdev_index, lpmliW,
                fdwInfo);
    case MIXER_GETLINEINFOF_SOURCE:
        return WINMM_GetSourceLineInfo(mmdevice, mmdev_index, lpmliW, fdwInfo);
    case MIXER_GETLINEINFOF_COMPONENTTYPE:
        return WINMM_GetComponentTypeLineInfo(mmdevice, mmdev_index, lpmliW,
                fdwInfo);
    case MIXER_GETLINEINFOF_LINEID:
        return WINMM_GetLineIDLineInfo(mmdevice, mmdev_index, lpmliW, fdwInfo);
    case MIXER_GETLINEINFOF_TARGETTYPE:
        FIXME("TARGETTYPE flag not implemented!\n");
        return MIXERR_INVALLINE;
    }

    TRACE("Returning INVALFLAG on these flags: %x\n", fdwInfo);
    return MMSYSERR_INVALFLAG;
}

/**************************************************************************
 * 				mixerGetLineInfoA		[WINMM.@]
 */
UINT WINAPI mixerGetLineInfoA(HMIXEROBJ hmix, LPMIXERLINEA lpmliA,
			      DWORD fdwInfo)
{
    MIXERLINEW		mliW;
    UINT		ret;

    TRACE("(%p, %p, %x)\n", hmix, lpmliA, fdwInfo);

    if (lpmliA == NULL || lpmliA->cbStruct != sizeof(*lpmliA))
	return MMSYSERR_INVALPARAM;

    mliW.cbStruct = sizeof(mliW);
    switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
    case MIXER_GETLINEINFOF_COMPONENTTYPE:
	mliW.dwComponentType = lpmliA->dwComponentType;
	break;
    case MIXER_GETLINEINFOF_DESTINATION:
	mliW.dwDestination = lpmliA->dwDestination;
	break;
    case MIXER_GETLINEINFOF_LINEID:
	mliW.dwLineID = lpmliA->dwLineID;
	break;
    case MIXER_GETLINEINFOF_SOURCE:
	mliW.dwDestination = lpmliA->dwDestination;
	mliW.dwSource = lpmliA->dwSource;
	break;
    case MIXER_GETLINEINFOF_TARGETTYPE:
	mliW.Target.dwType = lpmliA->Target.dwType;
	mliW.Target.wMid = lpmliA->Target.wMid;
	mliW.Target.wPid = lpmliA->Target.wPid;
	mliW.Target.vDriverVersion = lpmliA->Target.vDriverVersion;
        MultiByteToWideChar( CP_ACP, 0, lpmliA->Target.szPname, -1, mliW.Target.szPname, sizeof(mliW.Target.szPname)/sizeof(WCHAR));
	break;
    default:
	WARN("Unsupported fdwControls=0x%08x\n", fdwInfo);
        return MMSYSERR_INVALFLAG;
    }

    ret = mixerGetLineInfoW(hmix, &mliW, fdwInfo);

    if(ret == MMSYSERR_NOERROR)
    {
        lpmliA->dwDestination = mliW.dwDestination;
        lpmliA->dwSource = mliW.dwSource;
        lpmliA->dwLineID = mliW.dwLineID;
        lpmliA->fdwLine = mliW.fdwLine;
        lpmliA->dwUser = mliW.dwUser;
        lpmliA->dwComponentType = mliW.dwComponentType;
        lpmliA->cChannels = mliW.cChannels;
        lpmliA->cConnections = mliW.cConnections;
        lpmliA->cControls = mliW.cControls;
        WideCharToMultiByte( CP_ACP, 0, mliW.szShortName, -1, lpmliA->szShortName,
                             sizeof(lpmliA->szShortName), NULL, NULL);
        WideCharToMultiByte( CP_ACP, 0, mliW.szName, -1, lpmliA->szName,
                             sizeof(lpmliA->szName), NULL, NULL );
        lpmliA->Target.dwType = mliW.Target.dwType;
        lpmliA->Target.dwDeviceID = mliW.Target.dwDeviceID;
        lpmliA->Target.wMid = mliW.Target.wMid;
        lpmliA->Target.wPid = mliW.Target.wPid;
        lpmliA->Target.vDriverVersion = mliW.Target.vDriverVersion;
        WideCharToMultiByte( CP_ACP, 0, mliW.Target.szPname, -1, lpmliA->Target.szPname,
                             sizeof(lpmliA->Target.szPname), NULL, NULL );
    }
    return ret;
}

/**************************************************************************
 * 				mixerSetControlDetails	[WINMM.@]
 */
UINT WINAPI mixerSetControlDetails(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcd,
				   DWORD fdwDetails)
{
    WINMM_ControlDetails details;
    UINT ret;

    TRACE("(%p, %p, %x)\n", hmix, lpmcd, fdwDetails);

    if((fdwDetails & MIXER_SETCONTROLDETAILSF_QUERYMASK) ==
            MIXER_SETCONTROLDETAILSF_CUSTOM)
        return MMSYSERR_NOTSUPPORTED;

    if(!lpmcd)
        return MMSYSERR_INVALPARAM;

    if(!WINMM_StartDevicesThread())
        return MMSYSERR_NODRIVER;

    TRACE("dwControlID: %u\n", lpmcd->dwControlID);

    details.hmix = hmix;
    details.details = lpmcd;
    details.flags = fdwDetails;

    ret = SendMessageW(g_devices_hwnd, MXDM_SETCONTROLDETAILS,
            (DWORD_PTR)&details, 0);
    InterlockedDecrement(&g_devthread_token);
    return ret;
}

/**************************************************************************
 * 				mixerMessage		[WINMM.@]
 */
DWORD WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
    TRACE("(%p, %d, %lx, %lx)\n", hmix, uMsg, dwParam1, dwParam2);

    return MMSYSERR_NOTSUPPORTED;
}
