/*  			DirectSound
 *
 * Copyright 1998 Marcus Meissner
 * Copyright 1998 Rob Riggs
 * Copyright 2000-2002 TransGaming Technologies, Inc.
 *
 * 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
 *
 * Most thread locking is complete. There may be a few race
 * conditions still lurking.
 *
 * TODO:
 *	Implement SetCooperativeLevel properly (need to address focus issues)
 *	Implement DirectSound3DBuffers (stubs in place)
 *	Use hardware 3D support if available
 *      Add critical section locking inside Release and AddRef methods
 *      Handle static buffers - put those in hardware, non-static not in hardware
 *      Hardware DuplicateSoundBuffer
 *      Proper volume calculation for 3d buffers
 *      Remove DS_HEL_FRAGS and use mixer fragment length for it
 */

#include <stdarg.h>

#define COBJMACROS
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "mmsystem.h"
#include "winternl.h"
#include "mmddk.h"
#include "wine/debug.h"
#include "dsound.h"
#include "dsconf.h"
#include "ks.h"
#include "rpcproxy.h"
#include "rpc.h"
#include "rpcndr.h"
#include "unknwn.h"
#include "oleidl.h"
#include "shobjidl.h"
#include "strmif.h"

#include "initguid.h"
#include "ksmedia.h"
#include "propkey.h"
#include "devpkey.h"

#include "dsound_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(dsound);

struct list DSOUND_renderers = LIST_INIT(DSOUND_renderers);
CRITICAL_SECTION DSOUND_renderers_lock;
static CRITICAL_SECTION_DEBUG DSOUND_renderers_lock_debug =
{
    0, 0, &DSOUND_renderers_lock,
    { &DSOUND_renderers_lock_debug.ProcessLocksList, &DSOUND_renderers_lock_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": DSOUND_renderers_lock") }
};
CRITICAL_SECTION DSOUND_renderers_lock = { &DSOUND_renderers_lock_debug, -1, 0, 0, 0, 0 };

struct list DSOUND_capturers = LIST_INIT(DSOUND_capturers);
CRITICAL_SECTION DSOUND_capturers_lock;
static CRITICAL_SECTION_DEBUG DSOUND_capturers_lock_debug =
{
    0, 0, &DSOUND_capturers_lock,
    { &DSOUND_capturers_lock_debug.ProcessLocksList, &DSOUND_capturers_lock_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": DSOUND_capturers_lock") }
};
CRITICAL_SECTION DSOUND_capturers_lock = { &DSOUND_capturers_lock_debug, -1, 0, 0, 0, 0 };

GUID                    DSOUND_renderer_guids[MAXWAVEDRIVERS];
GUID                    DSOUND_capture_guids[MAXWAVEDRIVERS];

const WCHAR wine_vxd_drv[] = { 'w','i','n','e','m','m','.','v','x','d', 0 };

/* All default settings, you most likely don't want to touch these, see wiki on UsefulRegistryKeys */
int ds_hel_buflen = 32768 * 2;
static HINSTANCE instance;

/*
 * Get a config key from either the app-specific or the default config
 */

static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
                                    char *buffer, DWORD size )
{
    if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
    if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
    return ERROR_FILE_NOT_FOUND;
}


/*
 * Setup the dsound options.
 */

void setup_dsound_options(void)
{
    char buffer[MAX_PATH+16];
    HKEY hkey, appkey = 0;
    DWORD len;

    buffer[MAX_PATH]='\0';

    /* @@ Wine registry key: HKCU\Software\Wine\DirectSound */
    if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\DirectSound", &hkey )) hkey = 0;

    len = GetModuleFileNameA( 0, buffer, MAX_PATH );
    if (len && len < MAX_PATH)
    {
        HKEY tmpkey;
        /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DirectSound */
        if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
        {
            char *p, *appname = buffer;
            if ((p = strrchr( appname, '/' ))) appname = p + 1;
            if ((p = strrchr( appname, '\\' ))) appname = p + 1;
            strcat( appname, "\\DirectSound" );
            TRACE("appname = [%s]\n", appname);
            if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
            RegCloseKey( tmpkey );
        }
    }

    /* get options */

    if (!get_config_key( hkey, appkey, "HelBuflen", buffer, MAX_PATH ))
        ds_hel_buflen = atoi(buffer);

    if (appkey) RegCloseKey( appkey );
    if (hkey) RegCloseKey( hkey );

    TRACE("ds_hel_buflen = %d\n", ds_hel_buflen);
}

