Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/winealsa.drv/alsa.c | 408 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 408 insertions(+)
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c index 272040f8047..db654bd75b9 100644 --- a/dlls/winealsa.drv/alsa.c +++ b/dlls/winealsa.drv/alsa.c @@ -2467,3 +2467,411 @@ unixlib_entry_t __wine_unix_call_funcs[] = midi_in_message, midi_notify_wait, }; + +#ifdef _WIN64 + +typedef UINT PTR32; + +static NTSTATUS wow64_get_endpoint_ids(void *args) +{ + struct + { + EDataFlow flow; + PTR32 endpoints; + unsigned int size; + HRESULT result; + unsigned int num; + unsigned int default_idx; + } *params32 = args; + struct get_endpoint_ids_params params = + { + .flow = params32->flow, + .endpoints = ULongToPtr(params32->endpoints), + .size = params32->size + }; + get_endpoint_ids(¶ms); + params32->size = params.size; + params32->result = params.result; + params32->num = params.num; + params32->default_idx = params.default_idx; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_create_stream(void *args) +{ + struct + { + PTR32 alsa_name; + EDataFlow flow; + AUDCLNT_SHAREMODE share; + DWORD flags; + REFERENCE_TIME duration; + REFERENCE_TIME period; + PTR32 fmt; + HRESULT result; + PTR32 stream; + } *params32 = args; + struct create_stream_params params = + { + .alsa_name = ULongToPtr(params32->alsa_name), + .flow = params32->flow, + .share = params32->share, + .flags = params32->flags, + .duration = params32->duration, + .period = params32->period, + .fmt = ULongToPtr(params32->fmt), + .stream = ULongToPtr(params32->stream) + }; + create_stream(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_release_stream(void *args) +{ + struct + { + stream_handle stream; + PTR32 timer_thread; + HRESULT result; + } *params32 = args; + struct release_stream_params params = + { + .stream = params32->stream, + .timer_thread = ULongToHandle(params32->timer_thread) + }; + release_stream(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_get_render_buffer(void *args) +{ + struct + { + stream_handle stream; + UINT32 frames; + HRESULT result; + PTR32 data; + } *params32 = args; + BYTE *data = NULL; + struct get_render_buffer_params params = + { + .stream = params32->stream, + .frames = params32->frames, + .data = &data + }; + 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) +{ + struct + { + stream_handle stream; + HRESULT result; + PTR32 data; + PTR32 frames; + PTR32 flags; + PTR32 devpos; + PTR32 qpcpos; + } *params32 = args; + BYTE *data = NULL; + struct get_capture_buffer_params params = + { + .stream = params32->stream, + .data = &data, + .frames = ULongToPtr(params32->frames), + .flags = ULongToPtr(params32->flags), + .devpos = ULongToPtr(params32->devpos), + .qpcpos = ULongToPtr(params32->qpcpos) + }; + 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) +{ + struct + { + PTR32 alsa_name; + EDataFlow flow; + AUDCLNT_SHAREMODE share; + PTR32 fmt_in; + PTR32 fmt_out; + HRESULT result; + } *params32 = args; + struct is_format_supported_params params = + { + .alsa_name = ULongToPtr(params32->alsa_name), + .flow = params32->flow, + .share = params32->share, + .fmt_in = ULongToPtr(params32->fmt_in), + .fmt_out = ULongToPtr(params32->fmt_out) + }; + is_format_supported(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_get_mix_format(void *args) +{ + struct + { + PTR32 alsa_name; + EDataFlow flow; + PTR32 fmt; + HRESULT result; + } *params32 = args; + struct get_mix_format_params params = + { + .alsa_name = ULongToPtr(params32->alsa_name), + .flow = params32->flow, + .fmt = ULongToPtr(params32->fmt) + }; + get_mix_format(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_get_buffer_size(void *args) +{ + struct + { + stream_handle stream; + HRESULT result; + PTR32 size; + } *params32 = args; + struct get_buffer_size_params params = + { + .stream = params32->stream, + .size = ULongToPtr(params32->size) + }; + get_buffer_size(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_get_latency(void *args) +{ + struct + { + stream_handle stream; + HRESULT result; + PTR32 latency; + } *params32 = args; + struct get_latency_params params = + { + .stream = params32->stream, + .latency = ULongToPtr(params32->latency) + }; + get_latency(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_get_current_padding(void *args) +{ + struct + { + stream_handle stream; + HRESULT result; + PTR32 padding; + } *params32 = args; + struct get_current_padding_params params = + { + .stream = params32->stream, + .padding = ULongToPtr(params32->padding) + }; + get_current_padding(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_get_next_packet_size(void *args) +{ + struct + { + stream_handle stream; + HRESULT result; + PTR32 frames; + } *params32 = args; + struct get_next_packet_size_params params = + { + .stream = params32->stream, + .frames = ULongToPtr(params32->frames) + }; + get_next_packet_size(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_get_frequency(void *args) +{ + struct + { + stream_handle stream; + HRESULT result; + PTR32 freq; + } *params32 = args; + struct get_frequency_params params = + { + .stream = params32->stream, + .freq = ULongToPtr(params32->freq) + }; + get_frequency(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_get_position(void *args) +{ + struct + { + stream_handle stream; + HRESULT result; + PTR32 pos; + PTR32 qpctime; + } *params32 = args; + struct get_position_params params = + { + .stream = params32->stream, + .pos = ULongToPtr(params32->pos), + .qpctime = ULongToPtr(params32->qpctime) + }; + get_position(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_set_volumes(void *args) +{ + struct + { + stream_handle stream; + float master_volume; + PTR32 volumes; + PTR32 session_volumes; + } *params32 = args; + struct set_volumes_params params = + { + .stream = params32->stream, + .master_volume = params32->master_volume, + .volumes = ULongToPtr(params32->volumes), + .session_volumes = ULongToPtr(params32->session_volumes) + }; + return set_volumes(¶ms); +} + +static NTSTATUS wow64_set_event_handle(void *args) +{ + struct + { + stream_handle stream; + PTR32 event; + HRESULT result; + } *params32 = args; + struct set_event_handle_params params = + { + .stream = params32->stream, + .event = ULongToHandle(params32->event) + }; + + set_event_handle(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_get_prop_value(void *args) +{ + struct propvariant32 + { + WORD vt; + WORD pad1, pad2, pad3; + union + { + ULONG ulVal; + PTR32 ptr; + ULARGE_INTEGER uhVal; + }; + } *value32; + struct + { + PTR32 alsa_name; + 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 = + { + .alsa_name = ULongToPtr(params32->alsa_name), + .flow = params32->flow, + .guid = ULongToPtr(params32->guid), + .prop = ULongToPtr(params32->prop), + .value = &value, + .buffer = ULongToPtr(params32->buffer), + .buffer_size = ULongToPtr(params32->buffer_size) + }; + get_prop_value(¶ms); + params32->result = params.result; + if (SUCCEEDED(params.result)) + { + value32 = UlongToPtr(params32->value); + value32->vt = value.vt; + switch (value.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; +} + +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, + midi_out_message, + midi_in_message, + midi_notify_wait, +}; + +#endif /* _WIN64 */