[DSOUND]
[reactos.git] / reactos / dll / directx / wine / dsound / propset.c
index cb309d0..658f04a 100644 (file)
@@ -21,8 +21,6 @@
 
 #include "dsound_private.h"
 
-static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
-
 typedef struct IKsPrivatePropertySetImpl
 {
     IKsPropertySet IKsPropertySet_iface;
@@ -40,7 +38,9 @@ static IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *iface
 
 /* IUnknown methods */
 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
-        IKsPropertySet *iface, REFIID riid, void **ppobj)
+    LPKSPROPERTYSET iface,
+    REFIID riid,
+    LPVOID *ppobj )
 {
     IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
     TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
@@ -48,7 +48,7 @@ static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
     if (IsEqualIID(riid, &IID_IUnknown) ||
         IsEqualIID(riid, &IID_IKsPropertySet)) {
         *ppobj = iface;
-        IKsPropertySet_AddRef(iface);
+        IUnknown_AddRef(iface);
         return S_OK;
     }
     *ppobj = NULL;
@@ -76,61 +76,67 @@ static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
     return ref;
 }
 
-struct search_data {
-    const WCHAR *tgt_name;
-    GUID *found_guid;
-};
-
-static BOOL CALLBACK search_callback(GUID *guid, const WCHAR *desc,
-        const WCHAR *module, void *user)
-{
-    struct search_data *search = user;
-
-    if(!lstrcmpW(desc, search->tgt_name)){
-        *search->found_guid = *guid;
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
 static HRESULT DSPROPERTY_WaveDeviceMappingW(
     LPVOID pPropData,
     ULONG cbPropData,
     PULONG pcbReturned )
 {
-    HRESULT hr;
-    PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd = pPropData;
-    struct search_data search;
-
+    HRESULT hr = DSERR_INVALIDPARAM;
+    PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
-          pPropData,cbPropData,pcbReturned);
+         pPropData,cbPropData,pcbReturned);
+
+    ppd = pPropData;
 
     if (!ppd) {
-        WARN("invalid parameter: pPropData\n");
-        return DSERR_INVALIDPARAM;
+       WARN("invalid parameter: pPropData\n");
+       return DSERR_INVALIDPARAM;
     }
 
-    search.tgt_name = ppd->DeviceName;
-    search.found_guid = &ppd->DeviceId;
-
-    if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
-        hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
-                search_callback, &search);
-    else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE)
-        hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
-                search_callback, &search);
-    else
-        return DSERR_INVALIDPARAM;
-
-    if(hr != S_FALSE)
-        /* device was not found */
-        return DSERR_INVALIDPARAM;
+    if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
+        ULONG wod;
+        unsigned int wodn;
+        TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
+        wodn = waveOutGetNumDevs();
+        for (wod = 0; wod < wodn; wod++) {
+            WAVEOUTCAPSW capsW;
+            MMRESULT res;
+            res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
+            if (res == MMSYSERR_NOERROR) {
+                if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
+                    ppd->DeviceId = DSOUND_renderer_guids[wod];
+                    hr = DS_OK;
+                    TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
+                          debugstr_w(ppd->DeviceName));
+                    break;
+                }
+            }
+        }
+    } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
+        ULONG wid;
+        unsigned int widn;
+        TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
+        widn = waveInGetNumDevs();
+        for (wid = 0; wid < widn; wid++) {
+            WAVEINCAPSW capsW;
+            MMRESULT res;
+            res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
+            if (res == MMSYSERR_NOERROR) {
+                if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
+                    ppd->DeviceId = DSOUND_capture_guids[wid];
+                    hr = DS_OK;
+                    TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
+                          debugstr_w(ppd->DeviceName));
+                    break;
+                }
+            }
+        }
+    }
 
     if (pcbReturned)
         *pcbReturned = cbPropData;
 
