[PATCH 1/2] [Msvfw32]: clearly separate the 16bit code out of the rest by wrapping 16bit message functions in thunks

Eric Pouech eric.pouech at orange.fr
Thu May 14 14:36:29 CDT 2009




A+
---

 dlls/msvfw32/msvideo16.c       |  242 ++++++++++++++++++++++++----------------
 dlls/msvfw32/msvideo_main.c    |   37 ++----
 dlls/msvfw32/msvideo_private.h |   14 --
 3 files changed, 159 insertions(+), 134 deletions(-)


diff --git a/dlls/msvfw32/msvideo16.c b/dlls/msvfw32/msvideo16.c
index c873da5..69321f5 100644
--- a/dlls/msvfw32/msvideo16.c
+++ b/dlls/msvfw32/msvideo16.c
@@ -30,7 +30,6 @@
 #include "winreg.h"
 #include "winuser.h"
 #include "vfw16.h"
-#include "msvideo_private.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
@@ -38,6 +37,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
 /* Drivers32 settings */
 #define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
 
+/* handle16 --> handle conversions */
+#define HDRAWDIB_32(h16)	((HDRAWDIB)(ULONG_PTR)(h16))
+#define HIC_32(h16)		((HIC)(ULONG_PTR)(h16))
+
+/* handle --> handle16 conversions */
+#define HDRVR_16(h32)		(LOWORD(h32))
+#define HDRAWDIB_16(h32)	(LOWORD(h32))
+#define HIC_16(h32)		(LOWORD(h32))
+
 /***********************************************************************
  *		DrawDibOpen		[MSVIDEO.102]
  */
@@ -135,14 +143,6 @@ HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode)
 }
 
 /***********************************************************************
- *		ICClose			[MSVIDEO.204]
- */
-LRESULT WINAPI ICClose16(HIC16 hic)
-{
-    return ICClose(HIC_32(hic));
-}
-
-/***********************************************************************
  *		_ICMessage			[MSVIDEO.207]
  */
 LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist )
@@ -670,40 +670,99 @@ BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo)
  *
  *
  */
-static  LRESULT CALLBACK  IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD lp1, DWORD lp2)
+static  LRESULT CALLBACK  IC_Callback3216(DWORD pfn16, HIC hic, HDRVR hdrv, UINT msg, DWORD lp1, DWORD lp2)
 {
-    WINE_HIC*   whic;
     WORD args[8];
+    DWORD ret = 0;
+
+    switch (msg)
+    {
+    case DRV_OPEN:
+        lp2 = (DWORD)MapLS((void*)lp2);
+        break;
+    }
+    args[7] = HIWORD(hic);
+    args[6] = LOWORD(hic);
+    args[5] = HDRVR_16(hdrv);
+    args[4] = msg;
+    args[3] = HIWORD(lp1);
+    args[2] = LOWORD(lp1);
+    args[1] = HIWORD(lp2);
+    args[0] = LOWORD(lp2);
+    WOWCallback16Ex( pfn16, WCB16_PASCAL, sizeof(args), args, &ret );
+
+    switch (msg)
+    {
+    case DRV_OPEN:
+        UnMapLS(lp2);
+        break;
+    }
+    return ret;
+}
+
+#define MAX_THUNKS      32
+
+static struct msvideo_thunk
+{
+    BYTE        popl_eax;        /* popl  %eax (return address) */
+    BYTE        pushl_func;      /* pushl $pfn16 (16bit callback function) */
+    DWORD       pfn16;
+    BYTE        pushl_eax;       /* pushl %eax */
+    BYTE        jmp;             /* ljmp WDML_InvokeCallback16 */
+    DWORD       callback;
+    HIC16       hIC16;           /* driver's handle */
+} *MSVIDEO_Thunks;
+
+static CRITICAL_SECTION msvideo_cs;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+    0, 0, &msvideo_cs,
+    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": msvideo_cs") }
+};
+static CRITICAL_SECTION msvideo_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
 
