Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

387 lines
10 KiB

  1. /*---------------------------------------------------------------------*\
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WMMEDIA.C
  8. * WOW32 16-bit MultiMedia API support
  9. *
  10. * Contains:
  11. * General support apis
  12. * Timer support apis
  13. * MCI apis
  14. *
  15. * History:
  16. * Created 21-Jan-1992 by Mike Tricker (MikeTri), after jeffpar
  17. * Changed 15-Jul-1992 by Mike Tricker (MikeTri), fixing GetDevCaps calls
  18. * 26-Jul-1992 by Stephen Estrop (StephenE) thunks for mciSendCommand
  19. * 30-Jul-1992 by Mike Tricker (MikeTri), fixing Wave/Midi/MMIO
  20. * 03-Aug-1992 by Mike Tricker (MikeTri), added proper error handling
  21. * 08-Oct-1992 by StephenE used correct thunk macro for UINT's
  22. * also split file into 3 because it was getting to big.
  23. *
  24. \*---------------------------------------------------------------------*/
  25. //
  26. // We define NO_STRICT so that the compiler doesn't moan and groan when
  27. // I use the FARPROC type for the Multi-Media api loading.
  28. //
  29. #define NO_STRICT
  30. #define OEMRESOURCE
  31. #include "precomp.h"
  32. #pragma hdrstop
  33. #include <stdlib.h>
  34. MODNAME(wmmedia.c);
  35. PCALLBACK_DATA pCallBackData; // A 32 bit ptr to the 16 bit callback data
  36. CRITICAL_SECTION mmCriticalSection;
  37. CRITICAL_SECTION mmHandleCriticalSection;
  38. //
  39. // All this stuff is required for the dynamic linking of Multi-Media to WOW32
  40. //
  41. HANDLE hWinmm = NULL;
  42. FARPROC mmAPIEatCmdEntry = NULL;
  43. FARPROC mmAPIGetParamSize = NULL;
  44. FARPROC mmAPIUnlockCmdTable = NULL;
  45. FARPROC mmAPISendCmdW = NULL;
  46. FARPROC mmAPIFindCmdItem = NULL;
  47. FARPROC mmAPIGetYieldProc = NULL;
  48. VOID FASTCALL Set_MultiMedia_16bit_Directory( PVDMFRAME pFrame );
  49. /*++
  50. GENERIC FUNCTION PROTOTYPE:
  51. ==========================
  52. ULONG FASTCALL WMM32<function name>(PVDMFRAME pFrame)
  53. {
  54. ULONG ul;
  55. register P<function name>16 parg16;
  56. GETARGPTR(pFrame, sizeof(<function name>16), parg16);
  57. <get any other required pointers into 16 bit space>
  58. ALLOCVDMPTR
  59. GETVDMPTR
  60. GETMISCPTR
  61. et cetera
  62. <copy any complex structures from 16 bit -> 32 bit space>
  63. <ALWAYS use the FETCHxxx macros>
  64. ul = GET<return type>16(<function name>(parg16->f1,
  65. :
  66. :
  67. parg16->f<n>);
  68. <copy any complex structures from 32 -> 16 bit space>
  69. <ALWAYS use the STORExxx macros>
  70. <free any pointers to 16 bit space you previously got>
  71. <flush any areas of 16 bit memory if they were written to>
  72. FLUSHVDMPTR
  73. FREEARGPTR(parg16);
  74. RETURN(ul);
  75. }
  76. NOTE:
  77. The VDM frame is automatically set up, with all the function parameters
  78. available via parg16->f<number>.
  79. Handles must ALWAYS be mapped for 16 -> 32 -> 16 space via the mapping tables
  80. laid out in WALIAS.C.
  81. Any storage you allocate must be freed (eventually...).
  82. Further to that - if a thunk which allocates memory fails in the 32 bit call
  83. then it must free that memory.
  84. Also, never update structures in 16 bit land if the 32 bit call fails.
  85. --*/
  86. /* ---------------------------------------------------------------------
  87. ** General Support API's
  88. ** ---------------------------------------------------------------------
  89. */
  90. /*****************************Private*Routine******************************\
  91. * WMM32CallProc32
  92. *
  93. *
  94. *
  95. * History:
  96. * dd-mm-94 - StephenE - Created
  97. *
  98. \**************************************************************************/
  99. ULONG FASTCALL
  100. WMM32CallProc32(
  101. PVDMFRAME pFrame
  102. )
  103. {
  104. register DWORD dwReturn;
  105. PMMCALLPROC3216 parg16;
  106. GETARGPTR(pFrame, sizeof(PMMCALLPROC32), parg16);
  107. // Don't call to Zero
  108. if (parg16->lpProcAddress == 0) {
  109. LOGDEBUG(LOG_ALWAYS,("MMCallProc32 - Error calling to 0 not allowed"));
  110. return(0);
  111. }
  112. //
  113. // Make sure we have the correct 16 bit directory set.
  114. //
  115. if (parg16->fSetCurrentDirectory != 0) {
  116. UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
  117. }
  118. dwReturn = ((FARPROC)parg16->lpProcAddress)( parg16->p5, parg16->p4,
  119. parg16->p3, parg16->p2,
  120. parg16->p1);
  121. FREEARGPTR(parg16);
  122. return dwReturn;
  123. }
  124. /******************************Public*Routine******************************\
  125. * WOW32ResolveMemory
  126. *
  127. * Enable multi-media (and others) to reliably map memory from 16 bit land
  128. * to 32 bit land.
  129. *
  130. * History:
  131. * dd-mm-93 - StephenE - Created
  132. *
  133. \**************************************************************************/
  134. LPVOID APIENTRY
  135. WOW32ResolveMemory(
  136. VPVOID vp
  137. )
  138. {
  139. LPVOID lpReturn;
  140. GETMISCPTR( vp, lpReturn );
  141. return lpReturn;
  142. }
  143. /**********************************************************************\
  144. * WOW32ResolveHandle
  145. *
  146. * This is a general purpose handle mapping function. It allows WOW thunk
  147. * extensions to get access to 32 bit handles given a 16 bit handle.
  148. *
  149. \**********************************************************************/
  150. BOOL APIENTRY WOW32ResolveHandle( UINT uHandleType, UINT uMappingDirection,
  151. WORD wHandle16_In, LPWORD lpwHandle16_Out,
  152. DWORD dwHandle32_In, LPDWORD lpdwHandle32_Out )
  153. {
  154. BOOL fReturn = FALSE;
  155. DWORD dwHandle32;
  156. WORD wHandle16;
  157. static FARPROC mmAPI = NULL;
  158. GET_MULTIMEDIA_API( "WOW32ResolveMultiMediaHandle", mmAPI,
  159. MMSYSERR_NODRIVER );
  160. if ( uMappingDirection == WOW32_DIR_16IN_32OUT ) {
  161. switch ( uHandleType ) {
  162. case WOW32_USER_HANDLE:
  163. dwHandle32 = (DWORD)USER32( wHandle16_In );
  164. break;
  165. case WOW32_GDI_HANDLE:
  166. dwHandle32 = (DWORD)GDI32( wHandle16_In );
  167. break;
  168. case WOW32_WAVEIN_HANDLE:
  169. case WOW32_WAVEOUT_HANDLE:
  170. case WOW32_MIDIOUT_HANDLE:
  171. case WOW32_MIDIIN_HANDLE:
  172. (*mmAPI)( uHandleType, uMappingDirection, wHandle16_In,
  173. lpwHandle16_Out, dwHandle32_In, lpdwHandle32_Out );
  174. dwHandle32 = 0;
  175. fReturn = TRUE;
  176. break;
  177. }
  178. /*
  179. ** Protect ourself from being given a duff pointer.
  180. */
  181. try {
  182. if ( dwHandle32 ) {
  183. if ( *lpdwHandle32_Out = dwHandle32 ) {
  184. fReturn = TRUE;
  185. }
  186. else {
  187. fReturn = FALSE;
  188. }
  189. }
  190. } except( EXCEPTION_EXECUTE_HANDLER ) {
  191. fReturn = FALSE;
  192. }
  193. }
  194. else if ( uMappingDirection == WOW32_DIR_32IN_16OUT ) {
  195. switch ( uHandleType ) {
  196. case WOW32_USER_HANDLE:
  197. wHandle16 = (WORD)USER16( dwHandle32_In );
  198. break;
  199. case WOW32_GDI_HANDLE:
  200. wHandle16 = (WORD)GDI16( dwHandle32_In );
  201. break;
  202. case WOW32_WAVEIN_HANDLE:
  203. case WOW32_WAVEOUT_HANDLE:
  204. case WOW32_MIDIOUT_HANDLE:
  205. case WOW32_MIDIIN_HANDLE:
  206. (*mmAPI)( uHandleType, uMappingDirection, wHandle16_In,
  207. lpwHandle16_Out, dwHandle32_In, lpdwHandle32_Out );
  208. wHandle16 = 0;
  209. fReturn = TRUE;
  210. break;
  211. }
  212. /*
  213. ** Protect ourself from being given a duff pointer.
  214. */
  215. try {
  216. if ( wHandle16 ) {
  217. if ( *lpwHandle16_Out = wHandle16 ) {
  218. fReturn = TRUE;
  219. }
  220. else {
  221. fReturn = FALSE;
  222. }
  223. }
  224. } except( EXCEPTION_EXECUTE_HANDLER ) {
  225. fReturn = FALSE;
  226. }
  227. }
  228. return fReturn;
  229. }
  230. /**********************************************************************\
  231. *
  232. * WOW32DriverCallback
  233. *
  234. * Callback stub, which invokes the "real" 16 bit callback.
  235. * The parameters to this function must be in the format that the 16 bit
  236. * code expects, i.e. all handles must be 16 bit handles, all addresses must
  237. * be 16:16 ones.
  238. *
  239. *
  240. * It is possible that this function will have been called with the
  241. * DCB_WINDOW set in which case the 16 bit interrupt handler will call
  242. * PostMessage. Howver, it is much more efficient if PostMessage is called
  243. * from the 32 bit side.
  244. *
  245. \**********************************************************************/
  246. BOOL APIENTRY WOW32DriverCallback( DWORD dwCallback, DWORD dwFlags,
  247. WORD wID, WORD wMsg,
  248. DWORD dwUser, DWORD dw1, DWORD dw2 )
  249. {
  250. static FARPROC mmAPI = NULL;
  251. GET_MULTIMEDIA_API( "WOW32DriverCallback", mmAPI, MMSYSERR_NODRIVER );
  252. /*
  253. ** Just pass the call onto winmm
  254. */
  255. return (*mmAPI)( dwCallback, dwFlags, wID, wMsg, dwUser, dw1, dw2 );
  256. }
  257. /**********************************************************************\
  258. *
  259. * Get_MultiMedia_ProcAddress
  260. *
  261. * This function gets the address of the given Multi-Media api. It loads
  262. * Winmm.dll if this it has not already been loaded.
  263. *
  264. \**********************************************************************/
  265. FARPROC Get_MultiMedia_ProcAddress( LPSTR lpstrProcName )
  266. {
  267. /*
  268. ** Either this is the first time this function has been called
  269. ** or the Multi-Media sub-system is in a bad way.
  270. */
  271. if ( hWinmm == NULL ) {
  272. // dprintf2(( "Attempting to load WINMM.DLL" ));
  273. hWinmm = SafeLoadLibrary( "WINMM.DLL" );
  274. if ( hWinmm == NULL ) {
  275. /* Looks like the Multi-Media sub-system is in a bad way */
  276. // dprintf2(( "FAILED TO LOAD WINMM.DLL!!" ));
  277. return NULL;
  278. }
  279. }
  280. return GetProcAddress( hWinmm, lpstrProcName );
  281. }
  282. /**********************************************************************\
  283. *
  284. * WOWDelayTimeGetTime
  285. *
  286. * on faster machines timeGetTime can return the same value
  287. * and some apps will take diff (0) to divide and fault
  288. * to prevent that check if it is one
  289. * of the known apps that do that and sleep if necessary
  290. *
  291. *
  292. \**********************************************************************/
  293. BOOL APIENTRY WOWDelayTimeGetTime(void)
  294. {
  295. if(CURRENTPTD()->dwWOWCompatFlags2 & WOWCF2_DELAYTIMEGETTIME) {
  296. Sleep(1);
  297. return 1;
  298. }
  299. return 0;
  300. }