From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winecoreaudio.drv/coreaudio.c | 45 +++++++++++++++++------------- dlls/winecoreaudio.drv/mmdevdrv.c | 25 +++++++++-------- dlls/winecoreaudio.drv/unixlib.h | 10 ++++--- 3 files changed, 44 insertions(+), 36 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index 2a9dcde0675..b35d8b698a3 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -266,17 +266,20 @@ static NTSTATUS get_endpoint_ids(void *args) endpoint = params->endpoints;
for(i = 0; i < params->num; i++){ - SIZE_T len = CFStringGetLength(info[i].name); - needed += (len + 1) * sizeof(WCHAR); + SIZE_T name_len = CFStringGetLength(info[i].name) + 1; + const SIZE_T len = MAX_DEV_NAME_LEN + 1; + needed += name_len * sizeof(WCHAR) + ((len + 1) & ~1);
if(needed <= params->size){ endpoint->name = offset; ptr = (UniChar *)((char *)params->endpoints + offset); - CFStringGetCharacters(info[i].name, CFRangeMake(0, len), ptr); - ptr[len] = 0; - endpoint->id = info[i].id; + offset += name_len * sizeof(WCHAR); + CFStringGetCharacters(info[i].name, CFRangeMake(0, --name_len), ptr); + ptr[name_len] = 0; + endpoint->device = offset; + sprintf((char *)params->endpoints + offset, "%u", info[i].id); + offset += (len + 1) & ~1; endpoint++; - offset += (len + 1) * sizeof(WCHAR); } CFRelease(info[i].name); if(info[i].id == default_id) params->default_idx = i; @@ -645,7 +648,7 @@ static NTSTATUS create_stream(void *args)
stream->period_ms = params->period / 10000; stream->period_frames = muldiv(params->period, stream->fmt->nSamplesPerSec, 10000000); - stream->dev_id = params->dev_id; + stream->dev_id = strtoul(params->device, NULL, 10); stream->flow = params->flow; stream->share = params->share;
@@ -903,6 +906,7 @@ static NTSTATUS get_mix_format(void *args) UInt32 size; OSStatus sc; int i; + const AudioDeviceID dev_id = strtoul(params->device, NULL, 10);
params->fmt->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
@@ -910,10 +914,10 @@ static NTSTATUS get_mix_format(void *args) addr.mElement = 0; addr.mSelector = kAudioDevicePropertyPreferredChannelLayout;
- sc = AudioObjectGetPropertyDataSize(params->dev_id, &addr, 0, NULL, &size); + sc = AudioObjectGetPropertyDataSize(dev_id, &addr, 0, NULL, &size); if(sc == noErr){ layout = malloc(size); - sc = AudioObjectGetPropertyData(params->dev_id, &addr, 0, NULL, &size, layout); + sc = AudioObjectGetPropertyData(dev_id, &addr, 0, NULL, &size, layout); if(sc == noErr){ TRACE("Got channel layout: {tag: 0x%x, bitmap: 0x%x, num_descs: %u}\n", (unsigned int)layout->mChannelLayoutTag, (unsigned int)layout->mChannelBitmap, @@ -942,7 +946,7 @@ static NTSTATUS get_mix_format(void *args) addr.mElement = 0; addr.mSelector = kAudioDevicePropertyStreamConfiguration;
- sc = AudioObjectGetPropertyDataSize(params->dev_id, &addr, 0, NULL, &size); + sc = AudioObjectGetPropertyDataSize(dev_id, &addr, 0, NULL, &size); if(sc != noErr){ WARN("Unable to get size for _StreamConfiguration property: %x\n", (int)sc); params->result = osstatus_to_hresult(sc); @@ -955,7 +959,7 @@ static NTSTATUS get_mix_format(void *args) return STATUS_SUCCESS; }
- sc = AudioObjectGetPropertyData(params->dev_id, &addr, 0, NULL, &size, buffers); + sc = AudioObjectGetPropertyData(dev_id, &addr, 0, NULL, &size, buffers); if(sc != noErr){ free(buffers); WARN("Unable to get _StreamConfiguration property: %x\n", (int)sc); @@ -973,7 +977,7 @@ static NTSTATUS get_mix_format(void *args)
addr.mSelector = kAudioDevicePropertyNominalSampleRate; size = sizeof(Float64); - sc = AudioObjectGetPropertyData(params->dev_id, &addr, 0, NULL, &size, &rate); + sc = AudioObjectGetPropertyData(dev_id, &addr, 0, NULL, &size, &rate); if(sc != noErr){ WARN("Unable to get _NominalSampleRate property: %x\n", (int)sc); params->result = osstatus_to_hresult(sc); @@ -1002,6 +1006,7 @@ static NTSTATUS is_format_supported(void *args) AudioStreamBasicDescription dev_desc; AudioConverterRef converter; AudioComponentInstance unit; + const AudioDeviceID dev_id = strtoul(params->device, NULL, 10);
params->result = S_OK;
@@ -1031,7 +1036,7 @@ static NTSTATUS is_format_supported(void *args) params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; return STATUS_SUCCESS; } - unit = get_audiounit(params->flow, params->dev_id); + unit = get_audiounit(params->flow, dev_id);
converter = NULL; params->result = ca_setup_audiounit(params->flow, unit, params->fmt_in, &dev_desc, &converter); @@ -1046,8 +1051,8 @@ unsupported: if(params->fmt_out){ struct get_mix_format_params get_mix_params = { + .device = params->device, .flow = params->flow, - .dev_id = params->dev_id, .fmt = params->fmt_out, };
@@ -1695,7 +1700,7 @@ static NTSTATUS wow64_create_stream(void *args) { struct { - DWORD dev_id; + PTR32 device; EDataFlow flow; AUDCLNT_SHAREMODE share; REFERENCE_TIME duration; @@ -1706,7 +1711,7 @@ static NTSTATUS wow64_create_stream(void *args) } *params32 = args; struct create_stream_params params = { - .dev_id = params32->dev_id, + .device = ULongToPtr(params32->device), .flow = params32->flow, .share = params32->share, .duration = params32->duration, @@ -1773,8 +1778,8 @@ static NTSTATUS wow64_is_format_supported(void *args) { struct { + PTR32 device; EDataFlow flow; - DWORD dev_id; AUDCLNT_SHAREMODE share; PTR32 fmt_in; PTR32 fmt_out; @@ -1782,8 +1787,8 @@ static NTSTATUS wow64_is_format_supported(void *args) } *params32 = args; struct is_format_supported_params params = { + .device = ULongToPtr(params32->device), .flow = params32->flow, - .dev_id = params32->dev_id, .share = params32->share, .fmt_in = ULongToPtr(params32->fmt_in), .fmt_out = ULongToPtr(params32->fmt_out) @@ -1797,15 +1802,15 @@ static NTSTATUS wow64_get_mix_format(void *args) { struct { + PTR32 device; EDataFlow flow; - DWORD dev_id; PTR32 fmt; HRESULT result; } *params32 = args; struct get_mix_format_params params = { + .device = ULongToPtr(params32->device), .flow = params32->flow, - .dev_id = params32->dev_id, .fmt = ULongToPtr(params32->fmt) }; get_mix_format(¶ms); diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index da6c05bdc1f..ee5fd0ba991 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -97,7 +97,7 @@ struct ACImpl { HANDLE event; float *vols;
- DWORD dev_id; + char dev_name[MAX_DEV_NAME_LEN + 1]; HANDLE timer;
AudioSession *session; @@ -261,11 +261,11 @@ exit: RegCloseKey(drv_key); }
-static void get_device_guid(EDataFlow flow, DWORD device_id, GUID *guid) +static void get_device_guid(EDataFlow flow, const char *dev, GUID *guid) { HKEY key = NULL, dev_key; DWORD type, size = sizeof(*guid); - WCHAR key_name[256]; + WCHAR key_name[MAX_DEV_NAME_LEN + 2];
if(flow == eCapture) key_name[0] = '1'; @@ -273,7 +273,7 @@ static void get_device_guid(EDataFlow flow, DWORD device_id, GUID *guid) key_name[0] = '0'; key_name[1] = ',';
- swprintf(key_name + 2, ARRAY_SIZE(key_name), L"%u", device_id); + MultiByteToWideChar(CP_UNIXCP, 0, dev, -1, key_name + 2, ARRAY_SIZE(key_name) - 2);
if(RegOpenKeyExW(HKEY_CURRENT_USER, drv_key_devicesW, 0, KEY_WRITE|KEY_READ, &key) == ERROR_SUCCESS){ if(RegOpenKeyExW(key, key_name, 0, KEY_READ, &dev_key) == ERROR_SUCCESS){ @@ -323,7 +323,7 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, TRACE("%d %p %p %p\n", flow, ids_out, num, def_index);
params.flow = flow; - params.size = 1000; + params.size = MAX_DEV_NAME_LEN + 1; params.endpoints = NULL; do{ heap_free(params.endpoints); @@ -341,8 +341,9 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, }
for(i = 0; i < params.num; i++){ - WCHAR *name = (WCHAR *)((char *)params.endpoints + params.endpoints[i].name); - int size = (wcslen(name) + 1) * sizeof(WCHAR); + const WCHAR *name = (WCHAR *)((char *)params.endpoints + params.endpoints[i].name); + const char *device = (char *)params.endpoints + params.endpoints[i].device; + const unsigned int size = (wcslen(name) + 1) * sizeof(WCHAR);
ids[i] = heap_alloc(size); if(!ids[i]){ @@ -350,7 +351,7 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, goto end; } memcpy(ids[i], name, size); - get_device_guid(flow, params.endpoints[i].id, guids + i); + get_device_guid(flow, device, guids + i); } *def_index = params.default_idx;
@@ -469,7 +470,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient This->parent = dev; IMMDevice_AddRef(This->parent);
- This->dev_id = dev_id; + snprintf(This->dev_name, sizeof(This->dev_name), "%lu", dev_id);
*out = (IAudioClient *)&This->IAudioClient3_iface; IAudioClient3_AddRef(&This->IAudioClient3_iface); @@ -731,7 +732,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, return AUDCLNT_E_ALREADY_INITIALIZED; }
- params.dev_id = This->dev_id; + params.device = This->dev_name; params.flow = This->dataflow; params.share = mode; params.duration = duration; @@ -849,7 +850,7 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface, TRACE("(%p)->(%x, %p, %p)\n", This, mode, pwfx, outpwfx); if(pwfx) dump_fmt(pwfx);
- params.dev_id = This->dev_id; + params.device = This->dev_name; params.flow = This->dataflow; params.share = mode; params.fmt_in = pwfx; @@ -882,7 +883,7 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface, return E_POINTER; *pwfx = NULL;
- params.dev_id = This->dev_id; + params.device = This->dev_name; params.flow = This->dataflow; params.fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE)); if(!params.fmt) diff --git a/dlls/winecoreaudio.drv/unixlib.h b/dlls/winecoreaudio.drv/unixlib.h index 1c7dcebb52d..c373eddea33 100644 --- a/dlls/winecoreaudio.drv/unixlib.h +++ b/dlls/winecoreaudio.drv/unixlib.h @@ -19,12 +19,14 @@ */ #include "mmddk.h"
+#define MAX_DEV_NAME_LEN 10 /* Max 32 bit digits */ + typedef UINT64 stream_handle;
struct endpoint { unsigned int name; - DWORD id; + unsigned int device; };
struct get_endpoint_ids_params @@ -39,7 +41,7 @@ struct get_endpoint_ids_params
struct create_stream_params { - DWORD dev_id; + const char *device; EDataFlow flow; AUDCLNT_SHAREMODE share; REFERENCE_TIME duration; @@ -109,16 +111,16 @@ struct release_capture_buffer_params
struct get_mix_format_params { + const char *device; EDataFlow flow; - DWORD dev_id; WAVEFORMATEXTENSIBLE *fmt; HRESULT result; };
struct is_format_supported_params { + const char *device; EDataFlow flow; - DWORD dev_id; AUDCLNT_SHAREMODE share; const WAVEFORMATEX *fmt_in; WAVEFORMATEXTENSIBLE *fmt_out;