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

388 lines
10 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*---------------------------------------------------------------------*\
*
* WOW v1.0
*
* Copyright (c) 1991, Microsoft Corporation
*
* WMMEDIA.C
* WOW32 16-bit MultiMedia API support
*
* Contains:
* General support apis
* Timer support apis
* MCI apis
*
* History:
* Created 21-Jan-1992 by Mike Tricker (MikeTri), after jeffpar
* Changed 15-Jul-1992 by Mike Tricker (MikeTri), fixing GetDevCaps calls
* 26-Jul-1992 by Stephen Estrop (StephenE) thunks for mciSendCommand
* 30-Jul-1992 by Mike Tricker (MikeTri), fixing Wave/Midi/MMIO
* 03-Aug-1992 by Mike Tricker (MikeTri), added proper error handling
* 08-Oct-1992 by StephenE used correct thunk macro for UINT's
* also split file into 3 because it was getting to big.
*
\*---------------------------------------------------------------------*/
//
// 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
#define OEMRESOURCE
#include "precomp.h"
#pragma hdrstop
#include <stdlib.h>
MODNAME(wmmedia.c);
PCALLBACK_DATA pCallBackData; // A 32 bit ptr to the 16 bit callback data
CRITICAL_SECTION mmCriticalSection;
CRITICAL_SECTION mmHandleCriticalSection;
//
// All this stuff is required for the dynamic linking of Multi-Media to WOW32
//
HANDLE hWinmm = NULL;
FARPROC mmAPIEatCmdEntry = NULL;
FARPROC mmAPIGetParamSize = NULL;
FARPROC mmAPIUnlockCmdTable = NULL;
FARPROC mmAPISendCmdW = NULL;
FARPROC mmAPIFindCmdItem = NULL;
FARPROC mmAPIGetYieldProc = NULL;
VOID FASTCALL Set_MultiMedia_16bit_Directory( PVDMFRAME pFrame );
/*++
GENERIC FUNCTION PROTOTYPE:
==========================
ULONG FASTCALL WMM32<function name>(PVDMFRAME pFrame)
{
ULONG ul;
register P<function name>16 parg16;
GETARGPTR(pFrame, sizeof(<function name>16), parg16);
<get any other required pointers into 16 bit space>
ALLOCVDMPTR
GETVDMPTR
GETMISCPTR
et cetera
<copy any complex structures from 16 bit -> 32 bit space>
<ALWAYS use the FETCHxxx macros>
ul = GET<return type>16(<function name>(parg16->f1,
:
:
parg16->f<n>);
<copy any complex structures from 32 -> 16 bit space>
<ALWAYS use the STORExxx macros>
<free any pointers to 16 bit space you previously got>
<flush any areas of 16 bit memory if they were written to>
FLUSHVDMPTR
FREEARGPTR(parg16);
RETURN(ul);
}
NOTE:
The VDM frame is automatically set up, with all the function parameters
available via parg16->f<number>.
Handles must ALWAYS be mapped for 16 -> 32 -> 16 space via the mapping tables
laid out in WALIAS.C.
Any storage you allocate must be freed (eventually...).
Further to that - if a thunk which allocates memory fails in the 32 bit call
then it must free that memory.
Also, never update structures in 16 bit land if the 32 bit call fails.
--*/
/* ---------------------------------------------------------------------
** General Support API's
** ---------------------------------------------------------------------
*/
/*****************************Private*Routine******************************\
* WMM32CallProc32
*
*
*
* History:
* dd-mm-94 - StephenE - Created
*
\**************************************************************************/
ULONG FASTCALL
WMM32CallProc32(
PVDMFRAME pFrame
)
{
register DWORD dwReturn;
PMMCALLPROC3216 parg16;
GETARGPTR(pFrame, sizeof(PMMCALLPROC32), parg16);
// Don't call to Zero
if (parg16->lpProcAddress == 0) {
LOGDEBUG(LOG_ALWAYS,("MMCallProc32 - Error calling to 0 not allowed"));
return(0);
}
//
// Make sure we have the correct 16 bit directory set.
//
if (parg16->fSetCurrentDirectory != 0) {
UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
}
dwReturn = ((FARPROC)parg16->lpProcAddress)( parg16->p5, parg16->p4,
parg16->p3, parg16->p2,
parg16->p1);
FREEARGPTR(parg16);
return dwReturn;
}
/******************************Public*Routine******************************\
* WOW32ResolveMemory
*
* Enable multi-media (and others) to reliably map memory from 16 bit land
* to 32 bit land.
*
* History:
* dd-mm-93 - StephenE - Created
*
\**************************************************************************/
LPVOID APIENTRY
WOW32ResolveMemory(
VPVOID vp
)
{
LPVOID lpReturn;
GETMISCPTR( vp, lpReturn );
return lpReturn;
}
/**********************************************************************\
* WOW32ResolveHandle
*
* This is a general purpose handle mapping function. It allows WOW thunk
* extensions to get access to 32 bit handles given a 16 bit handle.
*
\**********************************************************************/
BOOL APIENTRY WOW32ResolveHandle( UINT uHandleType, UINT uMappingDirection,
WORD wHandle16_In, LPWORD lpwHandle16_Out,
DWORD dwHandle32_In, LPDWORD lpdwHandle32_Out )
{
BOOL fReturn = FALSE;
DWORD dwHandle32;
WORD wHandle16;
static FARPROC mmAPI = NULL;
GET_MULTIMEDIA_API( "WOW32ResolveMultiMediaHandle", mmAPI,
MMSYSERR_NODRIVER );
if ( uMappingDirection == WOW32_DIR_16IN_32OUT ) {
switch ( uHandleType ) {
case WOW32_USER_HANDLE:
dwHandle32 = (DWORD)USER32( wHandle16_In );
break;
case WOW32_GDI_HANDLE:
dwHandle32 = (DWORD)GDI32( wHandle16_In );
break;
case WOW32_WAVEIN_HANDLE:
case WOW32_WAVEOUT_HANDLE:
case WOW32_MIDIOUT_HANDLE:
case WOW32_MIDIIN_HANDLE:
(*mmAPI)( uHandleType, uMappingDirection, wHandle16_In,
lpwHandle16_Out, dwHandle32_In, lpdwHandle32_Out );
dwHandle32 = 0;
fReturn = TRUE;
break;
}
/*
** Protect ourself from being given a duff pointer.
*/
try {
if ( dwHandle32 ) {
if ( *lpdwHandle32_Out = dwHandle32 ) {
fReturn = TRUE;
}
else {
fReturn = FALSE;
}
}
} except( EXCEPTION_EXECUTE_HANDLER ) {
fReturn = FALSE;
}
}
else if ( uMappingDirection == WOW32_DIR_32IN_16OUT ) {
switch ( uHandleType ) {
case WOW32_USER_HANDLE:
wHandle16 = (WORD)USER16( dwHandle32_In );
break;
case WOW32_GDI_HANDLE:
wHandle16 = (WORD)GDI16( dwHandle32_In );
break;
case WOW32_WAVEIN_HANDLE:
case WOW32_WAVEOUT_HANDLE:
case WOW32_MIDIOUT_HANDLE:
case WOW32_MIDIIN_HANDLE:
(*mmAPI)( uHandleType, uMappingDirection, wHandle16_In,
lpwHandle16_Out, dwHandle32_In, lpdwHandle32_Out );
wHandle16 = 0;
fReturn = TRUE;
break;
}
/*
** Protect ourself from being given a duff pointer.
*/
try {
if ( wHandle16 ) {
if ( *lpwHandle16_Out = wHandle16 ) {
fReturn = TRUE;
}
else {
fReturn = FALSE;
}
}
} except( EXCEPTION_EXECUTE_HANDLER ) {
fReturn = FALSE;
}
}
return fReturn;
}
/**********************************************************************\
*
* WOW32DriverCallback
*
* Callback stub, which invokes the "real" 16 bit callback.
* The parameters to this function must be in the format that the 16 bit
* code expects, i.e. all handles must be 16 bit handles, all addresses must
* be 16:16 ones.
*
*
* It is possible that this function will have been called with the
* DCB_WINDOW set in which case the 16 bit interrupt handler will call
* PostMessage. Howver, it is much more efficient if PostMessage is called
* from the 32 bit side.
*
\**********************************************************************/
BOOL APIENTRY WOW32DriverCallback( DWORD dwCallback, DWORD dwFlags,
WORD wID, WORD wMsg,
DWORD dwUser, DWORD dw1, DWORD dw2 )
{
static FARPROC mmAPI = NULL;
GET_MULTIMEDIA_API( "WOW32DriverCallback", mmAPI, MMSYSERR_NODRIVER );
/*
** Just pass the call onto winmm
*/
return (*mmAPI)( dwCallback, dwFlags, wID, wMsg, dwUser, dw1, dw2 );
}
/**********************************************************************\
*
* Get_MultiMedia_ProcAddress
*
* This function gets the address of the given Multi-Media api. It loads
* Winmm.dll if this it has not already been loaded.
*
\**********************************************************************/
FARPROC Get_MultiMedia_ProcAddress( LPSTR lpstrProcName )
{
/*
** Either this is the first time this function has been called
** or the Multi-Media sub-system is in a bad way.
*/
if ( hWinmm == NULL ) {
// dprintf2(( "Attempting to load WINMM.DLL" ));
hWinmm = SafeLoadLibrary( "WINMM.DLL" );
if ( hWinmm == NULL ) {
/* Looks like the Multi-Media sub-system is in a bad way */
// dprintf2(( "FAILED TO LOAD WINMM.DLL!!" ));
return NULL;
}
}
return GetProcAddress( hWinmm, lpstrProcName );
}
/**********************************************************************\
*
* WOWDelayTimeGetTime
*
* on faster machines timeGetTime can return the same value
* and some apps will take diff (0) to divide and fault
* to prevent that check if it is one
* of the known apps that do that and sleep if necessary
*
*
\**********************************************************************/
BOOL APIENTRY WOWDelayTimeGetTime(void)
{
if(CURRENTPTD()->dwWOWCompatFlags2 & WOWCF2_DELAYTIMEGETTIME) {
Sleep(1);
return 1;
}
return 0;
}