diff options
Diffstat (limited to 'src/output')
-rw-r--r-- | src/output/winmm_output_plugin.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/output/winmm_output_plugin.c b/src/output/winmm_output_plugin.c index 66e693dd4..47d98498f 100644 --- a/src/output/winmm_output_plugin.c +++ b/src/output/winmm_output_plugin.c @@ -74,33 +74,45 @@ winmm_output_test_default_device(void) return waveOutGetNumDevs() > 0; } -static UINT -get_device_id(const char *device_name) +static bool +get_device_id(const char *device_name, UINT *device_id, GError **error_r) { /* if device is not specified use wave mapper */ - if (device_name == NULL) - return WAVE_MAPPER; + if (device_name == NULL) { + *device_id = WAVE_MAPPER; + return true; + } + + UINT numdevs = waveOutGetNumDevs(); /* check for device id */ char *endptr; UINT id = strtoul(device_name, &endptr, 0); - if (endptr > device_name && *endptr == 0) - return id; + if (endptr > device_name && *endptr == 0) { + if (id >= numdevs) + goto fail; + *device_id = id; + return true; + } /* check for device name */ - for (UINT i = 0; i < waveOutGetNumDevs(); i++) { + for (UINT i = 0; i < numdevs; i++) { WAVEOUTCAPS caps; MMRESULT result = waveOutGetDevCaps(i, &caps, sizeof(caps)); if (result != MMSYSERR_NOERROR) continue; /* szPname is only 32 chars long, so it is often truncated. Use partial match to work around this. */ - if (strstr(device_name, caps.szPname) == device_name) - return i; + if (strstr(device_name, caps.szPname) == device_name) { + *device_id = i; + return true; + } } - /* fallback to wave mapper */ - return WAVE_MAPPER; +fail: + g_set_error(error_r, winmm_output_quark(), 0, + "device \"%s\" is not found", device_name); + return false; } static struct audio_output * @@ -113,7 +125,12 @@ winmm_output_init(const struct config_param *param, GError **error_r) } const char *device = config_get_block_string(param, "device", NULL); - wo->device_id = get_device_id(device); + if (!get_device_id(device, &wo->device_id, error_r)) { + ao_base_finish(&wo->base); + g_free(wo); + return NULL; + } + return &wo->base; } |