-    whic = MSVIDEO_GetHicPtr(hic);
-    if (whic)
+static struct msvideo_thunk*      MSVIDEO_AddThunk(DWORD pfn16)
+{
+    struct msvideo_thunk* thunk;
+
+    if (!MSVIDEO_Thunks)
     {
-        DWORD ret = 0;
-        switch (msg)
+        MSVIDEO_Thunks = VirtualAlloc(NULL, MAX_THUNKS * sizeof(*MSVIDEO_Thunks), MEM_COMMIT,
+                                      PAGE_EXECUTE_READWRITE);
+        if (!MSVIDEO_Thunks) return NULL;
+        for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
         {
-        case DRV_OPEN:
-            lp2 = (DWORD)MapLS((void*)lp2);
-            break;
+            thunk->popl_eax     = 0x58;   /* popl  %eax */
+            thunk->pushl_func   = 0x68;   /* pushl $pfn16 */
+            thunk->pfn16        = 0;
+            thunk->pushl_eax    = 0x50;   /* pushl %eax */
+            thunk->jmp          = 0xe9;   /* jmp IC_Callback3216 */
+            thunk->callback     = (char *)IC_Callback3216 - (char *)(&thunk->callback + 1);
+            thunk->hIC16        = 0;
         }
-        args[7] = HIWORD(hic);
-        args[6] = LOWORD(hic);
-        args[5] = HDRVR_16(whic->hdrv);
-        args[4] = msg;
-        args[3] = HIWORD(lp1);
-        args[2] = LOWORD(lp1);
-        args[1] = HIWORD(lp2);
-        args[0] = LOWORD(lp2);
-        WOWCallback16Ex( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &ret );
-
-        switch (msg)
+    }
+    for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
+    {
+        if (thunk->pfn16 == 0)
         {
-        case DRV_OPEN:
-            UnMapLS(lp2);
-            break;
+            thunk->pfn16 = pfn16;
+            return thunk;
         }
-        return ret;
     }
-    else return ICERR_BADHANDLE;
+    FIXME("Out of msvideo-thunks. Bump MAX_THUNKS\n");
+    return NULL;
+}
+
+static struct msvideo_thunk*    MSVIDEO_HasThunk(HIC16 hic)
+{
+    struct msvideo_thunk* thunk;
+
+    for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
+    {
+        if (thunk->hIC16 == hic) return thunk;
+    }
+    return NULL;
 }
 
 /***********************************************************************
@@ -712,9 +771,15 @@ static  LRESULT CALLBACK  IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD l
 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
 {
     HIC         hic32;
+    struct msvideo_thunk*       thunk;
 
-    hic32 = MSVIDEO_OpenFunction(fccType, fccHandler, wMode, 
-                                 (DRIVERPROC)IC_Callback3216, (DWORD)lpfnHandler);
+    EnterCriticalSection(&msvideo_cs);
+    if (!(thunk = MSVIDEO_AddThunk((DWORD)lpfnHandler))) return 0;
+    if ((hic32 = ICOpenFunction(fccType, fccHandler, wMode, IC_Callback3216)))
+        thunk->hIC16 = HIC_16(hic32);
+    else
+        thunk->pfn16 = 0;
+    LeaveCriticalSection(&msvideo_cs);
     return HIC_16(hic32);
 }
 
@@ -724,40 +789,57 @@ HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FAR
 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) 
 {
     LRESULT     ret = ICERR_BADHANDLE;
-    WINE_HIC*   whic;
+    struct msvideo_thunk* thunk;
 
-    whic = MSVIDEO_GetHicPtr(HIC_32(hic));
-    if (whic)
+    if ((thunk = MSVIDEO_HasThunk(hic)))
     {
-        /* we've got a 16 bit driver proc... call it directly */
-        if (whic->driverproc16)
-        {
-            WORD args[8];
-            DWORD result;
-
-            /* FIXME: original code was passing hdrv first and hic second */
-            /* but this doesn't match what IC_Callback3216 does */
-            args[7] = HIWORD(hic);
-            args[6] = LOWORD(hic);
-            args[5] = HDRVR_16(whic->hdrv);
-            args[4] = msg;
-            args[3] = HIWORD(lParam1);
-            args[2] = LOWORD(lParam1);
-            args[1] = HIWORD(lParam2);
-            args[0] = LOWORD(lParam2);
-            WOWCallback16Ex( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &result );
-            ret = result;
-        }
-        else
+        WORD args[8];
+        DWORD result;
+
+        /* FIXME: original code was passing hdrv first and hic second */
+        /* but this doesn't match what IC_Callback3216 does */
+        args[7] = HIWORD(hic);
+        args[6] = LOWORD(hic);
+        args[5] = 0; /* the 32bit also sets it to NULL */
+        args[4] = msg;
+        args[3] = HIWORD(lParam1);
+        args[2] = LOWORD(lParam1);
+        args[1] = HIWORD(lParam2);
+        args[0] = LOWORD(lParam2);
+        WOWCallback16Ex( thunk->pfn16, WCB16_PASCAL, sizeof(args), args, &result );
+        ret = result;
+    }
+    else
+    {
+        /* map the message for a 32 bit infrastructure, and pass it along */
+        void*       data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2);
+
+        ret = ICSendMessage(HIC_32(hic), msg, lParam1, lParam2);
+        if (data16)
+            MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *		ICClose			[MSVIDEO.204]
+ */
+LRESULT WINAPI ICClose16(HIC16 hic)
+{
+    BOOL ret = ICClose(HIC_32(hic));
+
+    EnterCriticalSection(&msvideo_cs);
+    if (ret)
+    {
+        struct msvideo_thunk* thunk;
+        if ((thunk = MSVIDEO_HasThunk(hic)))
         {
-            /* map the message for a 32 bit infrastructure, and pass it along */
-            void*       data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2);
-    
-            ret = MSVIDEO_SendMessage(whic, msg, lParam1, lParam2);
-            if (data16)
-                MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
+            thunk->pfn16 = 0;
+            thunk->hIC16 = 0;
         }
+        else ret = FALSE;
     }
