windows-nt/Source/XPSP1/NT/base/mvdm/wow32/wmmstru2.c

540 lines
16 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
*
* WOW v1.0
*
* Copyright (c) 1991, Microsoft Corporation
*
* WMMSTRU2.C
* WOW32 16-bit MultiMedia structure conversion support
* Contains support for mciSendCommand UnThunk message Parms.
*
* History:
* Created 17-Jul-1992 by Stephen Estrop (stephene)
*
--*/
//
// We define NO_STRICT so that the compiler doesn't moan and groan when
// I use the FARPROC type for the Multi-Media api loading.
//
#define NO_STRICT
#include "precomp.h"
#pragma hdrstop
#if 0
MODNAME(wmmstru2.c);
//
// The following are required for the dynamic linking of Multi-Media code
// from within WOW. They are all defined in wmmedia.c
//
extern FARPROC mmAPIEatCmdEntry;
extern FARPROC mmAPIGetParamSize;
extern FARPROC mmAPIUnlockCmdTable;
extern FARPROC mmAPISendCmdW;
/**********************************************************************\
*
* UnThunkMciCommand16
*
* This function "unthunks" a 32 bit mci send command request.
*
* The ideas behind this function were stolen from UnThunkWMMsg16,
* see wmsg16.c
*
\**********************************************************************/
INT UnThunkMciCommand16( MCIDEVICEID devID, UINT OrigCommand, DWORD OrigFlags,
DWORD OrigParms, DWORD NewParms, LPWSTR lpCommand,
UINT uTable )
{
BOOL fReturnValNotThunked = FALSE;
#if DBG
static LPSTR f_name = "UnThunkMciCommand16: ";
register int i;
int n;
dprintf3(( "UnThunkMciCommand :" ));
n = sizeof(mciMessageNames) / sizeof(MCI_MESSAGE_NAMES);
for ( i = 0; i < n; i++ ) {
if ( mciMessageNames[i].uMsg == OrigCommand ) {
break;
}
}
dprintf3(( "OrigCommand -> %lX", (DWORD)OrigCommand ));
dprintf3(( " Name -> %s", i != n ? mciMessageNames[i].lpstMsgName : "Unkown Name" ));
dprintf5(( " OrigFlags -> %lX", OrigFlags ));
dprintf5(( " OrigParms -> %lX", OrigParms ));
dprintf5(( " NewParms -> %lX", NewParms ));
//
// If NewParms is 0 we shouldn't be here, I haven't got an assert
// macro, but the following we do the same thing.
//
if ( NewParms == 0 ) {
dprintf(( "%scalled with NewParms == NULL !!", f_name ));
dprintf(( "Call StephenE NOW !!" ));
DebugBreak();
}
#endif
//
// We have to do a manual unthunk of MCI_SYSINFO because the
// command table is not consistent. As a command table should be
// available now we can load it and then use it to unthunk MCI_OPEN.
//
switch ( OrigCommand ) {
case MCI_OPEN:
UnThunkOpenCmd( OrigFlags, OrigParms, NewParms );
break;
case MCI_SYSINFO:
UnThunkSysInfoCmd( OrigFlags, OrigParms, NewParms );
break;
case MCI_STATUS:
UnThunkStatusCmd( devID, OrigFlags, OrigParms, NewParms );
break;
default:
fReturnValNotThunked = TRUE;
break;
}
//
// Do we have a command table ? It is possible that we have
// a custom command but we did not find a custom command table, in which
// case we should just free the pNewParms storage.
//
if ( lpCommand != NULL ) {
//
// We now parse the custom command table to see if there is a
// return field in the parms structure.
//
dprintf3(( "%sUnthunking via command table", f_name ));
UnThunkCommandViaTable( lpCommand, OrigFlags, OrigParms,
NewParms, fReturnValNotThunked );
//
// Now we have finished with the command table we should unlock it.
//
dprintf4(( "%sUnlocking custom command table", f_name ));
(*mmAPIUnlockCmdTable)( uTable );
}
//
// All that needs to be done now is to free the storage
// that was allocated during the ThunkXxxCmd function.
//
dprintf4(( "%sFreeing storage.", f_name ));
free_w( (PBYTE)NewParms );
return 0;
}
/**********************************************************************\
* UnThunkOpenCmd
*
* UnThunk the Open mci command parms.
\**********************************************************************/
VOID UnThunkOpenCmd( DWORD OrigFlags, DWORD OrigParms, DWORD NewParms )
{
#if DBG
static LPSTR f_name = "UnThunkOpenCmd: ";
#endif
LPMCI_OPEN_PARMS lpOpeParms = (LPMCI_OPEN_PARMS)NewParms;
PMCI_OPEN_PARMS16 lpOpeParms16;
WORD wDevice;
dprintf4(( "%sCopying Device ID.", f_name ));
GETVDMPTR( OrigParms, sizeof(MCI_OPEN_PARMS16), lpOpeParms16 );
wDevice = LOWORD( lpOpeParms->wDeviceID );
STOREWORD( lpOpeParms16->wDeviceID, wDevice );
FLUSHVDMPTR( OrigParms, sizeof(MCI_OPEN_PARMS16), lpOpeParms16 );
FREEVDMPTR( lpOpeParms16 );
dprintf5(( "wDeviceID -> %u", wDevice ));
if ( (OrigParms & MCI_OPEN_TYPE) && !(OrigParms & MCI_OPEN_TYPE_ID ) ) {
dprintf3(( "%sFreeing a STRING pointer", f_name ));
FREEPSZPTR( lpOpeParms->lpstrDeviceType );
}
if ( (OrigParms & MCI_OPEN_ELEMENT)
&& !(OrigParms & MCI_OPEN_ELEMENT_ID ) ) {
dprintf3(( "%sFreeing a STRING pointer", f_name ));
FREEPSZPTR( lpOpeParms->lpstrElementName );
}
}
/**********************************************************************\
* UnThunkSysInfoCmd
*
* UnThunk the SysInfo mci command parms.
\**********************************************************************/
VOID UnThunkSysInfoCmd( DWORD OrigFlags, DWORD OrigParms, DWORD NewParms )
{
#if DBG
static LPSTR f_name = "UnThunkSysInfoCmd: ";
#endif
LPMCI_SYSINFO_PARMS lpSysParms = (LPMCI_SYSINFO_PARMS)NewParms;
//
// Had better check that we did actually allocate
// a pointer.
//
if ( lpSysParms->lpstrReturn && lpSysParms->dwRetSize ) {
#if DBG
if ( !(OrigFlags & MCI_SYSINFO_QUANTITY) ) {
dprintf5(( "lpstrReturn -> %s", lpSysParms->lpstrReturn ));
}
else {
dprintf5(( "lpstrReturn -> %d", *(LPDWORD)lpSysParms->lpstrReturn ));
}
#endif
//
// Free lpSysParms->lpstrReturn;
//
dprintf4(( "%sFreeing lpstrReturn", f_name ));
FREEVDMPTR( lpSysParms->lpstrReturn );
}
}
/**********************************************************************\
* UnThunkMciStatus
*
* UnThunk the Status mci command parms.
\**********************************************************************/
VOID UnThunkStatusCmd( MCIDEVICEID devID, DWORD OrigFlags,
DWORD OrigParms, DWORD NewParms )
{
#if DBG
static LPSTR f_name = "UnThunkStatusCmd: ";
#endif
MCI_GETDEVCAPS_PARMS GetDevCaps;
DWORD dwRetVal;
DWORD dwParm16;
PDWORD pdwOrig16;
PDWORD pdwParm32;
int iReturnType = MCI_INTEGER;
/*
** If the MCI_STATUS_ITEM flag is not specified don't bother
** doing any unthunking.
*/
if ( !(OrigFlags & MCI_STATUS_ITEM) ) {
return;
}
/*
** We need to determine what type of device we are
** dealing with. We can do this by send an MCI_GETDEVCAPS
** command to the device. (We might as well use the Unicode
** version of mciSendCommand and avoid another thunk).
*/
RtlZeroMemory( &GetDevCaps, sizeof(MCI_GETDEVCAPS_PARMS) );
GetDevCaps.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
dwRetVal = (*mmAPISendCmdW)( devID, MCI_GETDEVCAPS, MCI_GETDEVCAPS_ITEM,
(DWORD)&GetDevCaps );
/*
** If we can't get the DevCaps then we are doomed.
*/
if ( dwRetVal ) {
dprintf(("%sFailure to get devcaps", f_name));
return;
}
/*
** Determine the dwReturn type.
*/
switch ( GetDevCaps.dwReturn ) {
case MCI_DEVTYPE_ANIMATION:
switch ( ((LPDWORD)NewParms)[2] ) {
case MCI_ANIM_STATUS_HWND:
iReturnType = MCI_HWND;
break;
case MCI_ANIM_STATUS_HPAL:
iReturnType = MCI_HPAL;
break;
}
break;
case MCI_DEVTYPE_OVERLAY:
if ( ((LPDWORD)NewParms)[2] == MCI_OVLY_STATUS_HWND ) {
iReturnType = MCI_HWND;
}
break;
case MCI_DEVTYPE_DIGITAL_VIDEO:
switch ( ((LPDWORD)NewParms)[2] ) {
case MCI_DGV_STATUS_HWND:
iReturnType = MCI_HWND;
break;
case MCI_DGV_STATUS_HPAL:
iReturnType = MCI_HPAL;
break;
}
break;
}
/*
** Thunk the dwReturn value according to the required type
*/
GETVDMPTR( OrigParms, sizeof( MCI_STATUS_PARMS), pdwOrig16 );
pdwParm32 = (LPDWORD)((LPBYTE)NewParms + 4);
switch ( iReturnType ) {
case MCI_HPAL:
dprintf4(( "%sFound an HPAL return field", f_name ));
dwParm16 = MAKELONG( GETHPALETTE16( (HPALETTE)*pdwParm32 ), 0 );
STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
dprintf5(( "HDC32 -> 0x%lX", *pdwParm32 ));
dprintf5(( "HDC16 -> 0x%lX", dwParm16 ));
break;
case MCI_HWND:
dprintf4(( "%sFound an HWND return field", f_name ));
dwParm16 = MAKELONG( GETHWND16( (HWND)*pdwParm32 ), 0 );
STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
dprintf5(( "HWND32 -> 0x%lX", *pdwParm32 ));
dprintf5(( "HWND16 -> 0x%lX", dwParm16 ));
break;
case MCI_INTEGER:
dprintf4(( "%sFound an INTEGER return field", f_name ));
STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), *pdwParm32 );
dprintf5(( "INTEGER -> %ld", *pdwParm32 ));
break;
// no default: all possible cases accounted for
}
/*
** Free the VDM pointer as we have finished with it
*/
FLUSHVDMPTR( OrigParms, sizeof( MCI_STATUS_PARMS), pdwOrig16 );
FREEVDMPTR( pdwOrig16 );
}
/**********************************************************************\
* UnThunkCommandViaTable
*
* Thunks the return field if there is one and then frees and pointers
* that were got via GETVDMPTR or GETPSZPTR.
\**********************************************************************/
INT UnThunkCommandViaTable( LPWSTR lpCommand, DWORD dwFlags, DWORD OrigParms,
DWORD pNewParms, BOOL fReturnValNotThunked )
{
#if DBG
static LPSTR f_name = "UnThunkCommandViaTable: ";
#endif
LPWSTR lpFirstParameter;
UINT wID;
DWORD dwValue;
UINT wOffset32, wOffset1stParm32;
DWORD dwParm16;
DWORD Size;
PDWORD pdwOrig16;
PDWORD pdwParm32;
DWORD dwMask = 1;
//
// Calculate the size of this command parameter block in terms
// of bytes, then get a VDM pointer to the OrigParms.
//
Size = GetSizeOfParameter( lpCommand );
//
// Skip past command entry
//
lpCommand = (LPWSTR)((LPBYTE)lpCommand +
(*mmAPIEatCmdEntry)( lpCommand, NULL, NULL ));
//
// Get the next entry
//
lpFirstParameter = lpCommand;
//
// Skip past the DWORD return value
//
wOffset1stParm32 = 4;
lpCommand = (LPWSTR)((LPBYTE)lpCommand +
(*mmAPIEatCmdEntry)( lpCommand, &dwValue, &wID ));
//
// If it is a return value, skip it
//
if ( (wID == MCI_RETURN) && (fReturnValNotThunked) ) {
GETVDMPTR( OrigParms, Size, pdwOrig16 );
pdwParm32 = (LPDWORD)((LPBYTE)pNewParms + 4);
//
// Look for a string return type, these are a special case.
//
switch ( dwValue ) {
case MCI_STRING:
dprintf4(( "%sFound a STRING return field", f_name ));
//
// Get string pointer and length
//
Size = *(LPDWORD)((LPBYTE)pNewParms + 8);
//
// Get the 32 bit string pointer
//
if ( Size > 0 ) {
dprintf4(( "%sFreeing a return STRING pointer", f_name ));
dprintf5(( "STRING -> %s", (LPSTR)*pdwParm32 ));
FREEVDMPTR( (LPSTR)*pdwParm32 );
}
break;
case MCI_RECT:
{
PRECT pRect32 = (PRECT)((LPBYTE)pNewParms + 4);
PRECT16 pRect16 = (PRECT16)((LPBYTE)pdwOrig16 + 4);
dprintf4(( "%sFound a RECT return field", f_name ));
STORESHORT( pRect16->top, (SHORT)pRect32->top );
STORESHORT( pRect16->bottom, (SHORT)pRect32->bottom );
STORESHORT( pRect16->left, (SHORT)pRect32->left );
STORESHORT( pRect16->right, (SHORT)pRect32->right );
}
break;
case MCI_INTEGER:
//
// Get the 32 bit return integer and store it in the
// 16 bit parameter structure.
//
dprintf4(( "%sFound an INTEGER return field", f_name ));
STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), *pdwParm32 );
dprintf5(( "INTEGER -> %ld", *pdwParm32 ));
break;
case MCI_HWND:
dprintf4(( "%sFound an HWND return field", f_name ));
dwParm16 = MAKELONG( GETHWND16( (HWND)*pdwParm32 ), 0 );
STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
dprintf5(( "HWND32 -> 0x%lX", *pdwParm32 ));
dprintf5(( "HWND16 -> 0x%lX", dwParm16 ));
break;
case MCI_HPAL:
dprintf4(( "%sFound an HPAL return field", f_name ));
dwParm16 = MAKELONG( GETHPALETTE16( (HPALETTE)*pdwParm32 ), 0 );
STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
dprintf5(( "HDC32 -> 0x%lX", *pdwParm32 ));
dprintf5(( "HDC16 -> 0x%lX", dwParm16 ));
break;
case MCI_HDC:
dprintf4(( "%sFound an HDC return field", f_name ));
dwParm16 = MAKELONG( GETHDC16( (HDC)*pdwParm32 ), 0 );
STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
dprintf5(( "HDC32 -> 0x%lX", *pdwParm32 ));
dprintf5(( "HDC16 -> 0x%lX", dwParm16 ));
break;
}
//
// Free the VDM pointer as we have finished with it
//
FLUSHVDMPTR( OrigParms, Size, pdwOrig16 );
FREEVDMPTR( pdwOrig16 );
//
// Adjust the offset of the first parameter.
//
wOffset1stParm32 = (*mmAPIGetParamSize)( dwValue, wID );
//
// Save the new first parameter
//
lpFirstParameter = lpCommand;
}
//
// Walk through each flag looking for strings to free
//
while ( dwMask != 0 ) {
//
// Is this bit set?
//
if ( (dwFlags & dwMask) != 0 ) {
wOffset32 = wOffset1stParm32;
lpCommand = (LPWSTR)((LPBYTE)lpFirstParameter +
(*mmAPIEatCmdEntry)( lpFirstParameter,
&dwValue, &wID ));
//
// What parameter uses this bit?
//
while ( wID != MCI_END_COMMAND && dwValue != dwMask ) {
wOffset32 = (*mmAPIGetParamSize)( dwValue, wID );
if ( wID == MCI_CONSTANT ) {
while ( wID != MCI_END_CONSTANT ) {
lpCommand = (LPWSTR)((LPBYTE)lpCommand +
(*mmAPIEatCmdEntry)( lpCommand, NULL, &wID ));
}
}
lpCommand = (LPWSTR)((LPBYTE)lpCommand +
(*mmAPIEatCmdEntry)( lpCommand, &dwValue, &wID ));
}
if ( wID == MCI_STRING ) {
dprintf4(( "%sFreeing a STRING pointer", f_name ));
pdwParm32 = (LPDWORD)((LPBYTE)pNewParms + wOffset32);
FREEPSZPTR( (LPSTR)*pdwParm32 );
}
}
//
// Go to the next flag
//
dwMask <<= 1;
}
return 0;
}
#endif