static const char * get_device_id(LPCGUID pGuid)
{
    if (IsEqualGUID(&DSDEVID_DefaultPlayback, pGuid))
        return "DSDEVID_DefaultPlayback";
    else if (IsEqualGUID(&DSDEVID_DefaultVoicePlayback, pGuid))
        return "DSDEVID_DefaultVoicePlayback";
    else if (IsEqualGUID(&DSDEVID_DefaultCapture, pGuid))
        return "DSDEVID_DefaultCapture";
    else if (IsEqualGUID(&DSDEVID_DefaultVoiceCapture, pGuid))
        return "DSDEVID_DefaultVoiceCapture";
    return debugstr_guid(pGuid);
}

static HRESULT get_mmdevenum(IMMDeviceEnumerator **devenum)
{
    HRESULT hr, init_hr;

    init_hr = CoInitialize(NULL);

    hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
            CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)devenum);
    if(FAILED(hr)){
        if(SUCCEEDED(init_hr))
            CoUninitialize();
        *devenum = NULL;
        ERR("CoCreateInstance failed: %08x\n", hr);
        return hr;
    }

    return init_hr;
}

static void release_mmdevenum(IMMDeviceEnumerator *devenum, HRESULT init_hr)
{
    IMMDeviceEnumerator_Release(devenum);
    if(SUCCEEDED(init_hr))
        CoUninitialize();
}

static HRESULT get_mmdevice_guid(IMMDevice *device, IPropertyStore *ps,
        GUID *guid)
{
    PROPVARIANT pv;
    HRESULT hr;

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

    PropVariantInit(&pv);

    hr = IPropertyStore_GetValue(ps, &PKEY_AudioEndpoint_GUID, &pv);
    if(FAILED(hr)){
        IPropertyStore_Release(ps);
        WARN("GetValue(GUID) failed: %08x\n", hr);
        return hr;
    }

    CLSIDFromString(pv.u.pwszVal, guid);

    PropVariantClear(&pv);
    IPropertyStore_Release(ps);

    return S_OK;
}

/***************************************************************************
 * GetDeviceID	[DSOUND.9]
 *
 * Retrieves unique identifier of default device specified
 *
 * PARAMS
 *    pGuidSrc  [I] Address of device GUID.
 *    pGuidDest [O] Address to receive unique device GUID.
 *
 * RETURNS
 *    Success: DS_OK
 *    Failure: DSERR_INVALIDPARAM
 *
 * NOTES
 *    pGuidSrc is a valid device GUID or DSDEVID_DefaultPlayback,
 *    DSDEVID_DefaultCapture, DSDEVID_DefaultVoicePlayback, or
 *    DSDEVID_DefaultVoiceCapture.
 *    Returns pGuidSrc if pGuidSrc is a valid device or the device
 *    GUID for the specified constants.
 */
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
{
    IMMDeviceEnumerator *devenum;
    EDataFlow flow = (EDataFlow)-1;
    ERole role = (ERole)-1;
    HRESULT hr, init_hr;

    TRACE("(%s,%p)\n", get_device_id(pGuidSrc),pGuidDest);

    if(!pGuidSrc || !pGuidDest)
        return DSERR_INVALIDPARAM;

    init_hr = get_mmdevenum(&devenum);
    if(!devenum)
        return init_hr;

    if(IsEqualGUID(&DSDEVID_DefaultPlayback, pGuidSrc)){
        role = eMultimedia;
        flow = eRender;
    }else if(IsEqualGUID(&DSDEVID_DefaultVoicePlayback, pGuidSrc)){
        role = eCommunications;
        flow = eRender;
    }else if(IsEqualGUID(&DSDEVID_DefaultCapture, pGuidSrc)){
        role = eMultimedia;
        flow = eCapture;
    }else if(IsEqualGUID(&DSDEVID_DefaultVoiceCapture, pGuidSrc)){
        role = eCommunications;
        flow = eCapture;
    }

    if(role != (ERole)-1 && flow != (EDataFlow)-1){
        IMMDevice *device;

        hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum,
                flow, role, &device);
        if(FAILED(hr)){
            WARN("GetDefaultAudioEndpoint failed: %08x\n", hr);
            release_mmdevenum(devenum, init_hr);
            return DSERR_NODRIVER;
        }

        hr = get_mmdevice_guid(device, NULL, pGuidDest);
        IMMDevice_Release(device);

        release_mmdevenum(devenum, init_hr);

        return (hr == S_OK) ? DS_OK : hr;
    }

    release_mmdevenum(devenum, init_hr);

    *pGuidDest = *pGuidSrc;

    return DS_OK;
}

