[PATCH 01/16] [WinMM, MMSystem]: added partial infrastructure for driver management in mmsystem.c

Eric Pouech eric.pouech at orange.fr
Thu Oct 22 15:09:39 CDT 2009




A+
---

 0 files changed, 0 insertions(+), 0 deletions(-)


diff --git a/dlls/winmm/message16.c b/dlls/winmm/message16.c
index 98c9701..fe9e3b6 100644
--- a/dlls/winmm/message16.c
+++ b/dlls/winmm/message16.c
@@ -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, &param1, &param2);
+    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, &param1, &param2, ret);
+        break;
+    default:
+        FIXME("NIY\n");
+        ret = MMSYSERR_NOTSUPPORTED;
+        break;
+    }
+    return ret;
+}
diff --git a/dlls/winmm/mmsystem.c b/dlls/winmm/mmsystem.c
index d3214f7..4007d46 100644
--- a/dlls/winmm/mmsystem.c
+++ b/dlls/winmm/mmsystem.c
@@ -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                        #
  * ###################################################
diff --git a/dlls/winmm/winemm16.h b/dlls/winmm/winemm16.h
index 38dbdeb..97b03ef 100644
--- a/dlls/winmm/winemm16.h
+++ b/dlls/winmm/winemm16.h
@@ -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);






More information about the wine-patches mailing list