+    LeaveCriticalSection(&msvideo_cs);
     return ret;
 }
 
@@ -863,32 +945,6 @@ DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
     return 0;
 }
 
-/******************************************************************
- *		IC_CallTo16
- *
- *
- */
-static  LRESULT CALLBACK IC_CallTo16(HDRVR hdrv, HIC hic, UINT msg, LPARAM lp1, LPARAM lp2)
-{
-#if 0
-    WINE_HIC*   whic = IC_GetPtr(hic);
-    LRESULT     ret = 0;
-    
-    
-    if (whic->driverproc) 
-    {
-        ret = whic->driverproc(hic, whic->hdrv, msg, lParam1, lParam2);
-    }
-    else
-    {
-        ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2);
-    }
-#else
-    FIXME("No 32=>16 conversion yet\n");
-#endif
-    return 0;
-}
-
 /**************************************************************************
  *                      DllEntryPoint (MSVIDEO.3)
  *
@@ -901,12 +957,8 @@ BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
     switch (fdwReason) 
     {
     case DLL_PROCESS_ATTACH:
-        /* hook in our 16 bit management functions */
-        pFnCallTo16 = IC_CallTo16;
         break;
     case DLL_PROCESS_DETACH:
-        /* remove our 16 bit management functions */
-        pFnCallTo16 = NULL;
         break;
     case DLL_THREAD_ATTACH:
     case DLL_THREAD_DETACH:
diff --git a/dlls/msvfw32/msvideo_main.c b/dlls/msvfw32/msvideo_main.c
index 962d6ef..7c98a16 100644
--- a/dlls/msvfw32/msvideo_main.c
+++ b/dlls/msvfw32/msvideo_main.c
@@ -53,8 +53,6 @@ static inline const char *wine_dbgstr_fcc( DWORD fcc )
                             LOBYTE(HIWORD(fcc)), HIBYTE(HIWORD(fcc)));
 }
 
-LRESULT (CALLBACK *pFnCallTo16)(HDRVR, HIC, UINT, LPARAM, LPARAM) = NULL;
-
 static WINE_HIC*        MSVIDEO_FirstHic /* = NULL */;
 
 typedef struct _reg_driver reg_driver;
@@ -327,7 +325,7 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
 
     if (driver && driver->proc)
 	/* The driver has been registered at runtime with its driverproc */
-        return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, driver->proc, 0);
+        return ICOpenFunction(fccType, fccHandler, wMode, driver->proc);
   
     /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
      * same layout as ICOPEN
@@ -360,9 +358,10 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
     }
     bIs16 = GetDriverFlags(hdrv) & 0x10000000; /* undocumented flag: WINE_GDF_16BIT */
 
-    if (bIs16 && !pFnCallTo16)
+    if (bIs16)
     {
         FIXME("Got a 16 bit driver, but no 16 bit support in msvfw\n");
+        CloseDriver(hdrv, 0, 0);
         return 0;
     }
     whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC));