struct morecontext
{
    LPDSENUMCALLBACKA callA;
    LPVOID data;
};

static BOOL CALLBACK a_to_w_callback(LPGUID guid, LPCWSTR descW, LPCWSTR modW, LPVOID data)
{
    struct morecontext *context = data;
    char descA[MAXPNAMELEN], modA[MAXPNAMELEN];

    WideCharToMultiByte(CP_ACP, 0, descW, -1, descA, sizeof(descA), NULL, NULL);
    WideCharToMultiByte(CP_ACP, 0, modW, -1, modA, sizeof(modA), NULL, NULL);

    return context->callA(guid, descA, modA, context->data);
}

/***************************************************************************
 * DirectSoundEnumerateA [DSOUND.2]
 *
 * Enumerate all DirectSound drivers installed in the system
 *
 * PARAMS
 *    lpDSEnumCallback  [I] Address of callback function.
 *    lpContext         [I] Address of user defined context passed to callback function.
 *
 * RETURNS
 *    Success: DS_OK
 *    Failure: DSERR_INVALIDPARAM
 */
HRESULT WINAPI DirectSoundEnumerateA(
    LPDSENUMCALLBACKA lpDSEnumCallback,
    LPVOID lpContext)
{
    struct morecontext context;

    if (lpDSEnumCallback == NULL) {
        WARN("invalid parameter: lpDSEnumCallback == NULL\n");
        return DSERR_INVALIDPARAM;
    }

    context.callA = lpDSEnumCallback;
    context.data = lpContext;

    return DirectSoundEnumerateW(a_to_w_callback, &context);
}

HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device)
{
    IMMDeviceEnumerator *devenum;
    IMMDeviceCollection *coll;
    UINT count, i;
    HRESULT hr, init_hr;

    init_hr = get_mmdevenum(&devenum);
    if(!devenum)
        return init_hr;

    hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
            DEVICE_STATE_ACTIVE, &coll);
    if(FAILED(hr)){
        WARN("EnumAudioEndpoints failed: %08x\n", hr);
        release_mmdevenum(devenum, init_hr);
        return hr;
    }

    hr = IMMDeviceCollection_GetCount(coll, &count);
    if(FAILED(hr)){
        IMMDeviceCollection_Release(coll);
        release_mmdevenum(devenum, init_hr);
        WARN("GetCount failed: %08x\n", hr);
        return hr;
    }

    for(i = 0; i < count; ++i){
        GUID guid;

        hr = IMMDeviceCollection_Item(coll, i, device);
        if(FAILED(hr))
            continue;

        hr = get_mmdevice_guid(*device, NULL, &guid);
        if(FAILED(hr)){
            IMMDevice_Release(*device);
            continue;
        }

        if(IsEqualGUID(&guid, tgt)){
            IMMDeviceCollection_Release(coll);
            release_mmdevenum(devenum, init_hr);
            return DS_OK;
        }

        IMMDevice_Release(*device);
    }

    WARN("No device with GUID %s found!\n", wine_dbgstr_guid(tgt));

    IMMDeviceCollection_Release(coll);
    release_mmdevenum(devenum, init_hr);

    return DSERR_INVALIDPARAM;
}

