mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 14:40:56 +00:00
winmm: Added partial infrastructure for driver management in mmsystem.c.
This commit is contained in:
parent
e58ebbf3e0
commit
60b652cd4e
@ -2545,3 +2545,218 @@ MMDRV_##_y##_Callback)
|
||||
pFnMciMapMsg32WTo16 = MCI_MapMsg32WTo16;
|
||||
pFnMciUnMapMsg32WTo16 = MCI_UnMapMsg32WTo16;
|
||||
}
|
||||
|
||||
/* ###################################################
|
||||
* # DRIVER THUNKING #
|
||||
* ###################################################
|
||||
*/
|
||||
typedef MMSYSTEM_MapType (*MMSYSTDRV_MAPMSG)(UINT wMsg, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2);
|
||||
typedef MMSYSTEM_MapType (*MMSYSTDRV_UNMAPMSG)(UINT wMsg, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT ret);
|
||||
typedef void (*MMSYSTDRV_MAPCB)(DWORD wMsg, DWORD_PTR* dwUser, DWORD_PTR* dwParam1, DWORD_PTR* dwParam2);
|
||||
|
||||
#include <pshpack1.h>
|
||||
#define MMSYSTDRV_MAX_THUNKS 32
|
||||
|
||||
static struct mmsystdrv_thunk
|
||||
{
|
||||
BYTE popl_eax; /* popl %eax (return address) */
|
||||
BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */
|
||||
struct mmsystdrv_thunk* this;
|
||||
BYTE pushl_eax; /* pushl %eax */
|
||||
BYTE jmp; /* ljmp MMDRV_Callback1632 */
|
||||
DWORD callback;
|
||||
DWORD pfn16;
|
||||
void* hMmdrv; /* Handle to 32bit mmdrv object */
|
||||
enum MMSYSTEM_DriverType kind;
|
||||
} *MMSYSTDRV_Thunks;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
static struct MMSYSTDRV_Type
|
||||
{
|
||||
MMSYSTDRV_MAPMSG mapmsg16to32W;
|
||||
MMSYSTDRV_UNMAPMSG unmapmsg16to32W;
|
||||
MMSYSTDRV_MAPCB mapcb;
|
||||
} MMSYSTEM_DriversType[MMSYSTDRV_MAX] =
|
||||
{
|
||||
};
|
||||
|
||||
/******************************************************************
|
||||
* MMSYSTDRV_Callback3216
|
||||
*
|
||||
*/
|
||||
static LRESULT CALLBACK MMSYSTDRV_Callback3216(struct mmsystdrv_thunk* thunk, DWORD uFlags, HDRVR hDev,
|
||||
DWORD wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1,
|
||||
DWORD_PTR dwParam2)
|
||||
{
|
||||
assert(thunk->kind < MMSYSTDRV_MAX);
|
||||
assert(MMSYSTEM_DriversType[thunk->kind].mapcb);
|
||||
|
||||
MMSYSTEM_DriversType[thunk->kind].mapcb(wMsg, &dwUser, &dwParam1, &dwParam2);
|
||||
|
||||
if ((uFlags & DCB_TYPEMASK) == DCB_FUNCTION)
|
||||
{
|
||||
WORD args[8];
|
||||
/* 16 bit func, call it */
|
||||
TRACE("Function (16 bit) !\n");
|
||||
|
||||
args[7] = HDRVR_16(hDev);
|
||||
args[6] = wMsg;
|
||||
args[5] = HIWORD(dwUser);
|
||||
args[4] = LOWORD(dwUser);
|
||||
args[3] = HIWORD(dwParam1);
|
||||
args[2] = LOWORD(dwParam1);
|
||||
args[1] = HIWORD(dwParam2);
|
||||
args[0] = LOWORD(dwParam2);
|
||||
return WOWCallback16Ex(thunk->pfn16, WCB16_PASCAL, sizeof(args), args, NULL);
|
||||
}
|
||||
return DriverCallback(thunk->pfn16, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* MMSYSTDRV_AddThunk
|
||||
*
|
||||
*/
|
||||
struct mmsystdrv_thunk* MMSYSTDRV_AddThunk(DWORD pfn16, enum MMSYSTEM_DriverType kind)
|
||||
{
|
||||
struct mmsystdrv_thunk* thunk;
|
||||
|
||||
EnterCriticalSection(&mmdrv_cs);
|
||||
if (!MMSYSTDRV_Thunks)
|
||||
{
|
||||
MMSYSTDRV_Thunks = VirtualAlloc(NULL, MMSYSTDRV_MAX_THUNKS * sizeof(*MMSYSTDRV_Thunks),
|
||||
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (!MMSYSTDRV_Thunks)
|
||||
{
|
||||
LeaveCriticalSection(&mmdrv_cs);
|
||||
return NULL;
|
||||
}
|
||||
for (thunk = MMSYSTDRV_Thunks; thunk < &MMSYSTDRV_Thunks[MMSYSTDRV_MAX_THUNKS]; thunk++)
|
||||
{
|
||||
thunk->popl_eax = 0x58; /* popl %eax */
|
||||
thunk->pushl_func = 0x68; /* pushl $pfn16 */
|
||||
thunk->this = thunk;
|
||||
thunk->pushl_eax = 0x50; /* pushl %eax */
|
||||
thunk->jmp = 0xe9; /* jmp MMDRV_Callback3216 */
|
||||
thunk->callback = (char *)MMSYSTDRV_Callback3216 - (char *)(&thunk->callback + 1);
|
||||
thunk->pfn16 = 0;
|
||||
thunk->hMmdrv = NULL;
|
||||
thunk->kind = MMSYSTDRV_MAX;
|
||||
}
|
||||
}
|
||||
for (thunk = MMSYSTDRV_Thunks; thunk < &MMSYSTDRV_Thunks[MMSYSTDRV_MAX_THUNKS]; thunk++)
|
||||
{
|
||||
if (thunk->pfn16 == 0 && thunk->hMmdrv == NULL)
|
||||
{
|
||||
thunk->pfn16 = pfn16;
|
||||
thunk->hMmdrv = NULL;
|
||||
thunk->kind = kind;
|
||||
LeaveCriticalSection(&mmdrv_cs);
|
||||
return thunk;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&mmdrv_cs);
|
||||
FIXME("Out of mmdrv-thunks. Bump MMDRV_MAX_THUNKS\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* MMSYSTDRV_FindHandle
|
||||
*
|
||||
* Must be called with lock set
|
||||
*/
|
||||
static void* MMSYSTDRV_FindHandle(void* h)
|
||||
{
|
||||
struct mmsystdrv_thunk* thunk;
|
||||
|
||||
for (thunk = MMSYSTDRV_Thunks; thunk < &MMSYSTDRV_Thunks[MMSYSTDRV_MAX_THUNKS]; thunk++)
|
||||
{
|
||||
if (thunk->hMmdrv == h)
|
||||
{
|
||||
if (thunk->kind >= MMSYSTDRV_MAX) FIXME("Kind isn't properly initialized %x\n", thunk->kind);
|
||||
return thunk;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* MMSYSTDRV_SetHandle
|
||||
*
|
||||
*/
|
||||
void MMSYSTDRV_SetHandle(struct mmsystdrv_thunk* thunk, void* h)
|
||||
{
|
||||
if (MMSYSTDRV_FindHandle(h)) FIXME("Already has a thunk for this handle %p!!!\n", h);
|
||||
thunk->hMmdrv = h;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* MMSYSTDRV_DeleteThunk
|
||||
*/
|
||||
void MMSYSTDRV_DeleteThunk(struct mmsystdrv_thunk* thunk)
|
||||
{
|
||||
thunk->pfn16 = 0;
|
||||
thunk->hMmdrv = NULL;
|
||||
thunk->kind = MMSYSTDRV_MAX;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* MMSYSTDRV_CloseHandle
|
||||
*/
|
||||
void MMSYSTDRV_CloseHandle(void* h)
|
||||
{
|
||||
struct mmsystdrv_thunk* thunk;
|
||||
|
||||
EnterCriticalSection(&mmdrv_cs);
|
||||
if ((thunk = MMSYSTDRV_FindHandle(h)))
|
||||
{
|
||||
MMSYSTDRV_DeleteThunk(thunk);
|
||||
}
|
||||
LeaveCriticalSection(&mmdrv_cs);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* MMSYSTDRV_Message
|
||||
*/
|
||||
DWORD MMSYSTDRV_Message(void* h, UINT msg, DWORD_PTR param1, DWORD_PTR param2)
|
||||
{
|
||||
struct mmsystdrv_thunk* thunk = MMSYSTDRV_FindHandle(h);
|
||||
struct MMSYSTDRV_Type* drvtype;
|
||||
MMSYSTEM_MapType map;
|
||||
DWORD ret;
|
||||
|
||||
if (!thunk) return MMSYSERR_INVALHANDLE;
|
||||
drvtype = &MMSYSTEM_DriversType[thunk->kind];
|
||||
|
||||
map = drvtype->mapmsg16to32W(msg, ¶m1, ¶m2);
|
||||
switch (map) {
|
||||
case MMSYSTEM_MAP_NOMEM:
|
||||
ret = MMSYSERR_NOMEM;
|
||||
break;
|
||||
case MMSYSTEM_MAP_MSGERROR:
|
||||
FIXME("NIY: no conversion yet 16->32 kind=%u msg=%u\n", thunk->kind, msg);
|
||||
ret = MMSYSERR_ERROR;
|
||||
break;
|
||||
case MMSYSTEM_MAP_OK:
|
||||
case MMSYSTEM_MAP_OKMEM:
|
||||
TRACE("Calling message(msg=%u p1=0x%08lx p2=0x%08lx)\n",
|
||||
msg, param1, param2);
|
||||
switch (thunk->kind)
|
||||
{
|
||||
case MMSYSTDRV_MIXER: ret = mixerMessage (h, msg, param1, param2); break;
|
||||
case MMSYSTDRV_MIDIIN: ret = midiInMessage (h, msg, param1, param2); break;
|
||||
case MMSYSTDRV_MIDIOUT: ret = midiOutMessage(h, msg, param1, param2); break;
|
||||
case MMSYSTDRV_WAVEIN: ret = waveInMessage (h, msg, param1, param2); break;
|
||||
case MMSYSTDRV_WAVEOUT: ret = waveOutMessage(h, msg, param1, param2); break;
|
||||
default: ret = MMSYSERR_INVALHANDLE; break; /* should never be reached */
|
||||
}
|
||||
if (map == MMSYSTEM_MAP_OKMEM)
|
||||
drvtype->unmapmsg16to32W(msg, ¶m1, ¶m2, ret);
|
||||
break;
|
||||
default:
|
||||
FIXME("NIY\n");
|
||||
ret = MMSYSERR_NOTSUPPORTED;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -52,14 +52,13 @@ static LPWINE_DRIVER DRIVER_OpenDriver16(LPCWSTR, LPCWSTR, LPARAM);
|
||||
static LRESULT DRIVER_CloseDriver16(HDRVR16, LPARAM, LPARAM);
|
||||
static LRESULT DRIVER_SendMessage16(HDRVR16, UINT, LPARAM, LPARAM);
|
||||
|
||||
static CRITICAL_SECTION mmdrv_cs;
|
||||
static CRITICAL_SECTION_DEBUG mmdrv_critsect_debug =
|
||||
{
|
||||
0, 0, &mmdrv_cs,
|
||||
{ &mmdrv_critsect_debug.ProcessLocksList, &mmdrv_critsect_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": mmsystem_mmdrv_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION mmdrv_cs = { &mmdrv_critsect_debug, -1, 0, 0, 0, 0 };
|
||||
CRITICAL_SECTION mmdrv_cs = { &mmdrv_critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/* ###################################################
|
||||
* # LIBRARY #
|
||||
@ -201,7 +200,6 @@ void WINAPI OutputDebugStr16(LPCSTR str)
|
||||
OutputDebugStringA( str );
|
||||
}
|
||||
|
||||
|
||||
/* ###################################################
|
||||
* # MIXER #
|
||||
* ###################################################
|
||||
|
@ -61,3 +61,21 @@ typedef enum {
|
||||
MMSYSTEM_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
|
||||
MMSYSTEM_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
|
||||
} MMSYSTEM_MapType;
|
||||
|
||||
extern CRITICAL_SECTION mmdrv_cs;
|
||||
|
||||
enum MMSYSTEM_DriverType
|
||||
{
|
||||
MMSYSTDRV_MIXER,
|
||||
MMSYSTDRV_MIDIIN,
|
||||
MMSYSTDRV_MIDIOUT,
|
||||
MMSYSTDRV_WAVEIN,
|
||||
MMSYSTDRV_WAVEOUT,
|
||||
MMSYSTDRV_MAX
|
||||
};
|
||||
|
||||
extern struct mmsystdrv_thunk* MMSYSTDRV_AddThunk(DWORD pfn16, enum MMSYSTEM_DriverType kind);
|
||||
extern void MMSYSTDRV_DeleteThunk(struct mmsystdrv_thunk* thunk);
|
||||
extern void MMSYSTDRV_SetHandle(struct mmsystdrv_thunk* thunk, void* h);
|
||||
extern void MMSYSTDRV_CloseHandle(void* h);
|
||||
extern DWORD MMSYSTDRV_Message(void* h, UINT msg, DWORD_PTR param1, DWORD_PTR param2);
|
||||
|
Loading…
Reference in New Issue
Block a user