winealsa: Implement Wow64 midi entry points in the Unix library.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
aed23f1928
commit
a1fb139fac
|
@ -2869,9 +2869,9 @@ unixlib_entry_t __wine_unix_call_wow64_funcs[] =
|
|||
is_started,
|
||||
wow64_get_prop_value,
|
||||
midi_release,
|
||||
midi_out_message,
|
||||
midi_in_message,
|
||||
midi_notify_wait,
|
||||
wow64_midi_out_message,
|
||||
wow64_midi_in_message,
|
||||
wow64_midi_notify_wait,
|
||||
};
|
||||
|
||||
#endif /* _WIN64 */
|
||||
|
|
|
@ -1499,3 +1499,357 @@ NTSTATUS midi_notify_wait(void *args)
|
|||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
typedef UINT PTR32;
|
||||
|
||||
struct notify_context32
|
||||
{
|
||||
BOOL send_notify;
|
||||
WORD dev_id;
|
||||
WORD msg;
|
||||
UINT param_1;
|
||||
UINT param_2;
|
||||
UINT callback;
|
||||
UINT flags;
|
||||
PTR32 device;
|
||||
UINT instance;
|
||||
};
|
||||
|
||||
static void notify_to_notify32(struct notify_context32 *notify32,
|
||||
const struct notify_context *notify)
|
||||
{
|
||||
notify32->send_notify = notify->send_notify;
|
||||
notify32->dev_id = notify->dev_id;
|
||||
notify32->msg = notify->msg;
|
||||
notify32->param_1 = notify->param_1;
|
||||
notify32->param_2 = notify->param_2;
|
||||
notify32->callback = notify->callback;
|
||||
notify32->flags = notify->flags;
|
||||
notify32->device = PtrToUlong(notify->device);
|
||||
notify32->instance = notify->instance;
|
||||
}
|
||||
|
||||
struct midi_open_desc32
|
||||
{
|
||||
PTR32 hMidi;
|
||||
UINT dwCallback;
|
||||
UINT dwInstance;
|
||||
UINT dnDevNode;
|
||||
UINT cIds;
|
||||
MIDIOPENSTRMID rgIds;
|
||||
};
|
||||
|
||||
struct midi_hdr32
|
||||
{
|
||||
PTR32 lpData;
|
||||
UINT dwBufferLength;
|
||||
UINT dwBytesRecorded;
|
||||
UINT dwUser;
|
||||
UINT dwFlags;
|
||||
PTR32 lpNext;
|
||||
UINT reserved;
|
||||
UINT dwOffset;
|
||||
UINT dwReserved[8];
|
||||
};
|
||||
|
||||
static UINT wow64_midi_out_prepare(WORD dev_id, struct midi_hdr32 *hdr, UINT hdr_size)
|
||||
{
|
||||
TRACE("(%04X, %p, %d);\n", dev_id, hdr, hdr_size);
|
||||
|
||||
if (hdr_size < offsetof(struct midi_hdr32, dwOffset) || !hdr || !hdr->lpData)
|
||||
return MMSYSERR_INVALPARAM;
|
||||
if (hdr->dwFlags & MHDR_PREPARED)
|
||||
return MMSYSERR_NOERROR;
|
||||
|
||||
hdr->lpNext = 0;
|
||||
hdr->dwFlags |= MHDR_PREPARED;
|
||||
hdr->dwFlags &= ~(MHDR_DONE | MHDR_INQUEUE);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static UINT wow64_midi_out_unprepare(WORD dev_id, struct midi_hdr32 *hdr, UINT hdr_size)
|
||||
{
|
||||
TRACE("(%04X, %p, %d);\n", dev_id, hdr, hdr_size);
|
||||
|
||||
if (hdr_size < offsetof(struct midi_hdr32, dwOffset) || !hdr || !hdr->lpData)
|
||||
return MMSYSERR_INVALPARAM;
|
||||
if (!(hdr->dwFlags & MHDR_PREPARED))
|
||||
return MMSYSERR_NOERROR;
|
||||
if (hdr->dwFlags & MHDR_INQUEUE)
|
||||
return MIDIERR_STILLPLAYING;
|
||||
|
||||
hdr->dwFlags &= ~MHDR_PREPARED;
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
NTSTATUS wow64_midi_out_message(void *args)
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT dev_id;
|
||||
UINT msg;
|
||||
UINT user;
|
||||
UINT param_1;
|
||||
UINT param_2;
|
||||
PTR32 err;
|
||||
PTR32 notify;
|
||||
} *params32 = args;
|
||||
struct notify_context32 *notify32 = ULongToPtr(params32->notify);
|
||||
struct midi_open_desc32 *desc32;
|
||||
struct midi_hdr32 *hdr32;
|
||||
struct notify_context notify;
|
||||
MIDIOPENDESC open_desc;
|
||||
MIDIHDR hdr;
|
||||
struct midi_out_message_params params =
|
||||
{
|
||||
.dev_id = params32->dev_id,
|
||||
.msg = params32->msg,
|
||||
.user = params32->user,
|
||||
.param_1 = params32->param_1,
|
||||
.param_2 = params32->param_2,
|
||||
.err = ULongToPtr(params32->err),
|
||||
.notify = ¬ify
|
||||
};
|
||||
notify32->send_notify = FALSE;
|
||||
|
||||
switch (params32->msg)
|
||||
{
|
||||
case MODM_OPEN:
|
||||
desc32 = ULongToPtr(params32->param_1);
|
||||
|
||||
open_desc.hMidi = ULongToPtr(desc32->hMidi);
|
||||
open_desc.dwCallback = desc32->dwCallback;
|
||||
open_desc.dwInstance = desc32->dwInstance;
|
||||
open_desc.dnDevNode = desc32->dnDevNode;
|
||||
open_desc.cIds = desc32->cIds;
|
||||
open_desc.rgIds.dwStreamID = desc32->rgIds.dwStreamID;
|
||||
open_desc.rgIds.wDeviceID = desc32->rgIds.wDeviceID;
|
||||
|
||||
params.param_1 = (UINT_PTR)&open_desc;
|
||||
break;
|
||||
|
||||
case MODM_LONGDATA:
|
||||
hdr32 = ULongToPtr(params32->param_1);
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
hdr.lpData = ULongToPtr(hdr32->lpData);
|
||||
hdr.dwBufferLength = hdr32->dwBufferLength;
|
||||
hdr.dwFlags = hdr32->dwFlags;
|
||||
|
||||
params.param_1 = (UINT_PTR)&hdr;
|
||||
params.param_2 = sizeof(hdr);
|
||||
break;
|
||||
|
||||
case MODM_PREPARE: /* prepare and unprepare are easier to handle explicitly */
|
||||
hdr32 = ULongToPtr(params32->param_1);
|
||||
|
||||
*params.err = wow64_midi_out_prepare(params32->dev_id, hdr32, params32->param_2);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case MODM_UNPREPARE:
|
||||
hdr32 = ULongToPtr(params32->param_1);
|
||||
|
||||
*params.err = wow64_midi_out_unprepare(params32->dev_id, hdr32, params32->param_2);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
midi_out_message(¶ms);
|
||||
|
||||
switch (params32->msg)
|
||||
{
|
||||
case MODM_LONGDATA:
|
||||
hdr32 = ULongToPtr(params32->param_1);
|
||||
|
||||
hdr32->dwFlags = hdr.dwFlags;
|
||||
break;
|
||||
}
|
||||
|
||||
if (notify.send_notify)
|
||||
{
|
||||
notify_to_notify32(notify32, ¬ify);
|
||||
|
||||
if (notify.msg == MOM_DONE)
|
||||
notify32->param_1 = params32->param_1; /* restore the 32-bit hdr */
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT wow64_midi_in_prepare(WORD dev_id, struct midi_hdr32 *hdr, UINT hdr_size)
|
||||
{
|
||||
TRACE("(%04X, %p, %d);\n", dev_id, hdr, hdr_size);
|
||||
|
||||
if (hdr_size < offsetof(struct midi_hdr32, dwOffset) || !hdr || !hdr->lpData)
|
||||
return MMSYSERR_INVALPARAM;
|
||||
if (hdr->dwFlags & MHDR_PREPARED)
|
||||
return MMSYSERR_NOERROR;
|
||||
|
||||
hdr->lpNext = 0;
|
||||
hdr->dwFlags |= MHDR_PREPARED;
|
||||
hdr->dwFlags &= ~(MHDR_DONE | MHDR_INQUEUE);
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static UINT wow64_midi_in_unprepare(WORD dev_id, struct midi_hdr32 *hdr, UINT hdr_size)
|
||||
{
|
||||
TRACE("(%04X, %p, %d);\n", dev_id, hdr, hdr_size);
|
||||
|
||||
if (hdr_size < offsetof(struct midi_hdr32, dwOffset) || !hdr || !hdr->lpData)
|
||||
return MMSYSERR_INVALPARAM;
|
||||
if (!(hdr->dwFlags & MHDR_PREPARED))
|
||||
return MMSYSERR_NOERROR;
|
||||
if (hdr->dwFlags & MHDR_INQUEUE)
|
||||
return MIDIERR_STILLPLAYING;
|
||||
|
||||
hdr->dwFlags &= ~MHDR_PREPARED;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
NTSTATUS wow64_midi_in_message(void *args)
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT dev_id;
|
||||
UINT msg;
|
||||
UINT user;
|
||||
UINT param_1;
|
||||
UINT param_2;
|
||||
PTR32 err;
|
||||
PTR32 notify;
|
||||
} *params32 = args;
|
||||
struct notify_context32 *notify32 = ULongToPtr(params32->notify);
|
||||
struct midi_open_desc32 *desc32;
|
||||
struct midi_hdr32 *hdr32;
|
||||
struct notify_context notify;
|
||||
MIDIOPENDESC open_desc;
|
||||
MIDIHDR *hdr = NULL;
|
||||
struct midi_in_message_params params =
|
||||
{
|
||||
.dev_id = params32->dev_id,
|
||||
.msg = params32->msg,
|
||||
.user = params32->user,
|
||||
.param_1 = params32->param_1,
|
||||
.param_2 = params32->param_2,
|
||||
.err = ULongToPtr(params32->err),
|
||||
.notify = ¬ify
|
||||
};
|
||||
notify32->send_notify = FALSE;
|
||||
|
||||
switch (params32->msg)
|
||||
{
|
||||
case MIDM_OPEN:
|
||||
desc32 = ULongToPtr(params32->param_1);
|
||||
|
||||
open_desc.hMidi = ULongToPtr(desc32->hMidi);
|
||||
open_desc.dwCallback = desc32->dwCallback;
|
||||
open_desc.dwInstance = desc32->dwInstance;
|
||||
open_desc.dnDevNode = desc32->dnDevNode;
|
||||
open_desc.cIds = desc32->cIds;
|
||||
open_desc.rgIds.dwStreamID = desc32->rgIds.dwStreamID;
|
||||
open_desc.rgIds.wDeviceID = desc32->rgIds.wDeviceID;
|
||||
|
||||
params.param_1 = (UINT_PTR)&open_desc;
|
||||
break;
|
||||
|
||||
case MIDM_ADDBUFFER:
|
||||
hdr32 = ULongToPtr(params32->param_1);
|
||||
|
||||
hdr = calloc(1, sizeof(*hdr));
|
||||
hdr->lpData = ULongToPtr(hdr32->lpData);
|
||||
hdr->dwBufferLength = hdr32->dwBufferLength;
|
||||
hdr->dwFlags = hdr32->dwFlags;
|
||||
hdr->dwReserved[7] = params32->param_1; /* keep hdr32 for MIM_LONGDATA notification */
|
||||
|
||||
params.param_1 = (UINT_PTR)hdr;
|
||||
params.param_2 = sizeof(*hdr);
|
||||
break;
|
||||
|
||||
case MIDM_PREPARE: /* prepare and unprepare are easier to handle explicitly */
|
||||
hdr32 = ULongToPtr(params32->param_1);
|
||||
|
||||
*params.err = wow64_midi_in_prepare(params32->dev_id, hdr32, params32->param_2);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case MIDM_UNPREPARE:
|
||||
hdr32 = ULongToPtr(params32->param_1);
|
||||
|
||||
*params.err = wow64_midi_in_unprepare(params32->dev_id, hdr32, params32->param_2);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
midi_in_message(¶ms);
|
||||
|
||||
switch (params32->msg)
|
||||
{
|
||||
case MIDM_ADDBUFFER:
|
||||
hdr32 = ULongToPtr(params32->param_1);
|
||||
|
||||
if (!*params.err)
|
||||
{
|
||||
hdr32->dwFlags = hdr->dwFlags;
|
||||
hdr32->dwBytesRecorded = hdr->dwBytesRecorded;
|
||||
hdr32->lpNext = 0;
|
||||
}
|
||||
else
|
||||
free(hdr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (notify.send_notify)
|
||||
{
|
||||
notify_to_notify32(notify32, ¬ify);
|
||||
|
||||
if (notify.msg == MIM_LONGDATA)
|
||||
{
|
||||
hdr = (MIDIHDR *)notify.param_1;
|
||||
notify32->param_1 = hdr->dwReserved[7];
|
||||
hdr32 = ULongToPtr(notify32->param_1);
|
||||
hdr32->dwBytesRecorded = hdr->dwBytesRecorded;
|
||||
hdr32->dwFlags = hdr->dwFlags;
|
||||
free(hdr);
|
||||
}
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS wow64_midi_notify_wait(void *args)
|
||||
{
|
||||
struct
|
||||
{
|
||||
PTR32 quit;
|
||||
PTR32 notify;
|
||||
} *params32 = args;
|
||||
struct notify_context32 *notify32 = ULongToPtr(params32->notify);
|
||||
struct midi_hdr32 *hdr32;
|
||||
struct notify_context notify;
|
||||
MIDIHDR *hdr;
|
||||
struct midi_notify_wait_params params =
|
||||
{
|
||||
.quit = ULongToPtr(params32->quit),
|
||||
.notify = ¬ify
|
||||
};
|
||||
notify32->send_notify = FALSE;
|
||||
|
||||
midi_notify_wait(¶ms);
|
||||
|
||||
if (!*params.quit && notify.send_notify)
|
||||
{
|
||||
notify_to_notify32(notify32, ¬ify);
|
||||
|
||||
if (notify.msg == MIM_LONGDATA)
|
||||
{
|
||||
hdr = (MIDIHDR *)notify.param_1;
|
||||
notify32->param_1 = hdr->dwReserved[7];
|
||||
hdr32 = ULongToPtr(notify32->param_1);
|
||||
hdr32->dwBytesRecorded = hdr->dwBytesRecorded;
|
||||
hdr32->dwFlags = hdr->dwFlags;
|
||||
free(hdr);
|
||||
}
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* _WIN64 */
|
||||
|
|
|
@ -284,6 +284,12 @@ NTSTATUS midi_out_message(void *args) DECLSPEC_HIDDEN;
|
|||
NTSTATUS midi_in_message(void *args) DECLSPEC_HIDDEN;
|
||||
NTSTATUS 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;
|
||||
#endif
|
||||
|
||||
extern unixlib_handle_t alsa_handle;
|
||||
|
||||
#define ALSA_CALL(func, params) __wine_unix_call(alsa_handle, alsa_ ## func, params)
|
||||
|
|
Loading…
Reference in New Issue