static BOOL send_device(IMMDevice *device, GUID *guid,
        LPDSENUMCALLBACKW cb, void *user)
{
    IPropertyStore *ps;
    PROPVARIANT pv;
    BOOL keep_going;
    HRESULT hr;

    PropVariantInit(&pv);

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

    hr = get_mmdevice_guid(device, ps, guid);
    if(FAILED(hr)){
        IPropertyStore_Release(ps);
        return TRUE;
    }

    hr = IPropertyStore_GetValue(ps,
            (const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
    if(FAILED(hr)){
        IPropertyStore_Release(ps);
        WARN("GetValue(FriendlyName) failed: %08x\n", hr);
        return TRUE;
    }

    TRACE("Calling back with %s (%s)\n", wine_dbgstr_guid(guid),
            wine_dbgstr_w(pv.u.pwszVal));

    keep_going = cb(guid, pv.u.pwszVal, wine_vxd_drv, user);

    PropVariantClear(&pv);
    IPropertyStore_Release(ps);

    return keep_going;
}

/* S_FALSE means the callback returned FALSE at some point
 * S_OK means the callback always returned TRUE */
HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
        LPDSENUMCALLBACKW cb, void *user)
{
    IMMDeviceEnumerator *devenum;
    IMMDeviceCollection *coll;
    IMMDevice *defdev = NULL;
    UINT count, i, n;
    BOOL keep_going;
    HRESULT hr, init_hr;

    static const WCHAR primary_desc[] = {'P','r','i','m','a','r','y',' ',
        'S','o','u','n','d',' ','D','r','i','v','e','r',0};
    static const WCHAR empty_drv[] = {0};

    init_hr = get_mmdevenum(&devenum);
    if(!devenum)
        return init_hr;

    hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
            DEVICE_STATE_ACTIVE, &coll);
    if(FAILED(hr)){
        release_mmdevenum(devenum, init_hr);
        WARN("EnumAudioEndpoints failed: %08x\n", hr);
        return DS_OK;
    }

    hr = IMMDeviceCollection_GetCount(coll, &count);
    if(FAILED(hr)){
        IMMDeviceCollection_Release(coll);
        release_mmdevenum(devenum, init_hr);
        WARN("GetCount failed: %08x\n", hr);
        return DS_OK;
    }

    if(count == 0){
        release_mmdevenum(devenum, init_hr);
        return DS_OK;
    }

    TRACE("Calling back with NULL (%s)\n", wine_dbgstr_w(primary_desc));
    keep_going = cb(NULL, primary_desc, empty_drv, user);

    /* always send the default device first */
    if(keep_going){
        hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, flow,
                eMultimedia, &defdev);
        if(FAILED(hr)){
            defdev = NULL;
            n = 0;
        }else{
            keep_going = send_device(defdev, &guids[0], cb, user);
            n = 1;
        }
    }

    for(i = 0; keep_going && i < count; ++i){
        IMMDevice *device;

        hr = IMMDeviceCollection_Item(coll, i, &device);
        if(FAILED(hr)){
            WARN("Item failed: %08x\n", hr);
            continue;
        }

        if(device != defdev){
            keep_going = send_device(device, &guids[n], cb, user);
            ++n;
        }

        IMMDevice_Release(device);
    }

    if(defdev)
        IMMDevice_Release(defdev);
    IMMDeviceCollection_Release(coll);

    release_mmdevenum(devenum, init_hr);

    return keep_going ? S_OK : S_FALSE;
}

/***************************************************************************
 * DirectSoundEnumerateW [DSOUND.3]
 *
 * Enumerate all DirectSound drivers installed in the system
 *
 * PARAMS
 *    lpDSEnumCallback  [I] Address of callback function.
 *    lpContext         [I] Address of user defined context passed to callback function.
 *
 * RETURNS
 *    Success: DS_OK
 *    Failure: DSERR_INVALIDPARAM
 */
