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.

539 lines
16 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WMMSTRU2.C
  8. * WOW32 16-bit MultiMedia structure conversion support
  9. * Contains support for mciSendCommand UnThunk message Parms.
  10. *
  11. * History:
  12. * Created 17-Jul-1992 by Stephen Estrop (stephene)
  13. *
  14. --*/
  15. //
  16. // We define NO_STRICT so that the compiler doesn't moan and groan when
  17. // I use the FARPROC type for the Multi-Media api loading.
  18. //
  19. #define NO_STRICT
  20. #include "precomp.h"
  21. #pragma hdrstop
  22. #if 0
  23. MODNAME(wmmstru2.c);
  24. //
  25. // The following are required for the dynamic linking of Multi-Media code
  26. // from within WOW. They are all defined in wmmedia.c
  27. //
  28. extern FARPROC mmAPIEatCmdEntry;
  29. extern FARPROC mmAPIGetParamSize;
  30. extern FARPROC mmAPIUnlockCmdTable;
  31. extern FARPROC mmAPISendCmdW;
  32. /**********************************************************************\
  33. *
  34. * UnThunkMciCommand16
  35. *
  36. * This function "unthunks" a 32 bit mci send command request.
  37. *
  38. * The ideas behind this function were stolen from UnThunkWMMsg16,
  39. * see wmsg16.c
  40. *
  41. \**********************************************************************/
  42. INT UnThunkMciCommand16( MCIDEVICEID devID, UINT OrigCommand, DWORD OrigFlags,
  43. DWORD OrigParms, DWORD NewParms, LPWSTR lpCommand,
  44. UINT uTable )
  45. {
  46. BOOL fReturnValNotThunked = FALSE;
  47. #if DBG
  48. static LPSTR f_name = "UnThunkMciCommand16: ";
  49. register int i;
  50. int n;
  51. dprintf3(( "UnThunkMciCommand :" ));
  52. n = sizeof(mciMessageNames) / sizeof(MCI_MESSAGE_NAMES);
  53. for ( i = 0; i < n; i++ ) {
  54. if ( mciMessageNames[i].uMsg == OrigCommand ) {
  55. break;
  56. }
  57. }
  58. dprintf3(( "OrigCommand -> %lX", (DWORD)OrigCommand ));
  59. dprintf3(( " Name -> %s", i != n ? mciMessageNames[i].lpstMsgName : "Unkown Name" ));
  60. dprintf5(( " OrigFlags -> %lX", OrigFlags ));
  61. dprintf5(( " OrigParms -> %lX", OrigParms ));
  62. dprintf5(( " NewParms -> %lX", NewParms ));
  63. //
  64. // If NewParms is 0 we shouldn't be here, I haven't got an assert
  65. // macro, but the following we do the same thing.
  66. //
  67. if ( NewParms == 0 ) {
  68. dprintf(( "%scalled with NewParms == NULL !!", f_name ));
  69. dprintf(( "Call StephenE NOW !!" ));
  70. DebugBreak();
  71. }
  72. #endif
  73. //
  74. // We have to do a manual unthunk of MCI_SYSINFO because the
  75. // command table is not consistent. As a command table should be
  76. // available now we can load it and then use it to unthunk MCI_OPEN.
  77. //
  78. switch ( OrigCommand ) {
  79. case MCI_OPEN:
  80. UnThunkOpenCmd( OrigFlags, OrigParms, NewParms );
  81. break;
  82. case MCI_SYSINFO:
  83. UnThunkSysInfoCmd( OrigFlags, OrigParms, NewParms );
  84. break;
  85. case MCI_STATUS:
  86. UnThunkStatusCmd( devID, OrigFlags, OrigParms, NewParms );
  87. break;
  88. default:
  89. fReturnValNotThunked = TRUE;
  90. break;
  91. }
  92. //
  93. // Do we have a command table ? It is possible that we have
  94. // a custom command but we did not find a custom command table, in which
  95. // case we should just free the pNewParms storage.
  96. //
  97. if ( lpCommand != NULL ) {
  98. //
  99. // We now parse the custom command table to see if there is a
  100. // return field in the parms structure.
  101. //
  102. dprintf3(( "%sUnthunking via command table", f_name ));
  103. UnThunkCommandViaTable( lpCommand, OrigFlags, OrigParms,
  104. NewParms, fReturnValNotThunked );
  105. //
  106. // Now we have finished with the command table we should unlock it.
  107. //
  108. dprintf4(( "%sUnlocking custom command table", f_name ));
  109. (*mmAPIUnlockCmdTable)( uTable );
  110. }
  111. //
  112. // All that needs to be done now is to free the storage
  113. // that was allocated during the ThunkXxxCmd function.
  114. //
  115. dprintf4(( "%sFreeing storage.", f_name ));
  116. free_w( (PBYTE)NewParms );
  117. return 0;
  118. }
  119. /**********************************************************************\
  120. * UnThunkOpenCmd
  121. *
  122. * UnThunk the Open mci command parms.
  123. \**********************************************************************/
  124. VOID UnThunkOpenCmd( DWORD OrigFlags, DWORD OrigParms, DWORD NewParms )
  125. {
  126. #if DBG
  127. static LPSTR f_name = "UnThunkOpenCmd: ";
  128. #endif
  129. LPMCI_OPEN_PARMS lpOpeParms = (LPMCI_OPEN_PARMS)NewParms;
  130. PMCI_OPEN_PARMS16 lpOpeParms16;
  131. WORD wDevice;
  132. dprintf4(( "%sCopying Device ID.", f_name ));
  133. GETVDMPTR( OrigParms, sizeof(MCI_OPEN_PARMS16), lpOpeParms16 );
  134. wDevice = LOWORD( lpOpeParms->wDeviceID );
  135. STOREWORD( lpOpeParms16->wDeviceID, wDevice );
  136. FLUSHVDMPTR( OrigParms, sizeof(MCI_OPEN_PARMS16), lpOpeParms16 );
  137. FREEVDMPTR( lpOpeParms16 );
  138. dprintf5(( "wDeviceID -> %u", wDevice ));
  139. if ( (OrigParms & MCI_OPEN_TYPE) && !(OrigParms & MCI_OPEN_TYPE_ID ) ) {
  140. dprintf3(( "%sFreeing a STRING pointer", f_name ));
  141. FREEPSZPTR( lpOpeParms->lpstrDeviceType );
  142. }
  143. if ( (OrigParms & MCI_OPEN_ELEMENT)
  144. && !(OrigParms & MCI_OPEN_ELEMENT_ID ) ) {
  145. dprintf3(( "%sFreeing a STRING pointer", f_name ));
  146. FREEPSZPTR( lpOpeParms->lpstrElementName );
  147. }
  148. }
  149. /**********************************************************************\
  150. * UnThunkSysInfoCmd
  151. *
  152. * UnThunk the SysInfo mci command parms.
  153. \**********************************************************************/
  154. VOID UnThunkSysInfoCmd( DWORD OrigFlags, DWORD OrigParms, DWORD NewParms )
  155. {
  156. #if DBG
  157. static LPSTR f_name = "UnThunkSysInfoCmd: ";
  158. #endif
  159. LPMCI_SYSINFO_PARMS lpSysParms = (LPMCI_SYSINFO_PARMS)NewParms;
  160. //
  161. // Had better check that we did actually allocate
  162. // a pointer.
  163. //
  164. if ( lpSysParms->lpstrReturn && lpSysParms->dwRetSize ) {
  165. #if DBG
  166. if ( !(OrigFlags & MCI_SYSINFO_QUANTITY) ) {
  167. dprintf5(( "lpstrReturn -> %s", lpSysParms->lpstrReturn ));
  168. }
  169. else {
  170. dprintf5(( "lpstrReturn -> %d", *(LPDWORD)lpSysParms->lpstrReturn ));
  171. }
  172. #endif
  173. //
  174. // Free lpSysParms->lpstrReturn;
  175. //
  176. dprintf4(( "%sFreeing lpstrReturn", f_name ));
  177. FREEVDMPTR( lpSysParms->lpstrReturn );
  178. }
  179. }
  180. /**********************************************************************\
  181. * UnThunkMciStatus
  182. *
  183. * UnThunk the Status mci command parms.
  184. \**********************************************************************/
  185. VOID UnThunkStatusCmd( MCIDEVICEID devID, DWORD OrigFlags,
  186. DWORD OrigParms, DWORD NewParms )
  187. {
  188. #if DBG
  189. static LPSTR f_name = "UnThunkStatusCmd: ";
  190. #endif
  191. MCI_GETDEVCAPS_PARMS GetDevCaps;
  192. DWORD dwRetVal;
  193. DWORD dwParm16;
  194. PDWORD pdwOrig16;
  195. PDWORD pdwParm32;
  196. int iReturnType = MCI_INTEGER;
  197. /*
  198. ** If the MCI_STATUS_ITEM flag is not specified don't bother
  199. ** doing any unthunking.
  200. */
  201. if ( !(OrigFlags & MCI_STATUS_ITEM) ) {
  202. return;
  203. }
  204. /*
  205. ** We need to determine what type of device we are
  206. ** dealing with. We can do this by send an MCI_GETDEVCAPS
  207. ** command to the device. (We might as well use the Unicode
  208. ** version of mciSendCommand and avoid another thunk).
  209. */
  210. RtlZeroMemory( &GetDevCaps, sizeof(MCI_GETDEVCAPS_PARMS) );
  211. GetDevCaps.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
  212. dwRetVal = (*mmAPISendCmdW)( devID, MCI_GETDEVCAPS, MCI_GETDEVCAPS_ITEM,
  213. (DWORD)&GetDevCaps );
  214. /*
  215. ** If we can't get the DevCaps then we are doomed.
  216. */
  217. if ( dwRetVal ) {
  218. dprintf(("%sFailure to get devcaps", f_name));
  219. return;
  220. }
  221. /*
  222. ** Determine the dwReturn type.
  223. */
  224. switch ( GetDevCaps.dwReturn ) {
  225. case MCI_DEVTYPE_ANIMATION:
  226. switch ( ((LPDWORD)NewParms)[2] ) {
  227. case MCI_ANIM_STATUS_HWND:
  228. iReturnType = MCI_HWND;
  229. break;
  230. case MCI_ANIM_STATUS_HPAL:
  231. iReturnType = MCI_HPAL;
  232. break;
  233. }
  234. break;
  235. case MCI_DEVTYPE_OVERLAY:
  236. if ( ((LPDWORD)NewParms)[2] == MCI_OVLY_STATUS_HWND ) {
  237. iReturnType = MCI_HWND;
  238. }
  239. break;
  240. case MCI_DEVTYPE_DIGITAL_VIDEO:
  241. switch ( ((LPDWORD)NewParms)[2] ) {
  242. case MCI_DGV_STATUS_HWND:
  243. iReturnType = MCI_HWND;
  244. break;
  245. case MCI_DGV_STATUS_HPAL:
  246. iReturnType = MCI_HPAL;
  247. break;
  248. }
  249. break;
  250. }
  251. /*
  252. ** Thunk the dwReturn value according to the required type
  253. */
  254. GETVDMPTR( OrigParms, sizeof( MCI_STATUS_PARMS), pdwOrig16 );
  255. pdwParm32 = (LPDWORD)((LPBYTE)NewParms + 4);
  256. switch ( iReturnType ) {
  257. case MCI_HPAL:
  258. dprintf4(( "%sFound an HPAL return field", f_name ));
  259. dwParm16 = MAKELONG( GETHPALETTE16( (HPALETTE)*pdwParm32 ), 0 );
  260. STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
  261. dprintf5(( "HDC32 -> 0x%lX", *pdwParm32 ));
  262. dprintf5(( "HDC16 -> 0x%lX", dwParm16 ));
  263. break;
  264. case MCI_HWND:
  265. dprintf4(( "%sFound an HWND return field", f_name ));
  266. dwParm16 = MAKELONG( GETHWND16( (HWND)*pdwParm32 ), 0 );
  267. STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
  268. dprintf5(( "HWND32 -> 0x%lX", *pdwParm32 ));
  269. dprintf5(( "HWND16 -> 0x%lX", dwParm16 ));
  270. break;
  271. case MCI_INTEGER:
  272. dprintf4(( "%sFound an INTEGER return field", f_name ));
  273. STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), *pdwParm32 );
  274. dprintf5(( "INTEGER -> %ld", *pdwParm32 ));
  275. break;
  276. // no default: all possible cases accounted for
  277. }
  278. /*
  279. ** Free the VDM pointer as we have finished with it
  280. */
  281. FLUSHVDMPTR( OrigParms, sizeof( MCI_STATUS_PARMS), pdwOrig16 );
  282. FREEVDMPTR( pdwOrig16 );
  283. }
  284. /**********************************************************************\
  285. * UnThunkCommandViaTable
  286. *
  287. * Thunks the return field if there is one and then frees and pointers
  288. * that were got via GETVDMPTR or GETPSZPTR.
  289. \**********************************************************************/
  290. INT UnThunkCommandViaTable( LPWSTR lpCommand, DWORD dwFlags, DWORD OrigParms,
  291. DWORD pNewParms, BOOL fReturnValNotThunked )
  292. {
  293. #if DBG
  294. static LPSTR f_name = "UnThunkCommandViaTable: ";
  295. #endif
  296. LPWSTR lpFirstParameter;
  297. UINT wID;
  298. DWORD dwValue;
  299. UINT wOffset32, wOffset1stParm32;
  300. DWORD dwParm16;
  301. DWORD Size;
  302. PDWORD pdwOrig16;
  303. PDWORD pdwParm32;
  304. DWORD dwMask = 1;
  305. //
  306. // Calculate the size of this command parameter block in terms
  307. // of bytes, then get a VDM pointer to the OrigParms.
  308. //
  309. Size = GetSizeOfParameter( lpCommand );
  310. //
  311. // Skip past command entry
  312. //
  313. lpCommand = (LPWSTR)((LPBYTE)lpCommand +
  314. (*mmAPIEatCmdEntry)( lpCommand, NULL, NULL ));
  315. //
  316. // Get the next entry
  317. //
  318. lpFirstParameter = lpCommand;
  319. //
  320. // Skip past the DWORD return value
  321. //
  322. wOffset1stParm32 = 4;
  323. lpCommand = (LPWSTR)((LPBYTE)lpCommand +
  324. (*mmAPIEatCmdEntry)( lpCommand, &dwValue, &wID ));
  325. //
  326. // If it is a return value, skip it
  327. //
  328. if ( (wID == MCI_RETURN) && (fReturnValNotThunked) ) {
  329. GETVDMPTR( OrigParms, Size, pdwOrig16 );
  330. pdwParm32 = (LPDWORD)((LPBYTE)pNewParms + 4);
  331. //
  332. // Look for a string return type, these are a special case.
  333. //
  334. switch ( dwValue ) {
  335. case MCI_STRING:
  336. dprintf4(( "%sFound a STRING return field", f_name ));
  337. //
  338. // Get string pointer and length
  339. //
  340. Size = *(LPDWORD)((LPBYTE)pNewParms + 8);
  341. //
  342. // Get the 32 bit string pointer
  343. //
  344. if ( Size > 0 ) {
  345. dprintf4(( "%sFreeing a return STRING pointer", f_name ));
  346. dprintf5(( "STRING -> %s", (LPSTR)*pdwParm32 ));
  347. FREEVDMPTR( (LPSTR)*pdwParm32 );
  348. }
  349. break;
  350. case MCI_RECT:
  351. {
  352. PRECT pRect32 = (PRECT)((LPBYTE)pNewParms + 4);
  353. PRECT16 pRect16 = (PRECT16)((LPBYTE)pdwOrig16 + 4);
  354. dprintf4(( "%sFound a RECT return field", f_name ));
  355. STORESHORT( pRect16->top, (SHORT)pRect32->top );
  356. STORESHORT( pRect16->bottom, (SHORT)pRect32->bottom );
  357. STORESHORT( pRect16->left, (SHORT)pRect32->left );
  358. STORESHORT( pRect16->right, (SHORT)pRect32->right );
  359. }
  360. break;
  361. case MCI_INTEGER:
  362. //
  363. // Get the 32 bit return integer and store it in the
  364. // 16 bit parameter structure.
  365. //
  366. dprintf4(( "%sFound an INTEGER return field", f_name ));
  367. STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), *pdwParm32 );
  368. dprintf5(( "INTEGER -> %ld", *pdwParm32 ));
  369. break;
  370. case MCI_HWND:
  371. dprintf4(( "%sFound an HWND return field", f_name ));
  372. dwParm16 = MAKELONG( GETHWND16( (HWND)*pdwParm32 ), 0 );
  373. STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
  374. dprintf5(( "HWND32 -> 0x%lX", *pdwParm32 ));
  375. dprintf5(( "HWND16 -> 0x%lX", dwParm16 ));
  376. break;
  377. case MCI_HPAL:
  378. dprintf4(( "%sFound an HPAL return field", f_name ));
  379. dwParm16 = MAKELONG( GETHPALETTE16( (HPALETTE)*pdwParm32 ), 0 );
  380. STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
  381. dprintf5(( "HDC32 -> 0x%lX", *pdwParm32 ));
  382. dprintf5(( "HDC16 -> 0x%lX", dwParm16 ));
  383. break;
  384. case MCI_HDC:
  385. dprintf4(( "%sFound an HDC return field", f_name ));
  386. dwParm16 = MAKELONG( GETHDC16( (HDC)*pdwParm32 ), 0 );
  387. STOREDWORD( *(LPDWORD)((LPBYTE)pdwOrig16 + 4), dwParm16 );
  388. dprintf5(( "HDC32 -> 0x%lX", *pdwParm32 ));
  389. dprintf5(( "HDC16 -> 0x%lX", dwParm16 ));
  390. break;
  391. }
  392. //
  393. // Free the VDM pointer as we have finished with it
  394. //
  395. FLUSHVDMPTR( OrigParms, Size, pdwOrig16 );
  396. FREEVDMPTR( pdwOrig16 );
  397. //
  398. // Adjust the offset of the first parameter.
  399. //
  400. wOffset1stParm32 = (*mmAPIGetParamSize)( dwValue, wID );
  401. //
  402. // Save the new first parameter
  403. //
  404. lpFirstParameter = lpCommand;
  405. }
  406. //
  407. // Walk through each flag looking for strings to free
  408. //
  409. while ( dwMask != 0 ) {
  410. //
  411. // Is this bit set?
  412. //
  413. if ( (dwFlags & dwMask) != 0 ) {
  414. wOffset32 = wOffset1stParm32;
  415. lpCommand = (LPWSTR)((LPBYTE)lpFirstParameter +
  416. (*mmAPIEatCmdEntry)( lpFirstParameter,
  417. &dwValue, &wID ));
  418. //
  419. // What parameter uses this bit?
  420. //
  421. while ( wID != MCI_END_COMMAND && dwValue != dwMask ) {
  422. wOffset32 = (*mmAPIGetParamSize)( dwValue, wID );
  423. if ( wID == MCI_CONSTANT ) {
  424. while ( wID != MCI_END_CONSTANT ) {
  425. lpCommand = (LPWSTR)((LPBYTE)lpCommand +
  426. (*mmAPIEatCmdEntry)( lpCommand, NULL, &wID ));
  427. }
  428. }
  429. lpCommand = (LPWSTR)((LPBYTE)lpCommand +
  430. (*mmAPIEatCmdEntry)( lpCommand, &dwValue, &wID ));
  431. }
  432. if ( wID == MCI_STRING ) {
  433. dprintf4(( "%sFreeing a STRING pointer", f_name ));
  434. pdwParm32 = (LPDWORD)((LPBYTE)pNewParms + wOffset32);
  435. FREEPSZPTR( (LPSTR)*pdwParm32 );
  436. }
  437. }
  438. //
  439. // Go to the next flag
  440. //
  441. dwMask <<= 1;
  442. }
  443. return 0;
  444. }
  445. #endif