This is the very first step for merging the `mmdevdrv.c` files into a single one.
The commit strictly focuses on Linux drivers, `wine{oss,coreaudio}` will follow.
Huge thanks to @jacek and @huw for making this simple, as they took care of ELF/PE separation.
From: Davide Beatrici git@davidebeatrici.dev
This is the very first step for merging the mmdevdrv.c files into a single one.
The commit strictly focuses on Linux drivers, wine{oss,coreaudio} will follow.
Huge thanks to Jacek Caban and Huw Davies for making this simple, as they took care of ELF/PE separation. --- dlls/{winepulse.drv => mmdevapi}/unixlib.h | 94 +++++-- dlls/winealsa.drv/alsa.c | 252 ++++++++++--------- dlls/winealsa.drv/alsamidi.c | 20 +- dlls/winealsa.drv/mmdevdrv.c | 8 +- dlls/winealsa.drv/unixlib.h | 279 +-------------------- dlls/winepulse.drv/mmdevdrv.c | 58 ++--- dlls/winepulse.drv/pulse.c | 143 +++++++---- 7 files changed, 350 insertions(+), 504 deletions(-) rename dlls/{winepulse.drv => mmdevapi}/unixlib.h (73%)
diff --git a/dlls/winepulse.drv/unixlib.h b/dlls/mmdevapi/unixlib.h similarity index 73% rename from dlls/winepulse.drv/unixlib.h rename to dlls/mmdevapi/unixlib.h index 1481a5db4b8..7fd4062b6c9 100644 --- a/dlls/winepulse.drv/unixlib.h +++ b/dlls/mmdevapi/unixlib.h @@ -1,5 +1,6 @@ /* * Copyright 2021 Jacek Caban for CodeWeavers + * Copyright 2022 Huw Davies * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,10 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "wine/list.h" -#include "wine/unixlib.h" +#include "windef.h"
-#define MAX_PULSE_NAME_LEN 256 +#include "audioclient.h" +#include "audiopolicy.h" +#include "endpointvolume.h" +#include "mmdeviceapi.h" +#include "spatialaudioclient.h"
typedef UINT64 stream_handle;
@@ -32,7 +36,7 @@ enum phys_device_bus_type { struct endpoint { unsigned int name; - unsigned int pulse_name; + unsigned int device; };
struct main_loop_params @@ -53,11 +57,12 @@ struct get_endpoint_ids_params struct create_stream_params { const char *name; - const char *pulse_name; - EDataFlow dataflow; - AUDCLNT_SHAREMODE mode; + const char *device; + EDataFlow flow; + AUDCLNT_SHAREMODE share; DWORD flags; REFERENCE_TIME duration; + REFERENCE_TIME period; const WAVEFORMATEX *fmt; HRESULT result; UINT32 *channel_count; @@ -67,7 +72,7 @@ struct create_stream_params struct release_stream_params { stream_handle stream; - HANDLE timer; + HANDLE timer_thread; HRESULT result; };
@@ -128,9 +133,19 @@ struct release_capture_buffer_params HRESULT result; };
+struct is_format_supported_params +{ + const char *device; + EDataFlow flow; + AUDCLNT_SHAREMODE share; + const WAVEFORMATEX *fmt_in; + WAVEFORMATEXTENSIBLE *fmt_out; + HRESULT result; +}; + struct get_mix_format_params { - const char *pulse_name; + const char *device; EDataFlow flow; WAVEFORMATEXTENSIBLE *fmt; HRESULT result; @@ -138,7 +153,7 @@ struct get_mix_format_params
struct get_device_period_params { - const char *pulse_name; + const char *device; EDataFlow flow; HRESULT result; REFERENCE_TIME *def_period; @@ -213,22 +228,60 @@ struct test_connect_params struct is_started_params { stream_handle stream; - BOOL started; + HRESULT result; };
struct get_prop_value_params { - const char *pulse_name; + const char *device; const GUID *guid; const PROPERTYKEY *prop; EDataFlow flow; HRESULT result; - VARTYPE vt; - union - { - WCHAR wstr[128]; - ULONG ulVal; - }; + PROPVARIANT *value; + void *buffer; /* caller allocated buffer to hold value's strings */ + unsigned int *buffer_size; +}; + +struct notify_context +{ + BOOL send_notify; + WORD dev_id; + WORD msg; + UINT_PTR param_1; + UINT_PTR param_2; + UINT_PTR callback; + UINT flags; + HANDLE device; + UINT_PTR instance; +}; + +struct midi_out_message_params +{ + UINT dev_id; + UINT msg; + UINT_PTR user; + UINT_PTR param_1; + UINT_PTR param_2; + UINT *err; + struct notify_context *notify; +}; + +struct midi_in_message_params +{ + UINT dev_id; + UINT msg; + UINT_PTR user; + UINT_PTR param_1; + UINT_PTR param_2; + UINT *err; + struct notify_context *notify; +}; + +struct midi_notify_wait_params +{ + BOOL *quit; + struct notify_context *notify; };
enum unix_funcs @@ -247,6 +300,7 @@ enum unix_funcs release_render_buffer, get_capture_buffer, release_capture_buffer, + is_format_supported, get_mix_format, get_device_period, get_buffer_size, @@ -260,4 +314,8 @@ enum unix_funcs test_connect, is_started, get_prop_value, + midi_release, + midi_out_message, + midi_in_message, + midi_notify_wait }; diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c index 8439262428f..57292c19201 100644 --- a/dlls/winealsa.drv/alsa.c +++ b/dlls/winealsa.drv/alsa.c @@ -468,7 +468,7 @@ static WCHAR *alsa_get_card_name(int card) return ret; }
-static NTSTATUS get_endpoint_ids(void *args) +static NTSTATUS alsa_get_endpoint_ids(void *args) { static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0}; struct get_endpoint_ids_params *params = args; @@ -775,7 +775,7 @@ static ULONG_PTR zero_bits(void) #endif }
-static NTSTATUS create_stream(void *args) +static NTSTATUS alsa_create_stream(void *args) { struct create_stream_params *params = args; struct alsa_stream *stream; @@ -792,7 +792,7 @@ static NTSTATUS create_stream(void *args) return STATUS_SUCCESS; }
- params->result = alsa_open_device(params->alsa_name, params->flow, &stream->pcm_handle, &stream->hw_params); + params->result = alsa_open_device(params->device, params->flow, &stream->pcm_handle, &stream->hw_params); if(FAILED(params->result)){ free(stream); return STATUS_SUCCESS; @@ -1009,7 +1009,7 @@ exit: return STATUS_SUCCESS; }
-static NTSTATUS release_stream(void *args) +static NTSTATUS alsa_release_stream(void *args) { struct release_stream_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -1505,7 +1505,7 @@ static int alsa_rewind_best_effort(struct alsa_stream *stream) return len; }
-static NTSTATUS start(void *args) +static NTSTATUS alsa_start(void *args) { struct start_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -1551,7 +1551,7 @@ static NTSTATUS start(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS stop(void *args) +static NTSTATUS alsa_stop(void *args) { struct stop_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -1569,7 +1569,7 @@ static NTSTATUS stop(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS reset(void *args) +static NTSTATUS alsa_reset(void *args) { struct reset_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -1604,7 +1604,7 @@ static NTSTATUS reset(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS timer_loop(void *args) +static NTSTATUS alsa_timer_loop(void *args) { struct timer_loop_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -1642,7 +1642,7 @@ static NTSTATUS timer_loop(void *args) return STATUS_SUCCESS; }
-static NTSTATUS get_render_buffer(void *args) +static NTSTATUS alsa_get_render_buffer(void *args) { struct get_render_buffer_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -1706,7 +1706,7 @@ static void alsa_wrap_buffer(struct alsa_stream *stream, BYTE *buffer, UINT32 wr } }
-static NTSTATUS release_render_buffer(void *args) +static NTSTATUS alsa_release_render_buffer(void *args) { struct release_render_buffer_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -1746,7 +1746,7 @@ static NTSTATUS release_render_buffer(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS get_capture_buffer(void *args) +static NTSTATUS alsa_get_capture_buffer(void *args) { struct get_capture_buffer_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -1807,7 +1807,7 @@ static NTSTATUS get_capture_buffer(void *args) return alsa_unlock_result(stream, ¶ms->result, *frames ? S_OK : AUDCLNT_S_BUFFER_EMPTY); }
-static NTSTATUS release_capture_buffer(void *args) +static NTSTATUS alsa_release_capture_buffer(void *args) { struct release_capture_buffer_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -1835,7 +1835,7 @@ static NTSTATUS release_capture_buffer(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS is_format_supported(void *args) +static NTSTATUS alsa_is_format_supported(void *args) { struct is_format_supported_params *params = args; const WAVEFORMATEXTENSIBLE *fmtex = (const WAVEFORMATEXTENSIBLE *)params->fmt_in; @@ -1869,7 +1869,7 @@ static NTSTATUS is_format_supported(void *args) return STATUS_SUCCESS; }
- params->result = alsa_open_device(params->alsa_name, params->flow, &pcm_handle, &hw_params); + params->result = alsa_open_device(params->device, params->flow, &pcm_handle, &hw_params); if(FAILED(params->result)) return STATUS_SUCCESS;
@@ -1974,7 +1974,7 @@ exit: return STATUS_SUCCESS; }
-static NTSTATUS get_mix_format(void *args) +static NTSTATUS alsa_get_mix_format(void *args) { struct get_mix_format_params *params = args; WAVEFORMATEXTENSIBLE *fmt = params->fmt; @@ -1984,7 +1984,7 @@ static NTSTATUS get_mix_format(void *args) unsigned int max_rate, max_channels; int err;
- params->result = alsa_open_device(params->alsa_name, params->flow, &pcm_handle, &hw_params); + params->result = alsa_open_device(params->device, params->flow, &pcm_handle, &hw_params); if(FAILED(params->result)) return STATUS_SUCCESS;
@@ -2091,7 +2091,7 @@ exit: return STATUS_SUCCESS; }
-static NTSTATUS get_buffer_size(void *args) +static NTSTATUS alsa_get_buffer_size(void *args) { struct get_buffer_size_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -2103,7 +2103,7 @@ static NTSTATUS get_buffer_size(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS get_latency(void *args) +static NTSTATUS alsa_get_latency(void *args) { struct get_latency_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -2124,7 +2124,7 @@ static NTSTATUS get_latency(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS get_current_padding(void *args) +static NTSTATUS alsa_get_current_padding(void *args) { struct get_current_padding_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -2137,7 +2137,7 @@ static NTSTATUS get_current_padding(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS get_next_packet_size(void *args) +static NTSTATUS alsa_get_next_packet_size(void *args) { struct get_next_packet_size_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -2149,7 +2149,7 @@ static NTSTATUS get_next_packet_size(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS get_frequency(void *args) +static NTSTATUS alsa_get_frequency(void *args) { struct get_frequency_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -2165,7 +2165,7 @@ static NTSTATUS get_frequency(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS get_position(void *args) +static NTSTATUS alsa_get_position(void *args) { struct get_position_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -2217,7 +2217,7 @@ static NTSTATUS get_position(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS set_volumes(void *args) +static NTSTATUS alsa_set_volumes(void *args) { struct set_volumes_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -2229,7 +2229,7 @@ static NTSTATUS set_volumes(void *args) return STATUS_SUCCESS; }
-static NTSTATUS set_event_handle(void *args) +static NTSTATUS alsa_set_event_handle(void *args) { struct set_event_handle_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -2249,7 +2249,7 @@ static NTSTATUS set_event_handle(void *args) return alsa_unlock_result(stream, ¶ms->result, S_OK); }
-static NTSTATUS is_started(void *args) +static NTSTATUS alsa_is_started(void *args) { struct is_started_params *params = args; struct alsa_stream *stream = handle_get_stream(params->stream); @@ -2304,10 +2304,10 @@ enum AudioDeviceConnectionType { AudioDeviceConnectionType_USB };
-static NTSTATUS get_prop_value(void *args) +static NTSTATUS alsa_get_prop_value(void *args) { struct get_prop_value_params *params = args; - const char *name = params->alsa_name; + const char *name = params->device; EDataFlow flow = params->flow; const GUID *guid = params->guid; const PROPERTYKEY *prop = params->prop; @@ -2431,40 +2431,45 @@ static NTSTATUS get_prop_value(void *args)
unixlib_entry_t __wine_unix_call_funcs[] = { - get_endpoint_ids, - create_stream, - release_stream, - start, - stop, - reset, - timer_loop, - get_render_buffer, - release_render_buffer, - get_capture_buffer, - release_capture_buffer, - is_format_supported, - get_mix_format, - get_buffer_size, - get_latency, - get_current_padding, - get_next_packet_size, - get_frequency, - get_position, - set_volumes, - set_event_handle, - is_started, - get_prop_value, - midi_release, - midi_out_message, - midi_in_message, - midi_notify_wait, + NULL, + NULL, + NULL, + alsa_get_endpoint_ids, + alsa_create_stream, + alsa_release_stream, + alsa_start, + alsa_stop, + alsa_reset, + alsa_timer_loop, + alsa_get_render_buffer, + alsa_release_render_buffer, + alsa_get_capture_buffer, + alsa_release_capture_buffer, + alsa_is_format_supported, + alsa_get_mix_format, + NULL, + alsa_get_buffer_size, + alsa_get_latency, + alsa_get_current_padding, + alsa_get_next_packet_size, + alsa_get_frequency, + alsa_get_position, + alsa_set_volumes, + alsa_set_event_handle, + NULL, + alsa_is_started, + alsa_get_prop_value, + alsa_midi_release, + alsa_midi_out_message, + alsa_midi_in_message, + alsa_midi_notify_wait, };
#ifdef _WIN64
typedef UINT PTR32;
-static NTSTATUS wow64_get_endpoint_ids(void *args) +static NTSTATUS alsa_wow64_get_endpoint_ids(void *args) { struct { @@ -2481,7 +2486,7 @@ static NTSTATUS wow64_get_endpoint_ids(void *args) .endpoints = ULongToPtr(params32->endpoints), .size = params32->size }; - get_endpoint_ids(¶ms); + alsa_get_endpoint_ids(¶ms); params32->size = params.size; params32->result = params.result; params32->num = params.num; @@ -2489,11 +2494,11 @@ static NTSTATUS wow64_get_endpoint_ids(void *args) return STATUS_SUCCESS; }
-static NTSTATUS wow64_create_stream(void *args) +static NTSTATUS alsa_wow64_create_stream(void *args) { struct { - PTR32 alsa_name; + PTR32 device; EDataFlow flow; AUDCLNT_SHAREMODE share; DWORD flags; @@ -2505,7 +2510,7 @@ static NTSTATUS wow64_create_stream(void *args) } *params32 = args; struct create_stream_params params = { - .alsa_name = ULongToPtr(params32->alsa_name), + .device = ULongToPtr(params32->device), .flow = params32->flow, .share = params32->share, .flags = params32->flags, @@ -2514,12 +2519,12 @@ static NTSTATUS wow64_create_stream(void *args) .fmt = ULongToPtr(params32->fmt), .stream = ULongToPtr(params32->stream) }; - create_stream(¶ms); + alsa_create_stream(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_release_stream(void *args) +static NTSTATUS alsa_wow64_release_stream(void *args) { struct { @@ -2532,12 +2537,12 @@ static NTSTATUS wow64_release_stream(void *args) .stream = params32->stream, .timer_thread = ULongToHandle(params32->timer_thread) }; - release_stream(¶ms); + alsa_release_stream(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_render_buffer(void *args) +static NTSTATUS alsa_wow64_get_render_buffer(void *args) { struct { @@ -2553,13 +2558,13 @@ static NTSTATUS wow64_get_render_buffer(void *args) .frames = params32->frames, .data = &data }; - get_render_buffer(¶ms); + alsa_get_render_buffer(¶ms); params32->result = params.result; *(unsigned int *)ULongToPtr(params32->data) = PtrToUlong(data); return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_capture_buffer(void *args) +static NTSTATUS alsa_wow64_get_capture_buffer(void *args) { struct { @@ -2581,17 +2586,17 @@ static NTSTATUS wow64_get_capture_buffer(void *args) .devpos = ULongToPtr(params32->devpos), .qpcpos = ULongToPtr(params32->qpcpos) }; - get_capture_buffer(¶ms); + alsa_get_capture_buffer(¶ms); params32->result = params.result; *(unsigned int *)ULongToPtr(params32->data) = PtrToUlong(data); return STATUS_SUCCESS; };
-static NTSTATUS wow64_is_format_supported(void *args) +static NTSTATUS alsa_wow64_is_format_supported(void *args) { struct { - PTR32 alsa_name; + PTR32 device; EDataFlow flow; AUDCLNT_SHAREMODE share; PTR32 fmt_in; @@ -2600,38 +2605,38 @@ static NTSTATUS wow64_is_format_supported(void *args) } *params32 = args; struct is_format_supported_params params = { - .alsa_name = ULongToPtr(params32->alsa_name), + .device = ULongToPtr(params32->device), .flow = params32->flow, .share = params32->share, .fmt_in = ULongToPtr(params32->fmt_in), .fmt_out = ULongToPtr(params32->fmt_out) }; - is_format_supported(¶ms); + alsa_is_format_supported(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_mix_format(void *args) +static NTSTATUS alsa_wow64_get_mix_format(void *args) { struct { - PTR32 alsa_name; + PTR32 device; EDataFlow flow; PTR32 fmt; HRESULT result; } *params32 = args; struct get_mix_format_params params = { - .alsa_name = ULongToPtr(params32->alsa_name), + .device = ULongToPtr(params32->device), .flow = params32->flow, .fmt = ULongToPtr(params32->fmt) }; - get_mix_format(¶ms); + alsa_get_mix_format(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_buffer_size(void *args) +static NTSTATUS alsa_wow64_get_buffer_size(void *args) { struct { @@ -2644,12 +2649,12 @@ static NTSTATUS wow64_get_buffer_size(void *args) .stream = params32->stream, .size = ULongToPtr(params32->size) }; - get_buffer_size(¶ms); + alsa_get_buffer_size(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_latency(void *args) +static NTSTATUS alsa_wow64_get_latency(void *args) { struct { @@ -2662,12 +2667,12 @@ static NTSTATUS wow64_get_latency(void *args) .stream = params32->stream, .latency = ULongToPtr(params32->latency) }; - get_latency(¶ms); + alsa_get_latency(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_current_padding(void *args) +static NTSTATUS alsa_wow64_get_current_padding(void *args) { struct { @@ -2680,12 +2685,12 @@ static NTSTATUS wow64_get_current_padding(void *args) .stream = params32->stream, .padding = ULongToPtr(params32->padding) }; - get_current_padding(¶ms); + alsa_get_current_padding(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_next_packet_size(void *args) +static NTSTATUS alsa_wow64_get_next_packet_size(void *args) { struct { @@ -2698,12 +2703,12 @@ static NTSTATUS wow64_get_next_packet_size(void *args) .stream = params32->stream, .frames = ULongToPtr(params32->frames) }; - get_next_packet_size(¶ms); + alsa_get_next_packet_size(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_frequency(void *args) +static NTSTATUS alsa_wow64_get_frequency(void *args) { struct { @@ -2716,12 +2721,12 @@ static NTSTATUS wow64_get_frequency(void *args) .stream = params32->stream, .freq = ULongToPtr(params32->freq) }; - get_frequency(¶ms); + alsa_get_frequency(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_position(void *args) +static NTSTATUS alsa_wow64_get_position(void *args) { struct { @@ -2736,12 +2741,12 @@ static NTSTATUS wow64_get_position(void *args) .pos = ULongToPtr(params32->pos), .qpctime = ULongToPtr(params32->qpctime) }; - get_position(¶ms); + alsa_get_position(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_set_volumes(void *args) +static NTSTATUS alsa_wow64_set_volumes(void *args) { struct { @@ -2757,10 +2762,10 @@ static NTSTATUS wow64_set_volumes(void *args) .volumes = ULongToPtr(params32->volumes), .session_volumes = ULongToPtr(params32->session_volumes) }; - return set_volumes(¶ms); + return alsa_set_volumes(¶ms); }
-static NTSTATUS wow64_set_event_handle(void *args) +static NTSTATUS alsa_wow64_set_event_handle(void *args) { struct { @@ -2774,12 +2779,12 @@ static NTSTATUS wow64_set_event_handle(void *args) .event = ULongToHandle(params32->event) };
- set_event_handle(¶ms); + alsa_set_event_handle(¶ms); params32->result = params.result; return STATUS_SUCCESS; }
-static NTSTATUS wow64_get_prop_value(void *args) +static NTSTATUS alsa_wow64_get_prop_value(void *args) { struct propvariant32 { @@ -2794,7 +2799,7 @@ static NTSTATUS wow64_get_prop_value(void *args) } *value32; struct { - PTR32 alsa_name; + PTR32 device; EDataFlow flow; PTR32 guid; PTR32 prop; @@ -2806,7 +2811,7 @@ static NTSTATUS wow64_get_prop_value(void *args) PROPVARIANT value; struct get_prop_value_params params = { - .alsa_name = ULongToPtr(params32->alsa_name), + .device = ULongToPtr(params32->device), .flow = params32->flow, .guid = ULongToPtr(params32->guid), .prop = ULongToPtr(params32->prop), @@ -2814,7 +2819,7 @@ static NTSTATUS wow64_get_prop_value(void *args) .buffer = ULongToPtr(params32->buffer), .buffer_size = ULongToPtr(params32->buffer_size) }; - get_prop_value(¶ms); + alsa_get_prop_value(¶ms); params32->result = params.result; if (SUCCEEDED(params.result)) { @@ -2837,33 +2842,38 @@ static NTSTATUS wow64_get_prop_value(void *args)
unixlib_entry_t __wine_unix_call_wow64_funcs[] = { - wow64_get_endpoint_ids, - wow64_create_stream, - wow64_release_stream, - start, - stop, - reset, - timer_loop, - wow64_get_render_buffer, - release_render_buffer, - wow64_get_capture_buffer, - release_capture_buffer, - wow64_is_format_supported, - wow64_get_mix_format, - wow64_get_buffer_size, - wow64_get_latency, - wow64_get_current_padding, - wow64_get_next_packet_size, - wow64_get_frequency, - wow64_get_position, - wow64_set_volumes, - wow64_set_event_handle, - is_started, - wow64_get_prop_value, - midi_release, - wow64_midi_out_message, - wow64_midi_in_message, - wow64_midi_notify_wait, + NULL, + NULL, + NULL, + alsa_wow64_get_endpoint_ids, + alsa_wow64_create_stream, + alsa_wow64_release_stream, + alsa_start, + alsa_stop, + alsa_reset, + alsa_timer_loop, + alsa_wow64_get_render_buffer, + alsa_release_render_buffer, + alsa_wow64_get_capture_buffer, + alsa_release_capture_buffer, + alsa_wow64_is_format_supported, + alsa_wow64_get_mix_format, + NULL, + alsa_wow64_get_buffer_size, + alsa_wow64_get_latency, + alsa_wow64_get_current_padding, + alsa_wow64_get_next_packet_size, + alsa_wow64_get_frequency, + alsa_wow64_get_position, + alsa_wow64_set_volumes, + alsa_wow64_set_event_handle, + NULL, + alsa_is_started, + alsa_wow64_get_prop_value, + alsa_midi_release, + alsa_wow64_midi_out_message, + alsa_wow64_midi_in_message, + alsa_wow64_midi_notify_wait, };
#endif /* _WIN64 */ diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c index 6350e3e4265..6fe6fee85a9 100644 --- a/dlls/winealsa.drv/alsamidi.c +++ b/dlls/winealsa.drv/alsamidi.c @@ -468,7 +468,7 @@ static UINT midi_init(void) return NOERROR; }
-NTSTATUS midi_release(void *args) +NTSTATUS alsa_midi_release(void *args) { /* stop the notify_wait thread */ notify_post(NULL); @@ -1389,7 +1389,7 @@ static DWORD midi_in_reset(WORD dev_id, struct notify_context *notify) return err; }
-NTSTATUS midi_out_message(void *args) +NTSTATUS alsa_midi_out_message(void *args) { struct midi_out_message_params *params = args;
@@ -1447,7 +1447,7 @@ NTSTATUS midi_out_message(void *args) return STATUS_SUCCESS; }
-NTSTATUS midi_in_message(void *args) +NTSTATUS alsa_midi_in_message(void *args) { struct midi_in_message_params *params = args;
@@ -1502,7 +1502,7 @@ NTSTATUS midi_in_message(void *args) return STATUS_SUCCESS; }
-NTSTATUS midi_notify_wait(void *args) +NTSTATUS alsa_midi_notify_wait(void *args) { struct midi_notify_wait_params *params = args;
@@ -1606,7 +1606,7 @@ static UINT wow64_midi_out_unprepare(WORD dev_id, struct midi_hdr32 *hdr, UINT h return MMSYSERR_NOERROR; }
-NTSTATUS wow64_midi_out_message(void *args) +NTSTATUS alsa_wow64_midi_out_message(void *args) { struct { @@ -1677,7 +1677,7 @@ NTSTATUS wow64_midi_out_message(void *args) return STATUS_SUCCESS; }
- midi_out_message(¶ms); + alsa_midi_out_message(¶ms);
switch (params32->msg) { @@ -1730,7 +1730,7 @@ static UINT wow64_midi_in_unprepare(WORD dev_id, struct midi_hdr32 *hdr, UINT hd return MMSYSERR_NOERROR; }
-NTSTATUS wow64_midi_in_message(void *args) +NTSTATUS alsa_wow64_midi_in_message(void *args) { struct { @@ -1802,7 +1802,7 @@ NTSTATUS wow64_midi_in_message(void *args) return STATUS_SUCCESS; }
- midi_in_message(¶ms); + alsa_midi_in_message(¶ms);
switch (params32->msg) { @@ -1837,7 +1837,7 @@ NTSTATUS wow64_midi_in_message(void *args) return STATUS_SUCCESS; }
-NTSTATUS wow64_midi_notify_wait(void *args) +NTSTATUS alsa_wow64_midi_notify_wait(void *args) { struct { @@ -1855,7 +1855,7 @@ NTSTATUS wow64_midi_notify_wait(void *args) }; notify32->send_notify = FALSE;
- midi_notify_wait(¶ms); + alsa_midi_notify_wait(¶ms);
if (!*params.quit && notify.send_notify) { diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c index cba96cdcfb8..b77c6e7418b 100644 --- a/dlls/winealsa.drv/mmdevdrv.c +++ b/dlls/winealsa.drv/mmdevdrv.c @@ -746,7 +746,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
dump_fmt(fmt);
- params.alsa_name = This->alsa_name; + params.device = This->alsa_name; params.flow = This->dataflow; params.share = mode; params.flags = flags; @@ -870,7 +870,7 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface, TRACE("(%p)->(%x, %p, %p)\n", This, mode, fmt, out); if(fmt) dump_fmt(fmt);
- params.alsa_name = This->alsa_name; + params.device = This->alsa_name; params.flow = This->dataflow; params.share = mode; params.fmt_in = fmt; @@ -903,7 +903,7 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface, return E_POINTER; *pwfx = NULL;
- params.alsa_name = This->alsa_name; + params.device = This->alsa_name; params.flow = This->dataflow; params.fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE)); if(!params.fmt) @@ -2455,7 +2455,7 @@ HRESULT WINAPI AUDDRV_GetPropValue(GUID *guid, const PROPERTYKEY *prop, PROPVARI return E_NOINTERFACE; }
- params.alsa_name = name; + params.device = name; params.flow = flow; params.guid = guid; params.prop = prop; diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h index dea3b5ebdc9..8c82281012a 100644 --- a/dlls/winealsa.drv/unixlib.h +++ b/dlls/winealsa.drv/unixlib.h @@ -16,280 +16,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "audioclient.h" +#include "../mmdevapi/unixlib.h"
-typedef UINT64 stream_handle; - -struct endpoint -{ - unsigned int name; - unsigned int device; -}; - -struct get_endpoint_ids_params -{ - EDataFlow flow; - struct endpoint *endpoints; - unsigned int size; - HRESULT result; - unsigned int num; - unsigned int default_idx; -}; - -struct create_stream_params -{ - const char *alsa_name; - EDataFlow flow; - AUDCLNT_SHAREMODE share; - DWORD flags; - REFERENCE_TIME duration; - REFERENCE_TIME period; - const WAVEFORMATEX *fmt; - HRESULT result; - stream_handle *stream; -}; - -struct release_stream_params -{ - stream_handle stream; - HANDLE timer_thread; - HRESULT result; -}; - -struct start_params -{ - stream_handle stream; - HRESULT result; -}; - -struct stop_params -{ - stream_handle stream; - HRESULT result; -}; - -struct reset_params -{ - stream_handle stream; - HRESULT result; -}; - -struct timer_loop_params -{ - stream_handle stream; -}; - -struct get_render_buffer_params -{ - stream_handle stream; - UINT32 frames; - HRESULT result; - BYTE **data; -}; - -struct release_render_buffer_params -{ - stream_handle stream; - UINT32 written_frames; - UINT flags; - HRESULT result; -}; - -struct get_capture_buffer_params -{ - stream_handle stream; - HRESULT result; - BYTE **data; - UINT32 *frames; - UINT *flags; - UINT64 *devpos; - UINT64 *qpcpos; -}; - -struct release_capture_buffer_params -{ - stream_handle stream; - UINT32 done; - HRESULT result; -}; - -struct is_format_supported_params -{ - const char *alsa_name; - EDataFlow flow; - AUDCLNT_SHAREMODE share; - const WAVEFORMATEX *fmt_in; - WAVEFORMATEXTENSIBLE *fmt_out; - HRESULT result; -}; - -struct get_mix_format_params -{ - const char *alsa_name; - EDataFlow flow; - WAVEFORMATEXTENSIBLE *fmt; - HRESULT result; -}; - -struct get_buffer_size_params -{ - stream_handle stream; - HRESULT result; - UINT32 *size; -}; - -struct get_latency_params -{ - stream_handle stream; - HRESULT result; - REFERENCE_TIME *latency; -}; - -struct get_current_padding_params -{ - stream_handle stream; - HRESULT result; - UINT32 *padding; -}; - -struct get_next_packet_size_params -{ - stream_handle stream; - HRESULT result; - UINT32 *frames; -}; - -struct get_frequency_params -{ - stream_handle stream; - HRESULT result; - UINT64 *freq; -}; - -struct get_position_params -{ - stream_handle stream; - HRESULT result; - UINT64 *pos; - UINT64 *qpctime; -}; - -struct set_volumes_params -{ - stream_handle stream; - float master_volume; - const float *volumes; - const float *session_volumes; -}; - -struct set_event_handle_params -{ - stream_handle stream; - HANDLE event; - HRESULT result; -}; - -struct is_started_params -{ - stream_handle stream; - HRESULT result; -}; - -struct get_prop_value_params -{ - const char *alsa_name; - EDataFlow flow; - const GUID *guid; - const PROPERTYKEY *prop; - HRESULT result; - PROPVARIANT *value; - void *buffer; /* caller allocated buffer to hold value's strings */ - unsigned int *buffer_size; -}; - -struct notify_context -{ - BOOL send_notify; - WORD dev_id; - WORD msg; - UINT_PTR param_1; - UINT_PTR param_2; - UINT_PTR callback; - UINT flags; - HANDLE device; - UINT_PTR instance; -}; - -struct midi_out_message_params -{ - UINT dev_id; - UINT msg; - UINT_PTR user; - UINT_PTR param_1; - UINT_PTR param_2; - UINT *err; - struct notify_context *notify; -}; - -struct midi_in_message_params -{ - UINT dev_id; - UINT msg; - UINT_PTR user; - UINT_PTR param_1; - UINT_PTR param_2; - UINT *err; - struct notify_context *notify; -}; - -struct midi_notify_wait_params -{ - BOOL *quit; - struct notify_context *notify; -}; - -enum alsa_funcs -{ - alsa_get_endpoint_ids, - alsa_create_stream, - alsa_release_stream, - alsa_start, - alsa_stop, - alsa_reset, - alsa_timer_loop, - alsa_get_render_buffer, - alsa_release_render_buffer, - alsa_get_capture_buffer, - alsa_release_capture_buffer, - alsa_is_format_supported, - alsa_get_mix_format, - alsa_get_buffer_size, - alsa_get_latency, - alsa_get_current_padding, - alsa_get_next_packet_size, - alsa_get_frequency, - alsa_get_position, - alsa_set_volumes, - alsa_set_event_handle, - alsa_is_started, - alsa_get_prop_value, - alsa_midi_release, - alsa_midi_out_message, - alsa_midi_in_message, - alsa_midi_notify_wait, -}; - -NTSTATUS midi_release(void *args) DECLSPEC_HIDDEN; -NTSTATUS midi_out_message(void *args) DECLSPEC_HIDDEN; -NTSTATUS midi_in_message(void *args) DECLSPEC_HIDDEN; -NTSTATUS midi_notify_wait(void *args) DECLSPEC_HIDDEN; +NTSTATUS alsa_midi_release(void *args) DECLSPEC_HIDDEN; +NTSTATUS alsa_midi_out_message(void *args) DECLSPEC_HIDDEN; +NTSTATUS alsa_midi_in_message(void *args) DECLSPEC_HIDDEN; +NTSTATUS alsa_midi_notify_wait(void *args) DECLSPEC_HIDDEN;
#ifdef _WIN64 -NTSTATUS wow64_midi_out_message(void *args) DECLSPEC_HIDDEN; -NTSTATUS wow64_midi_in_message(void *args) DECLSPEC_HIDDEN; -NTSTATUS wow64_midi_notify_wait(void *args) DECLSPEC_HIDDEN; +NTSTATUS alsa_wow64_midi_out_message(void *args) DECLSPEC_HIDDEN; +NTSTATUS alsa_wow64_midi_in_message(void *args) DECLSPEC_HIDDEN; +NTSTATUS alsa_wow64_midi_notify_wait(void *args) DECLSPEC_HIDDEN; #endif
extern unixlib_handle_t alsa_handle;
-#define ALSA_CALL(func, params) __wine_unix_call(alsa_handle, alsa_ ## func, params) +#define ALSA_CALL(func, params) __wine_unix_call(alsa_handle, func, params) diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 446354fb9a5..57e143566d2 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -2,6 +2,7 @@ * Copyright 2011-2012 Maarten Lankhorst * Copyright 2010-2011 Maarten Lankhorst for CodeWeavers * Copyright 2011 Andrew Eikum for CodeWeavers + * Copyright 2022 Huw Davies * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,6 +29,7 @@ #include "winternl.h" #include "wine/debug.h" #include "wine/list.h" +#include "wine/unixlib.h"
#include "ole2.h" #include "mimeole.h" @@ -44,12 +46,14 @@ #include "endpointvolume.h" #include "audiopolicy.h"
-#include "unixlib.h" +#include "../mmdevapi/unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(pulse);
static unixlib_handle_t pulse_handle;
+#define MAX_PULSE_NAME_LEN 256 + #define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
/* From <dlls/mmdevapi/mmdevapi.h> */ @@ -229,8 +233,8 @@ static void pulse_call(enum unix_funcs code, void *params) static void pulse_release_stream(stream_handle stream, HANDLE timer) { struct release_stream_params params; - params.stream = stream; - params.timer = timer; + params.stream = stream; + params.timer_thread = timer; pulse_call(release_stream, ¶ms); }
@@ -456,7 +460,7 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, GUID **ke
for (i = 0; i < params.num; i++) { WCHAR *name = (WCHAR *)((char *)params.endpoints + params.endpoints[i].name); - char *pulse_name = (char *)params.endpoints + params.endpoints[i].pulse_name; + char *pulse_name = (char *)params.endpoints + params.endpoints[i].device; unsigned int size = (wcslen(name) + 1) * sizeof(WCHAR);
if (!(ids[i] = HeapAlloc(GetProcessHeap(), 0, size))) { @@ -875,9 +879,9 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, }
params.name = name = get_application_name(TRUE); - params.pulse_name = This->pulse_name; - params.dataflow = This->dataflow; - params.mode = mode; + params.device = This->pulse_name; + params.flow = This->dataflow; + params.share = mode; params.flags = flags; params.duration = duration; params.fmt = fmt; @@ -1141,7 +1145,7 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface, return E_POINTER; *pwfx = NULL;
- params.pulse_name = This->pulse_name; + params.device = This->pulse_name; params.flow = This->dataflow; params.fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE)); if (!params.fmt) @@ -1171,7 +1175,7 @@ static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface, return E_POINTER;
params.flow = This->dataflow; - params.pulse_name = This->pulse_name; + params.device = This->pulse_name; params.def_period = defperiod; params.min_period = minperiod;
@@ -2020,7 +2024,7 @@ static HRESULT WINAPI AudioSessionControl_GetState(IAudioSessionControl2 *iface,
params.stream = client->pulse_stream; pulse_call(is_started, ¶ms); - if (params.started) { + if (params.result == S_OK) { *state = AudioSessionStateActive; goto out; } @@ -2659,35 +2663,33 @@ HRESULT WINAPI AUDDRV_GetPropValue(GUID *guid, const PROPERTYKEY *prop, PROPVARI { struct get_prop_value_params params; char pulse_name[MAX_PULSE_NAME_LEN]; - DWORD size; + unsigned int size = 0;
TRACE("%s, (%s,%lu), %p\n", wine_dbgstr_guid(guid), wine_dbgstr_guid(&prop->fmtid), prop->pid, out);
if (!get_pulse_name_by_guid(guid, pulse_name, ¶ms.flow)) return E_FAIL;
- params.pulse_name = pulse_name; + params.device = pulse_name; params.guid = guid; params.prop = prop; - pulse_call(get_prop_value, ¶ms); + params.value = out; + params.buffer = NULL; + params.buffer_size = &size; + + while(1) { + pulse_call(get_prop_value, ¶ms);
- if (params.result != S_OK) - return params.result; + if(params.result != E_NOT_SUFFICIENT_BUFFER) + break;
- switch (params.vt) { - case VT_LPWSTR: - size = (wcslen(params.wstr) + 1) * sizeof(WCHAR); - if (!(out->pwszVal = CoTaskMemAlloc(size))) + CoTaskMemFree(params.buffer); + params.buffer = CoTaskMemAlloc(*params.buffer_size); + if(!params.buffer) return E_OUTOFMEMORY; - memcpy(out->pwszVal, params.wstr, size); - break; - case VT_UI4: - out->ulVal = params.ulVal; - break; - default: - assert(0); } - out->vt = params.vt; + if(FAILED(params.result)) + CoTaskMemFree(params.buffer);
- return S_OK; + return params.result; } diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index bd918b6f260..38738a81779 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -2,6 +2,7 @@ * Copyright 2011-2012 Maarten Lankhorst * Copyright 2010-2011 Maarten Lankhorst for CodeWeavers * Copyright 2011 Andrew Eikum for CodeWeavers + * Copyright 2022 Huw Davies * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,9 +38,11 @@ #include "initguid.h" #include "audioclient.h"
-#include "unixlib.h" - #include "wine/debug.h" +#include "wine/list.h" +#include "wine/unixlib.h" + +#include "../mmdevapi/unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(pulse);
@@ -268,7 +271,7 @@ static NTSTATUS pulse_get_endpoint_ids(void *args) endpoint->name = offset; memcpy((char *)params->endpoints + offset, dev->name, name_len * sizeof(WCHAR)); offset += name_len * sizeof(WCHAR); - endpoint->pulse_name = offset; + endpoint->device = offset; memcpy((char *)params->endpoints + offset, dev->pulse_name, len); offset += (len + 1) & ~1; endpoint++; @@ -1108,7 +1111,7 @@ static NTSTATUS pulse_create_stream(void *args) return STATUS_SUCCESS; }
- stream->dataflow = params->dataflow; + stream->dataflow = params->flow; for (i = 0; i < ARRAY_SIZE(stream->vol); ++i) stream->vol[i] = 1.f;
@@ -1119,7 +1122,7 @@ static NTSTATUS pulse_create_stream(void *args) goto exit;
period = 0; - hr = get_device_period_helper(params->dataflow, params->pulse_name, &period, NULL); + hr = get_device_period_helper(params->flow, params->device, &period, NULL); if (FAILED(hr)) goto exit;
@@ -1134,9 +1137,9 @@ static NTSTATUS pulse_create_stream(void *args) bufsize_bytes = stream->bufsize_frames * pa_frame_size(&stream->ss); stream->mmdev_period_usec = period / 10;
- stream->share = params->mode; + stream->share = params->share; stream->flags = params->flags; - hr = pulse_stream_connect(stream, params->pulse_name, stream->period_bytes); + hr = pulse_stream_connect(stream, params->device, stream->period_bytes); if (SUCCEEDED(hr)) { UINT32 unalign; const pa_buffer_attr *attr = pa_stream_get_buffer_attr(stream->stream); @@ -1203,10 +1206,10 @@ static NTSTATUS pulse_release_stream(void *args) struct pulse_stream *stream = handle_get_stream(params->stream); SIZE_T size;
- if(params->timer) { + if(params->timer_thread) { stream->please_quit = TRUE; - NtWaitForSingleObject(params->timer, FALSE, NULL); - NtClose(params->timer); + NtWaitForSingleObject(params->timer_thread, FALSE, NULL); + NtClose(params->timer_thread); }
pulse_lock(); @@ -2055,7 +2058,7 @@ static NTSTATUS pulse_get_mix_format(void *args) PhysDevice *dev;
LIST_FOR_EACH_ENTRY(dev, list, PhysDevice, entry) { - if (strcmp(params->pulse_name, dev->pulse_name)) + if (strcmp(params->device, dev->pulse_name)) continue;
*params->fmt = dev->fmt; @@ -2072,7 +2075,7 @@ static NTSTATUS pulse_get_device_period(void *args) { struct get_device_period_params *params = args;
- params->result = get_device_period_helper(params->flow, params->pulse_name, params->def_period, params->min_period); + params->result = get_device_period_helper(params->flow, params->device, params->def_period, params->min_period); return STATUS_SUCCESS; }
@@ -2258,7 +2261,7 @@ static NTSTATUS pulse_is_started(void *args) struct pulse_stream *stream = handle_get_stream(params->stream);
pulse_lock(); - params->started = pulse_stream_valid(stream) && stream->started; + params->result = pulse_stream_valid(stream) && stream->started ? S_OK : S_FALSE; pulse_unlock();
return STATUS_SUCCESS; @@ -2267,6 +2270,7 @@ static NTSTATUS pulse_is_started(void *args) static BOOL get_device_path(PhysDevice *dev, struct get_prop_value_params *params) { const GUID *guid = params->guid; + PROPVARIANT *out = params->value; UINT serial_number; char path[128]; int len; @@ -2288,9 +2292,19 @@ static BOOL get_device_path(PhysDevice *dev, struct get_prop_value_params *param break; }
- ntdll_umbstowcs(path, len + 1, params->wstr, ARRAY_SIZE(params->wstr)); + if (*params->buffer_size < ++len * sizeof(WCHAR)) { + params->result = E_NOT_SUFFICIENT_BUFFER; + *params->buffer_size = len * sizeof(WCHAR); + return FALSE; + } + + out->vt = VT_LPWSTR; + out->pwszVal = params->buffer; + + ntdll_umbstowcs(path, len, out->pwszVal, len); + + params->result = S_OK;
- params->vt = VT_LPWSTR; return TRUE; }
@@ -2308,7 +2322,7 @@ static NTSTATUS pulse_get_prop_value(void *args)
params->result = S_OK; LIST_FOR_EACH_ENTRY(dev, list, PhysDevice, entry) { - if (strcmp(params->pulse_name, dev->pulse_name)) + if (strcmp(params->device, dev->pulse_name)) continue; if (IsEqualPropertyKey(*params->prop, devicepath_key)) { if (!get_device_path(dev, params)) @@ -2317,20 +2331,20 @@ static NTSTATUS pulse_get_prop_value(void *args) } else if (IsEqualGUID(¶ms->prop->fmtid, &PKEY_AudioEndpoint_GUID)) { switch (params->prop->pid) { case 0: /* FormFactor */ - params->vt = VT_UI4; - params->ulVal = dev->form; + params->value->vt = VT_UI4; + params->value->ulVal = dev->form; return STATUS_SUCCESS; case 3: /* PhysicalSpeakers */ if (!dev->channel_mask) goto fail; - params->vt = VT_UI4; - params->ulVal = dev->channel_mask; + params->value->vt = VT_UI4; + params->value->ulVal = dev->channel_mask; return STATUS_SUCCESS; default: - break; + params->result = E_NOTIMPL; } } - params->result = E_NOTIMPL; + return STATUS_SUCCESS; }
@@ -2355,6 +2369,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = pulse_release_render_buffer, pulse_get_capture_buffer, pulse_release_capture_buffer, + NULL, pulse_get_mix_format, pulse_get_device_period, pulse_get_buffer_size, @@ -2368,6 +2383,10 @@ const unixlib_entry_t __wine_unix_call_funcs[] = pulse_test_connect, pulse_is_started, pulse_get_prop_value, + NULL, + NULL, + NULL, + NULL };
#ifdef _WIN64 @@ -2417,9 +2436,9 @@ static NTSTATUS pulse_wow64_create_stream(void *args) struct { PTR32 name; - PTR32 pulse_name; - EDataFlow dataflow; - AUDCLNT_SHAREMODE mode; + PTR32 device; + EDataFlow flow; + AUDCLNT_SHAREMODE share; DWORD flags; REFERENCE_TIME duration; PTR32 fmt; @@ -2430,9 +2449,9 @@ static NTSTATUS pulse_wow64_create_stream(void *args) struct create_stream_params params = { .name = ULongToPtr(params32->name), - .pulse_name = ULongToPtr(params32->pulse_name), - .dataflow = params32->dataflow, - .mode = params32->mode, + .device = ULongToPtr(params32->device), + .flow = params32->flow, + .share = params32->share, .flags = params32->flags, .duration = params32->duration, .fmt = ULongToPtr(params32->fmt), @@ -2455,7 +2474,7 @@ static NTSTATUS pulse_wow64_release_stream(void *args) struct release_stream_params params = { .stream = params32->stream, - .timer = ULongToHandle(params32->timer) + .timer_thread = ULongToHandle(params32->timer) }; pulse_release_stream(¶ms); params32->result = params.result; @@ -2516,14 +2535,14 @@ static NTSTATUS pulse_wow64_get_mix_format(void *args) { struct { - PTR32 pulse_name; + PTR32 device; EDataFlow flow; PTR32 fmt; HRESULT result; } *params32 = args; struct get_mix_format_params params = { - .pulse_name = ULongToPtr(params32->pulse_name), + .device = ULongToPtr(params32->device), .flow = params32->flow, .fmt = ULongToPtr(params32->fmt), }; @@ -2536,7 +2555,7 @@ static NTSTATUS pulse_wow64_get_device_period(void *args) { struct { - PTR32 pulse_name; + PTR32 device; EDataFlow flow; HRESULT result; PTR32 def_period; @@ -2544,7 +2563,7 @@ static NTSTATUS pulse_wow64_get_device_period(void *args) } *params32 = args; struct get_device_period_params params = { - .pulse_name = ULongToPtr(params32->pulse_name), + .device = ULongToPtr(params32->device), .flow = params32->flow, .def_period = ULongToPtr(params32->def_period), .min_period = ULongToPtr(params32->min_period), @@ -2721,42 +2740,55 @@ static NTSTATUS pulse_wow64_test_connect(void *args)
static NTSTATUS pulse_wow64_get_prop_value(void *args) { - struct + struct propvariant32 { - PTR32 pulse_name; - PTR32 guid; - PTR32 prop; - EDataFlow flow; - HRESULT result; - VARTYPE vt; + WORD vt; + WORD pad1, pad2, pad3; union { - WCHAR wstr[128]; ULONG ulVal; + PTR32 ptr; + ULARGE_INTEGER uhVal; }; + } *value32; + struct + { + PTR32 device; + EDataFlow flow; + PTR32 guid; + PTR32 prop; + HRESULT result; + PTR32 value; + PTR32 buffer; /* caller allocated buffer to hold value's strings */ + PTR32 buffer_size; } *params32 = args; + PROPVARIANT value; struct get_prop_value_params params = { - .pulse_name = ULongToPtr(params32->pulse_name), + .device = ULongToPtr(params32->device), + .flow = params32->flow, .guid = ULongToPtr(params32->guid), .prop = ULongToPtr(params32->prop), - .flow = params32->flow, + .value = &value, + .buffer = ULongToPtr(params32->buffer), + .buffer_size = ULongToPtr(params32->buffer_size) }; pulse_get_prop_value(¶ms); params32->result = params.result; - params32->vt = params.vt; if (SUCCEEDED(params.result)) { - switch (params.vt) + value32 = UlongToPtr(params32->value); + value32->vt = value.vt; + switch (value.vt) { - case VT_UI4: - params32->ulVal = params.ulVal; - break; - case VT_LPWSTR: - wcscpy(params32->wstr, params.wstr); - break; - default: - FIXME("Unhandled vt %04x\n", params.vt); + case VT_UI4: + value32->ulVal = value.ulVal; + break; + case VT_LPWSTR: + value32->ptr = params32->buffer; + break; + default: + FIXME("Unhandled vt %04x\n", value.vt); } } return STATUS_SUCCESS; @@ -2778,6 +2810,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = pulse_release_render_buffer, pulse_wow64_get_capture_buffer, pulse_release_capture_buffer, + NULL, pulse_wow64_get_mix_format, pulse_wow64_get_device_period, pulse_wow64_get_buffer_size, @@ -2791,6 +2824,10 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = pulse_wow64_test_connect, pulse_is_started, pulse_wow64_get_prop_value, + NULL, + NULL, + NULL, + NULL };
#endif /* _WIN64 */
Changes were tested locally like this:
``` tools/runtest -P wine -T . -M mmdevapi.dll -p dlls/mmdevapi/tests/mmdevapi_test.exe.so capture tools/runtest -P wine -T . -M mmdevapi.dll -p dlls/mmdevapi/tests/mmdevapi_test.exe.so dependency tools/runtest -P wine -T . -M mmdevapi.dll -p dlls/mmdevapi/tests/mmdevapi_test.exe.so mmdevenum tools/runtest -P wine -T . -M mmdevapi.dll -p dlls/mmdevapi/tests/mmdevapi_test.exe.so propstore tools/runtest -P wine -T . -M mmdevapi.dll -p dlls/mmdevapi/tests/mmdevapi_test.exe.so render tools/runtest -P wine -T . -M mmdevapi.dll -p dlls/mmdevapi/tests/mmdevapi_test.exe.so spatialaudio ```
For both `winealsa.drv` and `winepulse.drv`, but only in 64 bit mode. In fact, I have to fix a build error that appeared on CI.