HRESULT WINAPI DirectSoundEnumerateW(
	LPDSENUMCALLBACKW lpDSEnumCallback,
	LPVOID lpContext )
{
    HRESULT hr;

    TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext);

    if (lpDSEnumCallback == NULL) {
        WARN("invalid parameter: lpDSEnumCallback == NULL\n");
        return DSERR_INVALIDPARAM;
    }

    setup_dsound_options();

    hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
            lpDSEnumCallback, lpContext);
    return SUCCEEDED(hr) ? DS_OK : hr;
}

/***************************************************************************
 * DirectSoundCaptureEnumerateA [DSOUND.7]
 *
 * Enumerate all DirectSound drivers installed in the system.
 *
 * PARAMS
 *    lpDSEnumCallback  [I] Address of callback function.
 *    lpContext         [I] Address of user defined context passed to callback function.
 *
 * RETURNS
 *    Success: DS_OK
 *    Failure: DSERR_INVALIDPARAM
 */
HRESULT WINAPI DirectSoundCaptureEnumerateA(
    LPDSENUMCALLBACKA lpDSEnumCallback,
    LPVOID lpContext)
{
    struct morecontext context;

    if (lpDSEnumCallback == NULL) {
        WARN("invalid parameter: lpDSEnumCallback == NULL\n");
        return DSERR_INVALIDPARAM;
    }

    context.callA = lpDSEnumCallback;
    context.data = lpContext;

    return DirectSoundCaptureEnumerateW(a_to_w_callback, &context);
}

/***************************************************************************
 * DirectSoundCaptureEnumerateW [DSOUND.8]
 *
 * Enumerate all DirectSound drivers installed in the system.
 *
 * PARAMS
 *    lpDSEnumCallback  [I] Address of callback function.
 *    lpContext         [I] Address of user defined context passed to callback function.
 *
 * RETURNS
 *    Success: DS_OK
 *    Failure: DSERR_INVALIDPARAM
 */
HRESULT WINAPI
DirectSoundCaptureEnumerateW(
    LPDSENUMCALLBACKW lpDSEnumCallback,
    LPVOID lpContext)
{
    HRESULT hr;

    TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );

    if (lpDSEnumCallback == NULL) {
        WARN("invalid parameter: lpDSEnumCallback == NULL\n");
        return DSERR_INVALIDPARAM;
    }

    setup_dsound_options();

    hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
            lpDSEnumCallback, lpContext);
    return SUCCEEDED(hr) ? DS_OK : hr;
}

/*******************************************************************************
 * DirectSound ClassFactory
 */

typedef  HRESULT (*FnCreateInstance)(REFIID riid, LPVOID *ppobj);
 
typedef struct {
    IClassFactory IClassFactory_iface;
    REFCLSID rclsid;
    FnCreateInstance pfnCreateInstance;
} IClassFactoryImpl;

static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
{
    return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
}

static HRESULT WINAPI
DSCF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppobj)
{
    IClassFactoryImpl *This = impl_from_IClassFactory(iface);
    TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
    if (ppobj == NULL)
        return E_POINTER;
    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IClassFactory))
    {
        *ppobj = iface;
        IClassFactory_AddRef(iface);
        return S_OK;
    }
    *ppobj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
{
    return 2;
}

static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
{
    /* static class, won't be freed */
    return 1;
}

static HRESULT WINAPI DSCF_CreateInstance(
    LPCLASSFACTORY iface,
    LPUNKNOWN pOuter,
    REFIID riid,
    LPVOID *ppobj)
{
    IClassFactoryImpl *This = impl_from_IClassFactory(iface);
    TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), ppobj);

    if (pOuter)
        return CLASS_E_NOAGGREGATION;

    if (ppobj == NULL) {
        WARN("invalid parameter\n");
        return DSERR_INVALIDPARAM;
    }
    *ppobj = NULL;
    return This->pfnCreateInstance(riid, ppobj);
}
 
static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
{
    IClassFactoryImpl *This = impl_from_IClassFactory(iface);
    FIXME("(%p, %d) stub!\n", This, dolock);
    return S_OK;
}

