|
|
/*++
* * 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
|