1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
/*---------------------------------------------------------------------*\
*
* 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 );
break;
}
/*
** Protect ourself from being given a duff pointer.
*/
try {
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 );
break;
}
/*
** Protect ourself from being given a duff pointer.
*/
try {
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 );
}
|