msvfw32: Clearly separate the 16-bit code out of the rest by wrapping 16-bit message functions in thunks.
This commit is contained in:
parent
aad81e5cea
commit
33a04dc69c
|
@ -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]
|
||||
*/
|
||||
|
@ -134,14 +142,6 @@ HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode)
|
|||
return HIC_16(ICOpen(fccType, fccHandler, wMode));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ICClose [MSVIDEO.204]
|
||||
*/
|
||||
LRESULT WINAPI ICClose16(HIC16 hic)
|
||||
{
|
||||
return ICClose(HIC_32(hic));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _ICMessage [MSVIDEO.207]
|
||||
*/
|
||||
|
@ -670,15 +670,11 @@ 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];
|
||||
|
||||
whic = MSVIDEO_GetHicPtr(hic);
|
||||
if (whic)
|
||||
{
|
||||
DWORD ret = 0;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case DRV_OPEN:
|
||||
|
@ -687,13 +683,13 @@ static LRESULT CALLBACK IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD l
|
|||
}
|
||||
args[7] = HIWORD(hic);
|
||||
args[6] = LOWORD(hic);
|
||||
args[5] = HDRVR_16(whic->hdrv);
|
||||
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( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &ret );
|
||||
WOWCallback16Ex( pfn16, WCB16_PASCAL, sizeof(args), args, &ret );
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
|
@ -703,7 +699,70 @@ static LRESULT CALLBACK IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD l
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
else return ICERR_BADHANDLE;
|
||||
|
||||
#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 };
|
||||
|
||||
static struct msvideo_thunk* MSVIDEO_AddThunk(DWORD pfn16)
|
||||
{
|
||||
struct msvideo_thunk* thunk;
|
||||
|
||||
if (!MSVIDEO_Thunks)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
|
||||
{
|
||||
if (thunk->pfn16 == 0)
|
||||
{
|
||||
thunk->pfn16 = pfn16;
|
||||
return thunk;
|
||||
}
|
||||
}
|
||||
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,13 +789,9 @@ 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)
|
||||
{
|
||||
/* we've got a 16 bit driver proc... call it directly */
|
||||
if (whic->driverproc16)
|
||||
if ((thunk = MSVIDEO_HasThunk(hic)))
|
||||
{
|
||||
WORD args[8];
|
||||
DWORD result;
|
||||
|
@ -739,13 +800,13 @@ LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lPara
|
|||
/* but this doesn't match what IC_Callback3216 does */
|
||||
args[7] = HIWORD(hic);
|
||||
args[6] = LOWORD(hic);
|
||||
args[5] = HDRVR_16(whic->hdrv);
|
||||
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( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &result );
|
||||
WOWCallback16Ex( thunk->pfn16, WCB16_PASCAL, sizeof(args), args, &result );
|
||||
ret = result;
|
||||
}
|
||||
else
|
||||
|
@ -753,11 +814,32 @@ LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lPara
|
|||
/* 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);
|
||||
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)))
|
||||
{
|
||||
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:
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -447,14 +442,6 @@ HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode,
|
|||
return whic->hic;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ICOpenFunction [MSVFW32.@]
|
||||
*/
|
||||
HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler)
|
||||
{
|
||||
return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)lpfnHandler, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ICGetInfo [MSVFW32.@]
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue