This will make the Wow64 syscall rather simpler.
Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/winepulse.drv/mmdevdrv.c | 9 ++++++--- dlls/winepulse.drv/pulse.c | 17 ++++++++--------- dlls/winepulse.drv/unixlib.h | 4 ++-- 3 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 96b8b28d1b5..f1a1b36c9ef 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -457,13 +457,16 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, GUID **ke }
for (i = 0; i < params.num; i++) { - unsigned int size = (wcslen(params.endpoints[i].name) + 1) * sizeof(WCHAR); + WCHAR *name = (WCHAR *)((char *)params.endpoints + params.endpoints[i].name); + char *pulse_name = (char *)params.endpoints + params.endpoints[i].pulse_name; + unsigned int size = (wcslen(name) + 1) * sizeof(WCHAR); + if (!(ids[i] = HeapAlloc(GetProcessHeap(), 0, size))) { params.result = E_OUTOFMEMORY; break; } - memcpy(ids[i], params.endpoints[i].name, size); - get_device_guid(drv_key, flow, params.endpoints[i].pulse_name, &guids[i]); + memcpy(ids[i], name, size); + get_device_guid(drv_key, flow, pulse_name, &guids[i]); } if (drv_key) RegCloseKey(drv_key); diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 5e3ddcc9b6e..34955a5ee8d 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -327,12 +327,11 @@ static NTSTATUS pulse_get_endpoint_ids(void *args) struct list *list = (params->flow == eRender) ? &g_phys_speakers : &g_phys_sources; struct endpoint *endpoint = params->endpoints; DWORD len, name_len, needed; + unsigned int offset; PhysDevice *dev; - char *ptr;
params->num = list_count(list); - needed = params->num * sizeof(*params->endpoints); - ptr = (char*)(endpoint + params->num); + offset = needed = params->num * sizeof(*params->endpoints);
LIST_FOR_EACH_ENTRY(dev, list, PhysDevice, entry) { name_len = lstrlenW(dev->name) + 1; @@ -340,12 +339,12 @@ static NTSTATUS pulse_get_endpoint_ids(void *args) needed += name_len * sizeof(WCHAR) + ((len + 1) & ~1);
if (needed <= params->size) { - endpoint->name = (WCHAR*)ptr; - memcpy(endpoint->name, dev->name, name_len * sizeof(WCHAR)); - ptr += name_len * sizeof(WCHAR); - endpoint->pulse_name = ptr; - memcpy(endpoint->pulse_name, dev->pulse_name, len); - ptr += (len + 1) & ~1; + endpoint->name = offset; + memcpy((char *)params->endpoints + offset, dev->name, name_len * sizeof(WCHAR)); + offset += name_len * sizeof(WCHAR); + endpoint->pulse_name = offset; + memcpy((char *)params->endpoints + offset, dev->pulse_name, len); + offset += (len + 1) & ~1; endpoint++; } } diff --git a/dlls/winepulse.drv/unixlib.h b/dlls/winepulse.drv/unixlib.h index e09362f0751..8d48af7dedc 100644 --- a/dlls/winepulse.drv/unixlib.h +++ b/dlls/winepulse.drv/unixlib.h @@ -39,8 +39,8 @@ struct pulse_config
struct endpoint { - WCHAR *name; - char *pulse_name; + unsigned int name; + unsigned int pulse_name; };
struct main_loop_params
On Thu, Apr 14, 2022 at 10:03:10AM +0100, Huw Davies wrote:
--- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -457,13 +457,16 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, GUID **ke }
for (i = 0; i < params.num; i++) {
unsigned int size = (wcslen(params.endpoints[i].name) + 1) * sizeof(WCHAR);
WCHAR *name = (WCHAR *)((char *)params.endpoints + params.endpoints[i].name);
char *pulse_name = (char *)params.endpoints + params.endpoints[i].pulse_name;
It's unfortunate that we're losing type checking, both here and in the "use handles" patch:
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 7b5ef7cfe39..96b8b28d1b5 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -156,7 +156,7 @@ struct ACImpl { UINT32 channel_count; HANDLE timer;
- struct pulse_stream *pulse_stream;
unsigned int pulse_stream;
AudioSession *session; AudioSessionWrapper *session_wrapper;
Is there any way we could get compile-time type checking back? Using typedefs or something...?
Andrew
On Thu, Apr 14, 2022 at 02:38:29PM -0500, Andrew Eikum wrote:
On Thu, Apr 14, 2022 at 10:03:10AM +0100, Huw Davies wrote:
--- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -457,13 +457,16 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, GUID **ke }
for (i = 0; i < params.num; i++) {
unsigned int size = (wcslen(params.endpoints[i].name) + 1) * sizeof(WCHAR);
WCHAR *name = (WCHAR *)((char *)params.endpoints + params.endpoints[i].name);
char *pulse_name = (char *)params.endpoints + params.endpoints[i].pulse_name;
It's unfortunate that we're losing type checking, both here and in the "use handles" patch:
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 7b5ef7cfe39..96b8b28d1b5 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -156,7 +156,7 @@ struct ACImpl { UINT32 channel_count; HANDLE timer;
- struct pulse_stream *pulse_stream;
unsigned int pulse_stream;
AudioSession *session; AudioSessionWrapper *session_wrapper;
Is there any way we could get compile-time type checking back? Using typedefs or something...?
Using something like "typedef unsigned int stream" is of course possible, but that doesn't get you any type checking. I'd considered using HANDLE, but then almost every syscall will need a wow64 wrapper, so it didn't seem worth the extra complexity.
Likewise, the strings could be left as ptrs, but the wow64 wrapper for get_endpoint_ids is significantly more complicated.
Huw.
On 4/14/22 15:49, Huw Davies wrote:
On Thu, Apr 14, 2022 at 02:38:29PM -0500, Andrew Eikum wrote:
On Thu, Apr 14, 2022 at 10:03:10AM +0100, Huw Davies wrote:
--- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -457,13 +457,16 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, GUID **ke }
for (i = 0; i < params.num; i++) {
unsigned int size = (wcslen(params.endpoints[i].name) + 1) * sizeof(WCHAR);
WCHAR *name = (WCHAR *)((char *)params.endpoints + params.endpoints[i].name);
char *pulse_name = (char *)params.endpoints + params.endpoints[i].pulse_name;
It's unfortunate that we're losing type checking, both here and in the "use handles" patch:
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 7b5ef7cfe39..96b8b28d1b5 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -156,7 +156,7 @@ struct ACImpl { UINT32 channel_count; HANDLE timer;
- struct pulse_stream *pulse_stream;
unsigned int pulse_stream;
AudioSession *session; AudioSessionWrapper *session_wrapper;
Is there any way we could get compile-time type checking back? Using typedefs or something...?
Using something like "typedef unsigned int stream" is of course possible, but that doesn't get you any type checking. I'd considered using HANDLE, but then almost every syscall will need a wow64 wrapper, so it didn't seem worth the extra complexity.
Likewise, the strings could be left as ptrs, but the wow64 wrapper for get_endpoint_ids is significantly more complicated.
One possibility that comes to mind is to define it as a fixed-size structure, e.g.
struct pulse_stream_handle { unsigned int handle; };