-    return DS_OK;
+    return hr;
 }
 
 static HRESULT DSPROPERTY_WaveDeviceMappingA(
@@ -174,12 +180,10 @@ static HRESULT DSPROPERTY_DescriptionW(
     PULONG pcbReturned )
 {
     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
+    HRESULT err;
     GUID dev_guid;
-    IMMDevice *mmdevice;
-    IPropertyStore *ps;
-    PROPVARIANT pv;
-    DWORD desclen;
-    HRESULT hr;
+    ULONG wod, wid, wodn, widn;
+    DSDRIVERDESC desc;
 
     TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
           pPropData,cbPropData,pcbReturned);
@@ -203,41 +207,63 @@ static HRESULT DSPROPERTY_DescriptionW(
 
     GetDeviceID(&ppd->DeviceId, &dev_guid);
 
-    hr = get_mmdevice(eRender, &dev_guid, &mmdevice);
-    if(FAILED(hr)){
-        hr = get_mmdevice(eCapture, &dev_guid, &mmdevice);
-        if(FAILED(hr))
-            return hr;
+    wodn = waveOutGetNumDevs();
+    widn = waveInGetNumDevs();
+    wid = wod = dev_guid.Data4[7];
+    if (!memcmp(&dev_guid, &DSOUND_renderer_guids[0], sizeof(GUID)-1)
+        && wod < wodn)
+    {
+        ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
+        ppd->WaveDeviceId = wod;
+    }
+    else if (!memcmp(&dev_guid, &DSOUND_capture_guids[0], sizeof(GUID)-1)
+             && wid < widn)
+    {
+        ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
+        ppd->WaveDeviceId = wid;
+    }
+    else
+    {
+        WARN("Device not found\n");
+        return E_PROP_ID_UNSUPPORTED;
     }
 
-    hr = IMMDevice_OpenPropertyStore(mmdevice, STGM_READ, &ps);
-    if(FAILED(hr)){
-        IMMDevice_Release(mmdevice);
-        WARN("OpenPropertyStore failed: %08x\n", hr);
-        return hr;
+    if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
+        err = waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel);
+    else
+        err = waveInMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel);
+
+    if (err != MMSYSERR_NOERROR)
+    {
+        WARN("waveMessage(DRV_QUERYDSOUNDDESC) failed!\n");
+        return E_PROP_ID_UNSUPPORTED;
     }
+    else
+    {
+        /* FIXME: Still a memory leak.. */
+        int desclen, modlen;
+        static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
+
+        modlen = MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, NULL, 0 );
+        desclen = MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, NULL, 0 );
+        ppd->Module = HeapAlloc(GetProcessHeap(),0,modlen*sizeof(WCHAR));
+        ppd->Description = HeapAlloc(GetProcessHeap(),0,desclen*sizeof(WCHAR));
+        ppd->Interface = wInterface;
+        if (!ppd->Description || !ppd->Module)
+        {
+            WARN("Out of memory\n");
+            HeapFree(GetProcessHeap(), 0, ppd->Description);
+            HeapFree(GetProcessHeap(), 0, ppd->Module);
+            ppd->Description = ppd->Module = NULL;
+            return E_OUTOFMEMORY;
+        }
 
-    hr = IPropertyStore_GetValue(ps,
-            (const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
-    if(FAILED(hr)){
-        IPropertyStore_Release(ps);
-        IMMDevice_Release(mmdevice);
-        WARN("GetValue(FriendlyName) failed: %08x\n", hr);
-        return hr;
+        MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->Module, modlen );
+        MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->Description, desclen );
     }
 
-    desclen = lstrlenW(pv.u.pwszVal) + 1;
-    /* FIXME: Still a memory leak.. */
-    ppd->Description = HeapAlloc(GetProcessHeap(), 0, desclen * sizeof(WCHAR));
-    memcpy(ppd->Description, pv.u.pwszVal, desclen * sizeof(WCHAR));
-    ppd->Module = wine_vxd_drv;
-    ppd->Interface = wInterface;
     ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
 
-    PropVariantClear(&pv);
-    IPropertyStore_Release(ps);
-    IMMDevice_Release(mmdevice);
-
     if (pcbReturned) {
         *pcbReturned = sizeof(*ppd);
         TRACE("*pcbReturned=%d\n", *pcbReturned);
@@ -246,49 +272,15 @@ static HRESULT DSPROPERTY_DescriptionW(
     return S_OK;
 }
 
-static
-BOOL CALLBACK enum_callback(GUID *guid, const WCHAR *desc, const WCHAR *module,
-        void *user)
-{
-    PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = user;
-    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
-    DWORD len;
-    BOOL ret;
-
-    TRACE("%s %s %s %p\n", wine_dbgstr_guid(guid), wine_dbgstr_w(desc),
-            wine_dbgstr_w(module), user);
-
-    if(!guid)
-        return TRUE;
-
-    data.DeviceId = *guid;
-
-    len = lstrlenW(module) + 1;
-    data.Module = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-    memcpy(data.Module, module, len * sizeof(WCHAR));
-
-    len = lstrlenW(desc) + 1;
-    data.Description = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-    memcpy(data.Description, desc, len * sizeof(WCHAR));
-
-    data.Interface = wInterface;
-
-    ret = ppd->Callback(&data, ppd->Context);
-
-    HeapFree(GetProcessHeap(), 0, data.Module);
-    HeapFree(GetProcessHeap(), 0, data.Description);
-
-    return ret;
-}
-
 static HRESULT DSPROPERTY_EnumerateW(
     LPVOID pPropData,
     ULONG cbPropData,
     PULONG pcbReturned )
 {
     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
-    HRESULT hr;
-
+    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
+    BOOL ret;
+    int widn, wodn, i;
     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
           pPropData,cbPropData,pcbReturned);
 
@@ -301,14 +293,45 @@ static HRESULT DSPROPERTY_EnumerateW(
         return E_PROP_ID_UNSUPPORTED;
     }
 
-    hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
-            enum_callback, ppd);
+    wodn = waveOutGetNumDevs();
+    widn = waveInGetNumDevs();
 
-    if(hr == S_OK)
-        hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
-                enum_callback, ppd);
+    data.DeviceId = DSOUND_renderer_guids[0];
+    for (i = 0; i < wodn; ++i)
+    {
+        HRESULT hr;
+        data.DeviceId.Data4[7] = i;
+        hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
+        if (FAILED(hr))
+        {
+            ERR("DescriptionW failed!\n");
+            return S_OK;
+        }
+        ret = ppd->Callback(&data, ppd->Context);
+        HeapFree(GetProcessHeap(), 0, data.Module);
+        HeapFree(GetProcessHeap(), 0, data.Description);
+        if (!ret)
+            return S_OK;
+    }
 
