afl.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:23k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: 7cb0eb8f180ed1c925df4f5a39ad37340f83437f $
  3.  *
  4.  * Copyright (C) 1998 Patrick Stridvall
  5.  * Copyright (C) 1999 Eric Pouech
  6.  *
  7.  * Originally distributed under LPGL 2.1 (or later) by the Wine project.
  8.  *
  9.  * Modified for use with MPlayer, detailed CVS changelog at
  10.  * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
  11.  *
  12.  * File now distributed as part of VLC media player with no modifications.
  13.  *
  14.  * This program is free software; you can redistribute it and/or modify
  15.  * it under the terms of the GNU General Public License as published by
  16.  * the Free Software Foundation; either version 2 of the License, or
  17.  * (at your option) any later version.
  18.  *
  19.  * This program is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  * GNU General Public License for more details.
  23.  *
  24.  * You should have received a copy of the GNU General Public License
  25.  * along with this program; if not, write to the Free Software
  26.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  27.  */
  28. /**************************************************************************
  29.   This file will contain an interface to ACM drivers.
  30.   Its content will be based mainly on wine/dlls/msacm32
  31.   actually, for audio decompression only the following functions
  32.   are needed:
  33.   
  34.   acmStreamOpen ( takes formats of src and dest, returns stream handle )
  35.   acmStreamPrepareHeader ( takes stream handler and info on data )
  36.   acmStreamConvert ( the same as PrepareHeader )
  37.   acmStreamUnprepareHeader
  38.   acmStreamClose
  39.   acmStreamSize
  40.   maybe acmStreamReset
  41.   
  42.   In future I'll also add functions for format enumeration, 
  43.   but not right now.
  44.   Modified for use with MPlayer, detailed CVS changelog at
  45.   http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
  46.   
  47. ***************************************************************************/
  48. #include "config.h"
  49. #include "wine/winbase.h"
  50. #include "wine/windef.h"
  51. #include "wine/winuser.h"
  52. #include "wine/vfw.h"
  53. #include "wine/winestring.h"
  54. #include "wine/driver.h"
  55. #include "wine/winerror.h"
  56. #include "wine/msacm.h"
  57. #include "wine/msacmdrv.h"
  58. #include "wineacm.h"
  59. #ifndef __MINGW32__
  60. #include "ext.h"
  61. #endif
  62. #include "driver.h"
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. #include <string.h>
  66. #pragma pack(1)
  67. #define OpenDriverA DrvOpen
  68. #define CloseDriver DrvClose
  69. static inline PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
  70. {
  71.     return (PWINE_ACMSTREAM)has;
  72. }
  73. /***********************************************************************
  74.  *           acmDriverAddA (MSACM32.2)
  75.  */
  76. MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
  77.       LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
  78. {
  79.     if (!phadid)
  80. return MMSYSERR_INVALPARAM;
  81.     
  82.     /* Check if any unknown flags */
  83.     if (fdwAdd & 
  84. ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
  85.   ACM_DRIVERADDF_GLOBAL))
  86. return MMSYSERR_INVALFLAG;
  87.     
  88.     /* Check if any incompatible flags */
  89.     if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && 
  90. (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
  91. return MMSYSERR_INVALFLAG;
  92.     
  93.     /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a 
  94.      * LoadDriver on it, to be sure we can call SendDriverMessage on the
  95.      * hDrvr handle.
  96.      */
  97.     *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, 0, hinstModule);
  98.     
  99.     /* FIXME: lParam, dwPriority and fdwAdd ignored */
  100.     
  101.     return MMSYSERR_NOERROR;
  102. }
  103. /***********************************************************************
  104.  *           acmDriverClose (MSACM32.4)
  105.  */
  106. MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
  107. {
  108.     PWINE_ACMDRIVER  p;
  109.     PWINE_ACMDRIVER* tp;
  110.     
  111.     if (fdwClose)
  112. return MMSYSERR_INVALFLAG;
  113.     
  114.     p = MSACM_GetDriver(had);
  115.     if (!p)
  116. return MMSYSERR_INVALHANDLE;
  117.     for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
  118. if (*tp == p) {
  119.     *tp = (*tp)->pNextACMDriver;
  120.     break;
  121. }
  122.     }
  123.     
  124.     if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
  125. CloseDriver(p->hDrvr);
  126.     
  127.     HeapFree(MSACM_hHeap, 0, p);
  128.     
  129.     return MMSYSERR_NOERROR;
  130. }
  131. /***********************************************************************
  132.  *           acmDriverEnum (MSACM32.7)
  133.  */
  134. MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
  135. {
  136.     PWINE_ACMDRIVERID p;
  137.     DWORD fdwSupport;
  138.     if (!fnCallback) {
  139. return MMSYSERR_INVALPARAM;
  140.     }
  141.     
  142.     if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
  143. return MMSYSERR_INVALFLAG;
  144.     }
  145.     
  146.     for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
  147. fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
  148. if (!p->bEnabled) {
  149.     if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
  150. fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
  151.     else
  152. continue;
  153. }
  154. (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
  155.     }
  156.     
  157.     return MMSYSERR_NOERROR;
  158. }
  159. /***********************************************************************
  160.  *           acmDriverID (MSACM32.8)
  161.  */
  162. MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
  163. {
  164.     PWINE_ACMOBJ pao;
  165.     
  166.     pao = MSACM_GetObj(hao);
  167.     if (!pao)
  168. return MMSYSERR_INVALHANDLE;
  169.     
  170.     if (!phadid)
  171. return MMSYSERR_INVALPARAM;
  172.     
  173.     if (fdwDriverID)
  174. return MMSYSERR_INVALFLAG;
  175.     
  176.     *phadid = (HACMDRIVERID) pao->pACMDriverID;
  177.     
  178.     return MMSYSERR_NOERROR;
  179. }
  180. /***********************************************************************
  181.  *           acmDriverMessage (MSACM32.9)
  182.  * FIXME
  183.  *   Not implemented
  184.  */
  185. LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
  186. {
  187.     PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
  188.     if (!pad)
  189. return MMSYSERR_INVALPARAM;
  190.     
  191.     /* FIXME: Check if uMsg legal */
  192.     
  193.     if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
  194. return MMSYSERR_NOTSUPPORTED;
  195.     
  196.     return MMSYSERR_NOERROR;
  197. }
  198. /***********************************************************************
  199.  *           acmDriverOpen (MSACM32.10)
  200.  */
  201. MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
  202. {
  203.     PWINE_ACMDRIVERID padid;
  204.     PWINE_ACMDRIVER pad;
  205.     ICOPEN icopen;
  206.     HDRVR hdrv;
  207.     TRACE("(%p, %x, %08lu)n", phad, hadid, fdwOpen);
  208.     if (!phad)
  209. return MMSYSERR_INVALPARAM;
  210.     
  211.     padid = MSACM_GetDriverID(hadid); 
  212.     if (!padid)
  213. return MMSYSERR_INVALHANDLE;
  214.     
  215.     if (fdwOpen)
  216. return MMSYSERR_INVALFLAG;
  217.     
  218.     pad = (PWINE_ACMDRIVER) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
  219.     if (!pad)
  220. return MMSYSERR_NOMEM;
  221.     pad->obj.pACMDriverID = padid;
  222.     icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c');
  223.     icopen.fccHandler = (long)padid->pszFileName;
  224.     icopen.dwSize = sizeof(ICOPEN);
  225.     icopen.dwFlags = 0;
  226.     icopen.pV1Reserved = padid->pszFileName;
  227.     if (!padid->hInstModule)
  228. pad->hDrvr = OpenDriverA((long)&icopen);
  229.     else
  230. pad->hDrvr = padid->hInstModule;
  231.     
  232.     if (!pad->hDrvr) {
  233. HeapFree(MSACM_hHeap, 0, pad);
  234. return MMSYSERR_ERROR;
  235.     }
  236.     pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
  237.     /* insert new pad at beg of list */
  238.     pad->pNextACMDriver = padid->pACMDriverList;
  239.     padid->pACMDriverList = pad;
  240.     /* FIXME: Create a WINE_ACMDRIVER32 */
  241.     *phad = (HACMDRIVER)pad;
  242.     return MMSYSERR_NOERROR;
  243. }
  244. /***********************************************************************
  245.  *           acmDriverRemove (MSACM32.12)
  246.  */
  247. MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
  248. {
  249.     PWINE_ACMDRIVERID padid;
  250.     
  251.     padid = MSACM_GetDriverID(hadid);
  252.     if (!padid)
  253. return MMSYSERR_INVALHANDLE;
  254.     
  255.     if (fdwRemove)
  256. return MMSYSERR_INVALFLAG;
  257.     
  258.     MSACM_UnregisterDriver(padid);
  259.     
  260.     return MMSYSERR_NOERROR;
  261. }
  262. /**********************************************************************/
  263. HANDLE MSACM_hHeap = (HANDLE) NULL;
  264. PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
  265. PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
  266. /***********************************************************************
  267.  *           MSACM_RegisterDriver32() 
  268.  */
  269. PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName,
  270.        WORD wFormatTag,
  271.        HINSTANCE hinstModule)
  272. {
  273.     PWINE_ACMDRIVERID padid;
  274.     TRACE("('%s', '%x', 0x%08x)n", pszFileName, wFormatTag, hinstModule);
  275. #ifndef WIN32_LOADER
  276. MSACM_hHeap = GetProcessHeap();
  277. #endif
  278.     padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
  279.     padid->pszFileName = (char*)malloc(strlen(pszFileName)+1);
  280.     strcpy(padid->pszFileName, pszFileName);
  281. //    1~strdup(pszDriverAlias);
  282.     padid->wFormatTag = wFormatTag;
  283.     padid->hInstModule = hinstModule;
  284.     padid->bEnabled = TRUE;
  285.     padid->pACMDriverList = NULL;
  286.     padid->pNextACMDriverID = NULL;
  287.     padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
  288.     if (MSACM_pLastACMDriverID)
  289. MSACM_pLastACMDriverID->pNextACMDriverID = padid;
  290.     MSACM_pLastACMDriverID = padid;
  291.     if (!MSACM_pFirstACMDriverID)
  292. MSACM_pFirstACMDriverID = padid;
  293.     
  294.     return padid;
  295. }
  296. /***********************************************************************
  297.  *           MSACM_UnregisterDriver32()
  298.  */
  299. PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
  300. {
  301.     PWINE_ACMDRIVERID pNextACMDriverID;
  302.     
  303.     while (p->pACMDriverList)
  304. acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
  305.     
  306.     free( p->pszFileName );
  307.     
  308.     if (p == MSACM_pFirstACMDriverID)
  309. MSACM_pFirstACMDriverID = p->pNextACMDriverID;
  310.     if (p == MSACM_pLastACMDriverID)
  311. MSACM_pLastACMDriverID = p->pPrevACMDriverID;
  312.     if (p->pPrevACMDriverID)
  313. p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
  314.     if (p->pNextACMDriverID)
  315. p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
  316.     
  317.     pNextACMDriverID = p->pNextACMDriverID;
  318.     
  319.     HeapFree(MSACM_hHeap, 0, p);
  320.     
  321.     return pNextACMDriverID;
  322. }
  323. /***********************************************************************
  324.  *           MSACM_UnregisterAllDrivers32()
  325.  * FIXME
  326.  *   Where should this function be called?
  327.  */
  328. void MSACM_UnregisterAllDrivers(void)
  329. {
  330.     PWINE_ACMDRIVERID p;
  331.     for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
  332. }
  333. /***********************************************************************
  334.  *           MSACM_GetDriverID32() 
  335.  */
  336. PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
  337. {
  338.     return (PWINE_ACMDRIVERID)hDriverID;
  339. }
  340. /***********************************************************************
  341.  *           MSACM_GetDriver32()
  342.  */
  343. PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
  344. {
  345.     return (PWINE_ACMDRIVER)hDriver;
  346. }
  347. /***********************************************************************
  348.  *           MSACM_GetObj32()
  349.  */
  350. PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
  351. {
  352.     return (PWINE_ACMOBJ)hObj;
  353. }
  354. /***********************************************************************
  355.  *           acmStreamOpen (MSACM32.40)
  356.  */
  357. MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
  358.       PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
  359.       DWORD dwInstance, DWORD fdwOpen)
  360. {
  361.     PWINE_ACMSTREAM was;
  362.     PWINE_ACMDRIVER wad;
  363.     MMRESULT ret;
  364.     int wfxSrcSize;
  365.     int wfxDstSize;
  366.     
  367.     TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)n",
  368.   phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
  369.     TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]n", 
  370.   pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec, 
  371.   pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
  372.     TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]n", 
  373.   pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec, 
  374.   pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
  375. #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
  376.     wfxSrcSize = SIZEOF_WFX(pwfxSrc);
  377.     wfxDstSize = SIZEOF_WFX(pwfxDst);
  378. #undef SIZEOF_WFX
  379.     was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
  380.     if (was == NULL)
  381. return MMSYSERR_NOMEM;
  382.     was->drvInst.cbStruct = sizeof(was->drvInst);
  383.     was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
  384.     memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
  385.     // LHACM is checking for 0x1
  386.     // but if this will not help
  387.     // was->drvInst.pwfxSrc->wFormatTag = 1;
  388.     was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
  389.     memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
  390.     if (pwfltr) {
  391. was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
  392. memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
  393.     } else {
  394. was->drvInst.pwfltr = NULL;
  395.     }
  396.     was->drvInst.dwCallback = dwCallback;    
  397.     was->drvInst.dwInstance = dwInstance;
  398.     was->drvInst.fdwOpen = fdwOpen;
  399.     was->drvInst.fdwDriver = 0L;  
  400.     was->drvInst.dwDriver = 0L;     
  401.     was->drvInst.has = (HACMSTREAM)was;
  402.     
  403.     if (had) {
  404. if (!(wad = MSACM_GetDriver(had))) {
  405.     ret = MMSYSERR_INVALPARAM;
  406.     goto errCleanUp;
  407. }
  408. was->obj.pACMDriverID = wad->obj.pACMDriverID;
  409. was->pDrv = wad;
  410. was->hAcmDriver = 0; /* not to close it in acmStreamClose */
  411. ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
  412. if (ret != MMSYSERR_NOERROR)
  413.     goto errCleanUp;
  414.     } else {
  415. PWINE_ACMDRIVERID wadi;
  416. short drv_tag;
  417. ret = ACMERR_NOTPOSSIBLE;
  418. /* if(pwfxSrc->wFormatTag==1)//compression
  419.     drv_tag=pwfxDst->wFormatTag;
  420.     else
  421.     if(pwfxDst->wFormatTag==1)//decompression
  422. drv_tag=pwfxSrc->wFormatTag;
  423. else
  424. goto errCleanUp;
  425.     ret=acmDriverOpen2(drv_tag); 
  426.     if (ret == MMSYSERR_NOERROR) {
  427. if ((wad = MSACM_GetDriver(had)) != 0) {
  428.     was->obj.pACMDriverID = wad->obj.pACMDriverID;
  429.     was->pDrv = wad;
  430.     was->hAcmDriver = had;
  431.     
  432.     ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
  433.     if (ret == MMSYSERR_NOERROR) {
  434. if (fdwOpen & ACM_STREAMOPENF_QUERY) {
  435.     acmDriverClose(had, 0L);
  436. }
  437. break;
  438.     }
  439. }
  440. acmDriverClose(had, 0L);*/
  441. //if(MSACM_pFirstACMDriverID==NULL)
  442. //    MSACM_RegisterAllDrivers();
  443. for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID)
  444. {
  445.     /* Check Format */
  446.     if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue;
  447.     ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
  448.     if (ret == MMSYSERR_NOERROR) {
  449. if ((wad = MSACM_GetDriver(had)) != NULL) {
  450.     was->obj.pACMDriverID = wad->obj.pACMDriverID;
  451.     was->pDrv = wad;
  452.     was->hAcmDriver = had;
  453.     
  454.     ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
  455.     //lhacm - crash printf("RETOPEN %dn", ret);
  456.                     //ret = 0;
  457.     if (ret == MMSYSERR_NOERROR) {
  458. if (fdwOpen & ACM_STREAMOPENF_QUERY) {
  459.     acmDriverClose(had, 0L);
  460. }
  461. break;
  462.     }
  463. }
  464. // no match, close this acm driver and try next one 
  465. acmDriverClose(had, 0L);
  466.     }
  467. }
  468. if (ret != MMSYSERR_NOERROR) {
  469.     ret = ACMERR_NOTPOSSIBLE;
  470.     goto errCleanUp;
  471. }
  472.     }
  473.     ret = MMSYSERR_NOERROR;
  474.     if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
  475. if (phas)
  476.     *phas = (HACMSTREAM)was;
  477. TRACE("=> (%d)n", ret);
  478. #ifdef WIN32_LOADER
  479.         CodecAlloc();
  480. #endif
  481. return ret;
  482.     }
  483. errCleanUp:
  484.     if (phas)
  485. *phas = (HACMSTREAM)0;
  486.     HeapFree(MSACM_hHeap, 0, was);
  487.     TRACE("=> (%d)n", ret);
  488.     return ret;
  489. }
  490. MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
  491. {
  492.     PWINE_ACMSTREAM was;
  493.     MMRESULT ret;
  494.     TRACE("(0x%08x, %ld)n", has, fdwClose);
  495.     
  496.     if ((was = ACM_GetStream(has)) == NULL) {
  497. return MMSYSERR_INVALHANDLE;
  498.     }
  499.     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
  500.     if (ret == MMSYSERR_NOERROR) {
  501. if (was->hAcmDriver)
  502.     acmDriverClose(was->hAcmDriver, 0L);
  503. HeapFree(MSACM_hHeap, 0, was);
  504. #ifdef WIN32_LOADER
  505.         CodecRelease();
  506. #endif
  507.     }
  508.     TRACE("=> (%d)n", ret);
  509.     return ret;
  510. }
  511. /***********************************************************************
  512.  *           acmStreamConvert (MSACM32.38)
  513.  */
  514. MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash, 
  515.  DWORD fdwConvert)
  516. {
  517.     PWINE_ACMSTREAM was;
  518.     MMRESULT ret = MMSYSERR_NOERROR;
  519.     PACMDRVSTREAMHEADER padsh;
  520.     TRACE("(0x%08x, %p, %ld)n", has, pash, fdwConvert);
  521.     if ((was = ACM_GetStream(has)) == NULL)
  522. return MMSYSERR_INVALHANDLE;
  523.     if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
  524. return MMSYSERR_INVALPARAM;
  525.     if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
  526. return ACMERR_UNPREPARED;
  527.     /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
  528.      * size. some fields are private to msacm internals, and are exposed
  529.      * in ACMSTREAMHEADER in the dwReservedDriver array
  530.      */
  531.     padsh = (PACMDRVSTREAMHEADER)pash;
  532.     /* check that pointers have not been modified */
  533.     if (padsh->pbPreparedSrc != padsh->pbSrc ||
  534. padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
  535. padsh->pbPreparedDst != padsh->pbDst ||
  536. padsh->cbPreparedDstLength < padsh->cbDstLength) {
  537. return MMSYSERR_INVALPARAM;
  538.     }
  539.     padsh->fdwConvert = fdwConvert;
  540.     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
  541.     if (ret == MMSYSERR_NOERROR) {
  542. padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
  543.     }
  544.     TRACE("=> (%d)n", ret);
  545.     return ret;
  546. }
  547. /***********************************************************************
  548.  *           acmStreamPrepareHeader (MSACM32.41)
  549.  */
  550. MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, 
  551.        DWORD fdwPrepare)
  552. {
  553.     PWINE_ACMSTREAM was;
  554.     MMRESULT ret = MMSYSERR_NOERROR;
  555.     PACMDRVSTREAMHEADER padsh;
  556.     TRACE("(0x%08x, %p, %ld)n", has, pash, fdwPrepare);
  557.     
  558.     if ((was = ACM_GetStream(has)) == NULL)
  559. return MMSYSERR_INVALHANDLE;
  560.     if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
  561. return MMSYSERR_INVALPARAM;
  562.     if (fdwPrepare)
  563. ret = MMSYSERR_INVALFLAG;
  564.     if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
  565. return MMSYSERR_NOERROR;
  566.     /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
  567.      * size. some fields are private to msacm internals, and are exposed
  568.      * in ACMSTREAMHEADER in the dwReservedDriver array
  569.      */
  570.     padsh = (PACMDRVSTREAMHEADER)pash;
  571.     padsh->fdwConvert = fdwPrepare;
  572.     padsh->padshNext = NULL;
  573.     padsh->fdwDriver = padsh->dwDriver = 0L;
  574.     padsh->fdwPrepared = 0;
  575.     padsh->dwPrepared = 0;
  576.     padsh->pbPreparedSrc = 0;
  577.     padsh->cbPreparedSrcLength = 0;
  578.     padsh->pbPreparedDst = 0;
  579.     padsh->cbPreparedDstLength = 0;
  580.     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
  581.     if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
  582. ret = MMSYSERR_NOERROR;
  583. padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
  584. padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
  585. padsh->fdwPrepared = padsh->fdwStatus;
  586. padsh->dwPrepared = 0;
  587. padsh->pbPreparedSrc = padsh->pbSrc;
  588. padsh->cbPreparedSrcLength = padsh->cbSrcLength;
  589. padsh->pbPreparedDst = padsh->pbDst;
  590. padsh->cbPreparedDstLength = padsh->cbDstLength;
  591.     } else {
  592. padsh->fdwPrepared = 0;
  593. padsh->dwPrepared = 0;
  594. padsh->pbPreparedSrc = 0;
  595. padsh->cbPreparedSrcLength = 0;
  596. padsh->pbPreparedDst = 0;
  597. padsh->cbPreparedDstLength = 0;
  598.     }
  599.     TRACE("=> (%d)n", ret);
  600.     return ret;
  601. }
  602. /***********************************************************************
  603.  *           acmStreamReset (MSACM32.42)
  604.  */
  605. MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
  606. {
  607.     PWINE_ACMSTREAM was;
  608.     MMRESULT ret = MMSYSERR_NOERROR;
  609.     TRACE("(0x%08x, %ld)n", has, fdwReset);
  610.     if (fdwReset) {
  611. ret = MMSYSERR_INVALFLAG;
  612.     } else if ((was = ACM_GetStream(has)) == NULL) {
  613. return MMSYSERR_INVALHANDLE;
  614.     } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
  615. ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
  616.     }
  617.     TRACE("=> (%d)n", ret);
  618.     return ret;
  619. }
  620. /***********************************************************************
  621.  *           acmStreamSize (MSACM32.43)
  622.  */
  623. MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput, 
  624.       LPDWORD pdwOutputBytes, DWORD fdwSize)
  625. {
  626.     PWINE_ACMSTREAM was;
  627.     ACMDRVSTREAMSIZE adss;
  628.     MMRESULT ret;
  629.     
  630.     TRACE("(0x%08x, %ld, %p, %ld)n", has, cbInput, pdwOutputBytes, fdwSize);
  631.     
  632.     if ((was = ACM_GetStream(has)) == NULL) {
  633. return MMSYSERR_INVALHANDLE;
  634.     }
  635.     if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
  636. return MMSYSERR_INVALFLAG;
  637.     }
  638.     *pdwOutputBytes = 0L;
  639.     
  640.     switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
  641.     case ACM_STREAMSIZEF_DESTINATION:
  642. adss.cbDstLength = cbInput;
  643. adss.cbSrcLength = 0;
  644. break;
  645.     case ACM_STREAMSIZEF_SOURCE:
  646. adss.cbSrcLength = cbInput;
  647. adss.cbDstLength = 0;
  648. break;
  649.     default:
  650. return MMSYSERR_INVALFLAG;
  651.     }
  652.     
  653.     adss.cbStruct = sizeof(adss);
  654.     adss.fdwSize = fdwSize;
  655.     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE, 
  656.     (DWORD)&was->drvInst, (DWORD)&adss);
  657.     if (ret == MMSYSERR_NOERROR) {
  658. switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
  659. case ACM_STREAMSIZEF_DESTINATION:
  660.     *pdwOutputBytes = adss.cbSrcLength;
  661.     break;
  662. case ACM_STREAMSIZEF_SOURCE:
  663.     *pdwOutputBytes = adss.cbDstLength;
  664.     break;
  665. }
  666.     }
  667.     TRACE("=> (%d) [%lu]n", ret, *pdwOutputBytes);
  668.     return ret;
  669. }
  670. /***********************************************************************
  671.  *           acmStreamUnprepareHeader (MSACM32.44)
  672.  */
  673. MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, 
  674.  DWORD fdwUnprepare)
  675. {
  676.     PWINE_ACMSTREAM was;
  677.     MMRESULT ret = MMSYSERR_NOERROR;
  678.     PACMDRVSTREAMHEADER padsh;
  679.     TRACE("(0x%08x, %p, %ld)n", has, pash, fdwUnprepare);
  680.     
  681.     if ((was = ACM_GetStream(has)) == NULL)
  682. return MMSYSERR_INVALHANDLE;
  683.     if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
  684. return MMSYSERR_INVALPARAM;
  685.     if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
  686. return ACMERR_UNPREPARED;
  687.     /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
  688.      * size. some fields are private to msacm internals, and are exposed
  689.      * in ACMSTREAMHEADER in the dwReservedDriver array
  690.      */
  691.     padsh = (PACMDRVSTREAMHEADER)pash;
  692.     /* check that pointers have not been modified */
  693.     if (padsh->pbPreparedSrc != padsh->pbSrc ||
  694. padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
  695. padsh->pbPreparedDst != padsh->pbDst ||
  696. padsh->cbPreparedDstLength < padsh->cbDstLength) {
  697. return MMSYSERR_INVALPARAM;
  698.     }
  699.     padsh->fdwConvert = fdwUnprepare;
  700.     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
  701.     if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
  702. ret = MMSYSERR_NOERROR;
  703. padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
  704.     }
  705.     TRACE("=> (%d)n", ret);
  706.     return ret;
  707. }