static const IClassFactoryVtbl DSCF_Vtbl = {
    DSCF_QueryInterface,
    DSCF_AddRef,
    DSCF_Release,
    DSCF_CreateInstance,
    DSCF_LockServer
};

static IClassFactoryImpl DSOUND_CF[] = {
    { { &DSCF_Vtbl }, &CLSID_DirectSound, DSOUND_Create },
    { { &DSCF_Vtbl }, &CLSID_DirectSound8, DSOUND_Create8 },
    { { &DSCF_Vtbl }, &CLSID_DirectSoundCapture, DSOUND_CaptureCreate },
    { { &DSCF_Vtbl }, &CLSID_DirectSoundCapture8, DSOUND_CaptureCreate8 },
    { { &DSCF_Vtbl }, &CLSID_DirectSoundFullDuplex, DSOUND_FullDuplexCreate },
    { { &DSCF_Vtbl }, &CLSID_DirectSoundPrivate, IKsPrivatePropertySetImpl_Create },
    { { NULL }, NULL, NULL }
};

/*******************************************************************************
 * DllGetClassObject [DSOUND.@]
 * Retrieves class object from a DLL object
 *
 * NOTES
 *    Docs say returns STDAPI
 *
 * PARAMS
 *    rclsid [I] CLSID for the class object
 *    riid   [I] Reference to identifier of interface for class object
 *    ppv    [O] Address of variable to receive interface pointer for riid
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
 *             E_UNEXPECTED
 */
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    int i = 0;
    TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);

    if (ppv == NULL) {
        WARN("invalid parameter\n");
        return E_INVALIDARG;
    }

    *ppv = NULL;

    if (!IsEqualIID(riid, &IID_IClassFactory) &&
        !IsEqualIID(riid, &IID_IUnknown)) {
        WARN("no interface for %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    while (NULL != DSOUND_CF[i].rclsid) {
        if (IsEqualGUID(rclsid, DSOUND_CF[i].rclsid)) {
            DSCF_AddRef(&DSOUND_CF[i].IClassFactory_iface);
            *ppv = &DSOUND_CF[i];
            return S_OK;
        }
        i++;
    }

    WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid),
         debugstr_guid(riid), ppv);
    return CLASS_E_CLASSNOTAVAILABLE;
}


/*******************************************************************************
 * DllCanUnloadNow [DSOUND.4]
 * Determines whether the DLL is in use.
 *
 * RETURNS
 *    Can unload now: S_OK
 *    Cannot unload now (the DLL is still active): S_FALSE
 */
HRESULT WINAPI DllCanUnloadNow(void)
{
    return S_FALSE;
}

#define INIT_GUID(guid, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)      \
        guid.Data1 = l; guid.Data2 = w1; guid.Data3 = w2;               \
        guid.Data4[0] = b1; guid.Data4[1] = b2; guid.Data4[2] = b3;     \
        guid.Data4[3] = b4; guid.Data4[4] = b5; guid.Data4[5] = b6;     \
        guid.Data4[6] = b7; guid.Data4[7] = b8;

/***********************************************************************
 *           DllMain (DSOUND.init)
 */
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpvReserved);

    switch (fdwReason) {
    case DLL_PROCESS_ATTACH:
        instance = hInstDLL;
        DisableThreadLibraryCalls(hInstDLL);
        /* Increase refcount on dsound by 1 */
        GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)hInstDLL, &hInstDLL);
        break;
    case DLL_PROCESS_DETACH:
        if (lpvReserved) break;
        DeleteCriticalSection(&DSOUND_renderers_lock);
        DeleteCriticalSection(&DSOUND_capturers_lock);
        break;
    }
    return TRUE;
}

/***********************************************************************
 *		DllRegisterServer (DSOUND.@)
 */
HRESULT WINAPI DllRegisterServer(void)
{
    return __wine_register_resources( instance );
}

/***********************************************************************
 *		DllUnregisterServer (DSOUND.@)
 */
HRESULT WINAPI DllUnregisterServer(void)
{
    return __wine_unregister_resources( instance );
}