-    return SUCCEEDED(hr) ? DS_OK : hr;
+    data.DeviceId = DSOUND_capture_guids[0];
+    for (i = 0; i < widn; ++i)
+    {
+        HRESULT hr;
+        data.DeviceId.Data4[7] = i;
+        hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
+        if (FAILED(hr))
+        {
+            ERR("DescriptionW failed!\n");
+            return S_OK;
+        }
+        ret = ppd->Callback(&data, ppd->Context);
+        HeapFree(GetProcessHeap(), 0, data.Module);
+        HeapFree(GetProcessHeap(), 0, data.Description);
+        if (!ret)
+            return S_OK;
+    }
+    return S_OK;
 }
 
 static BOOL DSPROPERTY_descWtoA(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
@@ -589,24 +612,23 @@ static const IKsPropertySetVtbl ikspvt = {
     IKsPrivatePropertySetImpl_QuerySupport
 };
 
-HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **ppv)
+HRESULT IKsPrivatePropertySetImpl_Create(
+    REFIID riid,
+    IKsPropertySet **piks)
 {
     IKsPrivatePropertySetImpl *iks;
-    HRESULT hr;
+    TRACE("(%s, %p)\n", debugstr_guid(riid), piks);
 
-    TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
-
-    iks = HeapAlloc(GetProcessHeap(), 0, sizeof(*iks));
-    if (!iks) {
-        WARN("out of memory\n");
-        return DSERR_OUTOFMEMORY;
+    if (!IsEqualIID(riid, &IID_IUnknown) &&
+        !IsEqualIID(riid, &IID_IKsPropertySet)) {
+        *piks = 0;
+        return E_NOINTERFACE;
     }
 
+    iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
     iks->ref = 1;
     iks->IKsPropertySet_iface.lpVtbl = &ikspvt;
 
-    hr = IKsPropertySet_QueryInterface(&iks->IKsPropertySet_iface, riid, ppv);
-    IKsPropertySet_Release(&iks->IKsPropertySet_iface);
-
-    return hr;
+    *piks = &iks->IKsPropertySet_iface;
+    return S_OK;
 }