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 DevMap *ProbeDevices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, ALuint *numdevs) { IMMDeviceCollection *coll; IMMDevice *defdev = NULL; DevMap *devlist = NULL; HRESULT hr; UINT count; UINT idx; UINT i; hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flowdir, DEVICE_STATE_ACTIVE, &coll); if(FAILED(hr)) { ERR("Failed to enumerate audio endpoints: 0x%08lx\n", hr); return NULL; } idx = count = 0; hr = IMMDeviceCollection_GetCount(coll, &count); if(SUCCEEDED(hr) && count > 0) { devlist = calloc(count, sizeof(*devlist)); if(!devlist) { IMMDeviceCollection_Release(coll); return NULL; } hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, flowdir, eMultimedia, &defdev); } if(SUCCEEDED(hr) && defdev != NULL) add_device(defdev, &devlist[idx++]); for(i = 0;i < count && idx < count;++i) { IMMDevice *device; if(FAILED(IMMDeviceCollection_Item(coll, i, &device))) continue; if(device != defdev) add_device(device, &devlist[idx++]); IMMDevice_Release(device); } if(defdev) IMMDevice_Release(defdev); IMMDeviceCollection_Release(coll); *numdevs = idx; return devlist; }
static HRESULT probe_devices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, vector_DevMap *list) { IMMDeviceCollection *coll; IMMDevice *defdev = NULL; HRESULT hr; UINT count; UINT i; hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flowdir, DEVICE_STATE_ACTIVE, &coll); if(FAILED(hr)) { ERR("Failed to enumerate audio endpoints: 0x%08lx\n", hr); return hr; } count = 0; hr = IMMDeviceCollection_GetCount(coll, &count); if(SUCCEEDED(hr) && count > 0) { clear_devlist(list); if(!VECTOR_RESERVE(*list, count+1)) { IMMDeviceCollection_Release(coll); return E_OUTOFMEMORY; } hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, flowdir, eMultimedia, &defdev); } if(SUCCEEDED(hr) && defdev != NULL) add_device(defdev, list); for(i = 0;i < count;++i) { IMMDevice *device; if(FAILED(IMMDeviceCollection_Item(coll, i, &device))) continue; if(device != defdev) add_device(device, list); IMMDevice_Release(device); } if(defdev) IMMDevice_Release(defdev); IMMDeviceCollection_Release(coll); return S_OK; }
static BOOL load_devices(IMMDeviceEnumerator *devenum, EDataFlow dataflow, UINT *ndevs, struct DeviceInfo **out) { IMMDeviceCollection *coll; UINT i; HRESULT hr; hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, dataflow, DEVICE_STATE_ACTIVE, &coll); if(FAILED(hr)) return FALSE; hr = IMMDeviceCollection_GetCount(coll, ndevs); if(FAILED(hr)){ IMMDeviceCollection_Release(coll); return FALSE; } if(*ndevs > 0){ *out = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInfo) * (*ndevs)); if(!*out){ IMMDeviceCollection_Release(coll); return FALSE; } for(i = 0; i < *ndevs; ++i){ IMMDevice *dev; hr = IMMDeviceCollection_Item(coll, i, &dev); if(FAILED(hr)){ (*out)[i].id = NULL; continue; } load_device(dev, &(*out)[i]); IMMDevice_Release(dev); } }else *out = NULL; IMMDeviceCollection_Release(coll); return TRUE; }
JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_wasapi_WASAPI_IMMDeviceEnumerator_1EnumAudioEndpoints (JNIEnv *env, jclass clazz, jlong thiz, jint dataFlow, jint dwStateMask) { IMMDeviceCollection *pDevices; HRESULT hr = IMMDeviceEnumerator_EnumAudioEndpoints( (IMMDeviceEnumerator *) (intptr_t) thiz, (EDataFlow) dataFlow, (DWORD) dwStateMask, &pDevices); if (FAILED(hr)) { pDevices = NULL; WASAPI_throwNewHResultException(env, hr, __func__, __LINE__); } return (jlong) (intptr_t) pDevices; }
/* 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){ 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 == TRUE) ? S_OK : S_FALSE; }