[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