@@ -372,13 +371,11 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
         return FALSE;
     }
     whic->hdrv          = hdrv;
-    /* FIXME: is the signature the real one ? */
-    whic->driverproc    = bIs16 ? (DRIVERPROC)pFnCallTo16 : NULL;
-    whic->driverproc16  = 0;
+    whic->driverproc    = NULL;
     whic->type          = fccType;
     whic->handler       = fccHandler;
-    while (MSVIDEO_GetHicPtr(HIC_32(IC_HandleRef)) != NULL) IC_HandleRef++;
-    whic->hic           = HIC_32(IC_HandleRef++);
+    while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++;
+    whic->hic           = (HIC)(ULONG_PTR)IC_HandleRef++;
     whic->next          = MSVIDEO_FirstHic;
     MSVIDEO_FirstHic = whic;
 
@@ -387,16 +384,15 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
 }
 
 /***********************************************************************
- *		MSVIDEO_OpenFunction
+ *		ICOpenFunction			[MSVFW32.@]
  */
-HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, 
-                         DRIVERPROC lpfnHandler, DWORD lpfnHandler16) 
+HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler)
 {
     ICOPEN      icopen;
     WINE_HIC*   whic;
 
-    TRACE("(%s,%s,%d,%p,%08x)\n",
-          wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode, lpfnHandler, lpfnHandler16);
+    TRACE("(%s,%s,%d,%p)\n",
+          wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode, lpfnHandler);
 
     icopen.dwSize		= sizeof(ICOPEN);
     icopen.fccType		= fccType;
@@ -412,9 +408,8 @@ HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode,
     if (!whic) return 0;
 
     whic->driverproc   = lpfnHandler;
-    whic->driverproc16 = lpfnHandler16;
-    while (MSVIDEO_GetHicPtr(HIC_32(IC_HandleRef)) != NULL) IC_HandleRef++;
-    whic->hic          = HIC_32(IC_HandleRef++);
+    while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++;
+    whic->hic          = (HIC)(ULONG_PTR)IC_HandleRef++;
     whic->next         = MSVIDEO_FirstHic;
     MSVIDEO_FirstHic = whic;
 
@@ -448,14 +443,6 @@ HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode,
 }
 
 /***********************************************************************
- *		ICOpenFunction			[MSVFW32.@]
- */
-HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) 
-{
-    return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)lpfnHandler, 0);
-}
-
-/***********************************************************************
  *		ICGetInfo			[MSVFW32.@]
  */
 LRESULT VFWAPI ICGetInfo(HIC hic, ICINFO *picinfo, DWORD cb) 
diff --git a/dlls/msvfw32/msvideo_private.h b/dlls/msvfw32/msvideo_private.h
index 6bd8e93..d1e5f8d 100644
--- a/dlls/msvfw32/msvideo_private.h
+++ b/dlls/msvfw32/msvideo_private.h
@@ -36,26 +36,12 @@ typedef struct tagWINE_HIC {
     WORD		x2;		/* 20: */
     DWORD		x3;		/* 22: */
 					/* 26: */
-    DWORD               driverproc16;   /* Wine specific flags */
     HIC                 hic;
     DWORD               driverId;
     struct tagWINE_HIC* next;
 } WINE_HIC;
 
-HIC             MSVIDEO_OpenFunction(DWORD, DWORD, UINT, DRIVERPROC, DWORD);
 LRESULT         MSVIDEO_SendMessage(WINE_HIC*, UINT, DWORD_PTR, DWORD_PTR);
-WINE_HIC*       MSVIDEO_GetHicPtr(HIC);
-
-extern LRESULT  (CALLBACK *pFnCallTo16)(HDRVR, HIC, UINT, LPARAM, LPARAM);
-
-/* handle16 --> handle conversions */
-#define HDRAWDIB_32(h16)	((HDRAWDIB)(ULONG_PTR)(h16))
-#define HIC_32(h16)		((HIC)(ULONG_PTR)(h16))
-
-/* handle --> handle16 conversions */
-#define HDRVR_16(h32)		(LOWORD(h32))
-#define HDRAWDIB_16(h32)	(LOWORD(h32))
-#define HIC_16(h32)		(LOWORD(h32))
 
 #define IDC_CONFIGURE 882
 #define IDC_ABOUT 883





More information about the wine-patches mailing list