1 /**************************************************************************
4 This file will contain an interface to ACM drivers.
5 Its content will be based mainly on wine/dlls/msacm32
6 actually, for audio decompression only the following functions
9 acmStreamOpen ( takes formats of src and dest, returns stream handle )
10 acmStreamPrepareHeader ( takes stream handler and info on data )
11 acmStreamConvert ( the same as PrepareHeader )
12 acmStreamUnprepareHeader
17 In future I'll also add functions for format enumeration,
20 Modified for use with MPlayer, detailed changelog at
21 http://svn.mplayerhq.hu/mplayer/trunk/
23 ***************************************************************************/
27 #include "wine/winbase.h"
28 #include "wine/windef.h"
29 #include "wine/winuser.h"
31 #include "wine/winestring.h"
32 #include "wine/driver.h"
33 #include "wine/winerror.h"
34 #include "wine/msacm.h"
35 #include "wine/msacmdrv.h"
46 #define OpenDriverA DrvOpen
47 #define CloseDriver DrvClose
49 static inline PWINE_ACMSTREAM
ACM_GetStream(HACMSTREAM has
)
51 return (PWINE_ACMSTREAM
)has
;
54 /***********************************************************************
55 * acmDriverAddA (MSACM32.2)
57 MMRESULT WINAPI
acmDriverAddA(PHACMDRIVERID phadid
, HINSTANCE hinstModule
,
58 LPARAM lParam
, DWORD dwPriority
, DWORD fdwAdd
)
61 return MMSYSERR_INVALPARAM
;
63 /* Check if any unknown flags */
65 ~(ACM_DRIVERADDF_FUNCTION
|ACM_DRIVERADDF_NOTIFYHWND
|
66 ACM_DRIVERADDF_GLOBAL
))
67 return MMSYSERR_INVALFLAG
;
69 /* Check if any incompatible flags */
70 if ((fdwAdd
& ACM_DRIVERADDF_FUNCTION
) &&
71 (fdwAdd
& ACM_DRIVERADDF_NOTIFYHWND
))
72 return MMSYSERR_INVALFLAG
;
74 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
75 * LoadDriver on it, to be sure we can call SendDriverMessage on the
78 *phadid
= (HACMDRIVERID
) MSACM_RegisterDriver(NULL
, 0, hinstModule
);
80 /* FIXME: lParam, dwPriority and fdwAdd ignored */
82 return MMSYSERR_NOERROR
;
85 /***********************************************************************
86 * acmDriverClose (MSACM32.4)
88 MMRESULT WINAPI
acmDriverClose(HACMDRIVER had
, DWORD fdwClose
)
94 return MMSYSERR_INVALFLAG
;
96 p
= MSACM_GetDriver(had
);
98 return MMSYSERR_INVALHANDLE
;
100 for (tp
= &(p
->obj
.pACMDriverID
->pACMDriverList
); *tp
; *tp
= (*tp
)->pNextACMDriver
) {
102 *tp
= (*tp
)->pNextACMDriver
;
107 if (p
->hDrvr
&& !p
->obj
.pACMDriverID
->pACMDriverList
)
108 CloseDriver(p
->hDrvr
);
110 HeapFree(MSACM_hHeap
, 0, p
);
112 return MMSYSERR_NOERROR
;
115 /***********************************************************************
116 * acmDriverEnum (MSACM32.7)
118 MMRESULT WINAPI
acmDriverEnum(ACMDRIVERENUMCB fnCallback
, DWORD dwInstance
, DWORD fdwEnum
)
124 return MMSYSERR_INVALPARAM
;
127 if (fdwEnum
&& ~(ACM_DRIVERENUMF_NOLOCAL
|ACM_DRIVERENUMF_DISABLED
)) {
128 return MMSYSERR_INVALFLAG
;
131 for (p
= MSACM_pFirstACMDriverID
; p
; p
= p
->pNextACMDriverID
) {
132 fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
134 if (fdwEnum
& ACM_DRIVERENUMF_DISABLED
)
135 fdwSupport
|= ACMDRIVERDETAILS_SUPPORTF_DISABLED
;
139 (*fnCallback
)((HACMDRIVERID
) p
, dwInstance
, fdwSupport
);
142 return MMSYSERR_NOERROR
;
145 /***********************************************************************
146 * acmDriverID (MSACM32.8)
148 MMRESULT WINAPI
acmDriverID(HACMOBJ hao
, PHACMDRIVERID phadid
, DWORD fdwDriverID
)
152 pao
= MSACM_GetObj(hao
);
154 return MMSYSERR_INVALHANDLE
;
157 return MMSYSERR_INVALPARAM
;
160 return MMSYSERR_INVALFLAG
;
162 *phadid
= (HACMDRIVERID
) pao
->pACMDriverID
;
164 return MMSYSERR_NOERROR
;
167 /***********************************************************************
168 * acmDriverMessage (MSACM32.9)
172 LRESULT WINAPI
acmDriverMessage(HACMDRIVER had
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
174 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
176 return MMSYSERR_INVALPARAM
;
178 /* FIXME: Check if uMsg legal */
180 if (!SendDriverMessage(pad
->hDrvr
, uMsg
, lParam1
, lParam2
))
181 return MMSYSERR_NOTSUPPORTED
;
183 return MMSYSERR_NOERROR
;
187 /***********************************************************************
188 * acmDriverOpen (MSACM32.10)
190 MMRESULT WINAPI
acmDriverOpen(PHACMDRIVER phad
, HACMDRIVERID hadid
, DWORD fdwOpen
)
192 PWINE_ACMDRIVERID padid
;
197 TRACE("(%p, %x, %08lu)\n", phad
, hadid
, fdwOpen
);
200 return MMSYSERR_INVALPARAM
;
202 padid
= MSACM_GetDriverID(hadid
);
204 return MMSYSERR_INVALHANDLE
;
207 return MMSYSERR_INVALFLAG
;
209 pad
= (PWINE_ACMDRIVER
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVER
));
211 return MMSYSERR_NOMEM
;
213 pad
->obj
.pACMDriverID
= padid
;
214 icopen
.fccType
= mmioFOURCC('a', 'u', 'd', 'c');
215 icopen
.fccHandler
= (long)padid
->pszFileName
;
216 icopen
.dwSize
= sizeof(ICOPEN
);
219 icopen
.pV1Reserved
= padid
->pszFileName
;
220 if (!padid
->hInstModule
)
221 pad
->hDrvr
= OpenDriverA((long)&icopen
);
223 pad
->hDrvr
= padid
->hInstModule
;
226 HeapFree(MSACM_hHeap
, 0, pad
);
227 return MMSYSERR_ERROR
;
230 pad
->pfnDriverProc
= GetProcAddress(pad
->hDrvr
, "DriverProc");
232 /* insert new pad at beg of list */
233 pad
->pNextACMDriver
= padid
->pACMDriverList
;
234 padid
->pACMDriverList
= pad
;
236 /* FIXME: Create a WINE_ACMDRIVER32 */
237 *phad
= (HACMDRIVER
)pad
;
239 return MMSYSERR_NOERROR
;
242 /***********************************************************************
243 * acmDriverRemove (MSACM32.12)
245 MMRESULT WINAPI
acmDriverRemove(HACMDRIVERID hadid
, DWORD fdwRemove
)
247 PWINE_ACMDRIVERID padid
;
249 padid
= MSACM_GetDriverID(hadid
);
251 return MMSYSERR_INVALHANDLE
;
254 return MMSYSERR_INVALFLAG
;
256 MSACM_UnregisterDriver(padid
);
258 return MMSYSERR_NOERROR
;
263 /**********************************************************************/
265 HANDLE MSACM_hHeap
= (HANDLE
) NULL
;
266 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID
= NULL
;
267 PWINE_ACMDRIVERID MSACM_pLastACMDriverID
= NULL
;
269 /***********************************************************************
270 * MSACM_RegisterDriver32()
272 PWINE_ACMDRIVERID
MSACM_RegisterDriver(const char* pszFileName
,
274 HINSTANCE hinstModule
)
276 PWINE_ACMDRIVERID padid
;
278 TRACE("('%s', '%x', 0x%08x)\n", pszFileName
, wFormatTag
, hinstModule
);
281 MSACM_hHeap
= GetProcessHeap();
283 padid
= (PWINE_ACMDRIVERID
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVERID
));
284 padid
->pszFileName
= malloc(strlen(pszFileName
)+1);
285 strcpy(padid
->pszFileName
, pszFileName
);
286 // 1~strdup(pszDriverAlias);
287 padid
->wFormatTag
= wFormatTag
;
288 padid
->hInstModule
= hinstModule
;
289 padid
->bEnabled
= TRUE
;
290 padid
->pACMDriverList
= NULL
;
291 padid
->pNextACMDriverID
= NULL
;
292 padid
->pPrevACMDriverID
= MSACM_pLastACMDriverID
;
293 if (MSACM_pLastACMDriverID
)
294 MSACM_pLastACMDriverID
->pNextACMDriverID
= padid
;
295 MSACM_pLastACMDriverID
= padid
;
296 if (!MSACM_pFirstACMDriverID
)
297 MSACM_pFirstACMDriverID
= padid
;
303 /***********************************************************************
304 * MSACM_UnregisterDriver32()
306 PWINE_ACMDRIVERID
MSACM_UnregisterDriver(PWINE_ACMDRIVERID p
)
308 PWINE_ACMDRIVERID pNextACMDriverID
;
310 while (p
->pACMDriverList
)
311 acmDriverClose((HACMDRIVER
) p
->pACMDriverList
, 0);
314 free(p
->pszFileName
);
316 if (p
== MSACM_pFirstACMDriverID
)
317 MSACM_pFirstACMDriverID
= p
->pNextACMDriverID
;
318 if (p
== MSACM_pLastACMDriverID
)
319 MSACM_pLastACMDriverID
= p
->pPrevACMDriverID
;
321 if (p
->pPrevACMDriverID
)
322 p
->pPrevACMDriverID
->pNextACMDriverID
= p
->pNextACMDriverID
;
323 if (p
->pNextACMDriverID
)
324 p
->pNextACMDriverID
->pPrevACMDriverID
= p
->pPrevACMDriverID
;
326 pNextACMDriverID
= p
->pNextACMDriverID
;
328 HeapFree(MSACM_hHeap
, 0, p
);
330 return pNextACMDriverID
;
333 /***********************************************************************
334 * MSACM_UnregisterAllDrivers32()
336 * Where should this function be called?
338 void MSACM_UnregisterAllDrivers(void)
342 for (p
= MSACM_pFirstACMDriverID
; p
; p
= MSACM_UnregisterDriver(p
));
345 /***********************************************************************
346 * MSACM_GetDriverID32()
348 PWINE_ACMDRIVERID
MSACM_GetDriverID(HACMDRIVERID hDriverID
)
350 return (PWINE_ACMDRIVERID
)hDriverID
;
353 /***********************************************************************
354 * MSACM_GetDriver32()
356 PWINE_ACMDRIVER
MSACM_GetDriver(HACMDRIVER hDriver
)
358 return (PWINE_ACMDRIVER
)hDriver
;
361 /***********************************************************************
364 PWINE_ACMOBJ
MSACM_GetObj(HACMOBJ hObj
)
366 return (PWINE_ACMOBJ
)hObj
;
371 /***********************************************************************
372 * acmStreamOpen (MSACM32.40)
374 MMRESULT WINAPI
acmStreamOpen(PHACMSTREAM phas
, HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
375 PWAVEFORMATEX pwfxDst
, PWAVEFILTER pwfltr
, DWORD dwCallback
,
376 DWORD dwInstance
, DWORD fdwOpen
)
384 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
385 phas
, had
, pwfxSrc
, pwfxDst
, pwfltr
, dwCallback
, dwInstance
, fdwOpen
);
387 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
388 pwfxSrc
->wFormatTag
, pwfxSrc
->nChannels
, pwfxSrc
->nSamplesPerSec
, pwfxSrc
->nAvgBytesPerSec
,
389 pwfxSrc
->nBlockAlign
, pwfxSrc
->wBitsPerSample
, pwfxSrc
->cbSize
);
391 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
392 pwfxDst
->wFormatTag
, pwfxDst
->nChannels
, pwfxDst
->nSamplesPerSec
, pwfxDst
->nAvgBytesPerSec
,
393 pwfxDst
->nBlockAlign
, pwfxDst
->wBitsPerSample
, pwfxDst
->cbSize
);
395 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
396 wfxSrcSize
= SIZEOF_WFX(pwfxSrc
);
397 wfxDstSize
= SIZEOF_WFX(pwfxDst
);
400 was
= (PWINE_ACMSTREAM
) HeapAlloc(MSACM_hHeap
, 0, sizeof(*was
) + wfxSrcSize
+ wfxDstSize
+ ((pwfltr
) ? sizeof(WAVEFILTER
) : 0));
402 return MMSYSERR_NOMEM
;
403 was
->drvInst
.cbStruct
= sizeof(was
->drvInst
);
404 was
->drvInst
.pwfxSrc
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
));
405 memcpy(was
->drvInst
.pwfxSrc
, pwfxSrc
, wfxSrcSize
);
406 // LHACM is checking for 0x1
407 // but if this will not help
408 // was->drvInst.pwfxSrc->wFormatTag = 1;
409 was
->drvInst
.pwfxDst
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
);
410 memcpy(was
->drvInst
.pwfxDst
, pwfxDst
, wfxDstSize
);
412 was
->drvInst
.pwfltr
= (PWAVEFILTER
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
+ wfxDstSize
);
413 memcpy(was
->drvInst
.pwfltr
, pwfltr
, sizeof(WAVEFILTER
));
415 was
->drvInst
.pwfltr
= NULL
;
417 was
->drvInst
.dwCallback
= dwCallback
;
418 was
->drvInst
.dwInstance
= dwInstance
;
419 was
->drvInst
.fdwOpen
= fdwOpen
;
420 was
->drvInst
.fdwDriver
= 0L;
421 was
->drvInst
.dwDriver
= 0L;
422 was
->drvInst
.has
= (HACMSTREAM
)was
;
425 if (!(wad
= MSACM_GetDriver(had
))) {
426 ret
= MMSYSERR_INVALPARAM
;
430 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
432 was
->hAcmDriver
= 0; /* not to close it in acmStreamClose */
434 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
435 if (ret
!= MMSYSERR_NOERROR
)
438 PWINE_ACMDRIVERID wadi
;
440 ret
= ACMERR_NOTPOSSIBLE
;
441 /* if(pwfxSrc->wFormatTag==1)//compression
442 drv_tag=pwfxDst->wFormatTag;
444 if(pwfxDst->wFormatTag==1)//decompression
445 drv_tag=pwfxSrc->wFormatTag;
449 ret=acmDriverOpen2(drv_tag);
450 if (ret == MMSYSERR_NOERROR) {
451 if ((wad = MSACM_GetDriver(had)) != 0) {
452 was->obj.pACMDriverID = wad->obj.pACMDriverID;
454 was->hAcmDriver = had;
456 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
457 if (ret == MMSYSERR_NOERROR) {
458 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
459 acmDriverClose(had, 0L);
464 acmDriverClose(had, 0L);*/
465 //if(MSACM_pFirstACMDriverID==NULL)
466 // MSACM_RegisterAllDrivers();
468 for (wadi
= MSACM_pFirstACMDriverID
; wadi
; wadi
= wadi
->pNextACMDriverID
)
471 if ((int)wadi
->wFormatTag
!= (int)pwfxSrc
->wFormatTag
) continue;
473 ret
= acmDriverOpen(&had
, (HACMDRIVERID
)wadi
, 0L);
474 if (ret
== MMSYSERR_NOERROR
) {
475 if ((wad
= MSACM_GetDriver(had
)) != 0) {
476 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
478 was
->hAcmDriver
= had
;
480 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
481 //lhacm - crash printf("RETOPEN %d\n", ret);
483 if (ret
== MMSYSERR_NOERROR
) {
484 if (fdwOpen
& ACM_STREAMOPENF_QUERY
) {
485 acmDriverClose(had
, 0L);
490 // no match, close this acm driver and try next one
491 acmDriverClose(had
, 0L);
494 if (ret
!= MMSYSERR_NOERROR
) {
495 ret
= ACMERR_NOTPOSSIBLE
;
499 ret
= MMSYSERR_NOERROR
;
500 if (!(fdwOpen
& ACM_STREAMOPENF_QUERY
)) {
502 *phas
= (HACMSTREAM
)was
;
503 TRACE("=> (%d)\n", ret
);
511 *phas
= (HACMSTREAM
)0;
512 HeapFree(MSACM_hHeap
, 0, was
);
513 TRACE("=> (%d)\n", ret
);
518 MMRESULT WINAPI
acmStreamClose(HACMSTREAM has
, DWORD fdwClose
)
523 TRACE("(0x%08x, %ld)\n", has
, fdwClose
);
525 if ((was
= ACM_GetStream(has
)) == NULL
) {
526 return MMSYSERR_INVALHANDLE
;
528 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CLOSE
, (DWORD
)&was
->drvInst
, 0);
529 if (ret
== MMSYSERR_NOERROR
) {
531 acmDriverClose(was
->hAcmDriver
, 0L);
532 HeapFree(MSACM_hHeap
, 0, was
);
537 TRACE("=> (%d)\n", ret
);
541 /***********************************************************************
542 * acmStreamConvert (MSACM32.38)
544 MMRESULT WINAPI
acmStreamConvert(HACMSTREAM has
, PACMSTREAMHEADER pash
,
548 MMRESULT ret
= MMSYSERR_NOERROR
;
549 PACMDRVSTREAMHEADER padsh
;
551 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwConvert
);
553 if ((was
= ACM_GetStream(has
)) == NULL
)
554 return MMSYSERR_INVALHANDLE
;
555 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
556 return MMSYSERR_INVALPARAM
;
558 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
559 return ACMERR_UNPREPARED
;
561 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
562 * size. some fields are private to msacm internals, and are exposed
563 * in ACMSTREAMHEADER in the dwReservedDriver array
565 padsh
= (PACMDRVSTREAMHEADER
)pash
;
567 /* check that pointers have not been modified */
568 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
569 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
570 padsh
->pbPreparedDst
!= padsh
->pbDst
||
571 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
572 return MMSYSERR_INVALPARAM
;
575 padsh
->fdwConvert
= fdwConvert
;
577 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CONVERT
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
578 if (ret
== MMSYSERR_NOERROR
) {
579 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_DONE
;
581 TRACE("=> (%d)\n", ret
);
586 /***********************************************************************
587 * acmStreamPrepareHeader (MSACM32.41)
589 MMRESULT WINAPI
acmStreamPrepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
593 MMRESULT ret
= MMSYSERR_NOERROR
;
594 PACMDRVSTREAMHEADER padsh
;
596 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwPrepare
);
598 if ((was
= ACM_GetStream(has
)) == NULL
)
599 return MMSYSERR_INVALHANDLE
;
600 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
601 return MMSYSERR_INVALPARAM
;
603 ret
= MMSYSERR_INVALFLAG
;
605 if (pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_DONE
)
606 return MMSYSERR_NOERROR
;
608 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
609 * size. some fields are private to msacm internals, and are exposed
610 * in ACMSTREAMHEADER in the dwReservedDriver array
612 padsh
= (PACMDRVSTREAMHEADER
)pash
;
614 padsh
->fdwConvert
= fdwPrepare
;
615 padsh
->padshNext
= NULL
;
616 padsh
->fdwDriver
= padsh
->dwDriver
= 0L;
618 padsh
->fdwPrepared
= 0;
619 padsh
->dwPrepared
= 0;
620 padsh
->pbPreparedSrc
= 0;
621 padsh
->cbPreparedSrcLength
= 0;
622 padsh
->pbPreparedDst
= 0;
623 padsh
->cbPreparedDstLength
= 0;
625 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_PREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
626 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
627 ret
= MMSYSERR_NOERROR
;
628 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
);
629 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_PREPARED
;
630 padsh
->fdwPrepared
= padsh
->fdwStatus
;
631 padsh
->dwPrepared
= 0;
632 padsh
->pbPreparedSrc
= padsh
->pbSrc
;
633 padsh
->cbPreparedSrcLength
= padsh
->cbSrcLength
;
634 padsh
->pbPreparedDst
= padsh
->pbDst
;
635 padsh
->cbPreparedDstLength
= padsh
->cbDstLength
;
637 padsh
->fdwPrepared
= 0;
638 padsh
->dwPrepared
= 0;
639 padsh
->pbPreparedSrc
= 0;
640 padsh
->cbPreparedSrcLength
= 0;
641 padsh
->pbPreparedDst
= 0;
642 padsh
->cbPreparedDstLength
= 0;
644 TRACE("=> (%d)\n", ret
);
648 /***********************************************************************
649 * acmStreamReset (MSACM32.42)
651 MMRESULT WINAPI
acmStreamReset(HACMSTREAM has
, DWORD fdwReset
)
654 MMRESULT ret
= MMSYSERR_NOERROR
;
656 TRACE("(0x%08x, %ld)\n", has
, fdwReset
);
659 ret
= MMSYSERR_INVALFLAG
;
660 } else if ((was
= ACM_GetStream(has
)) == NULL
) {
661 return MMSYSERR_INVALHANDLE
;
662 } else if (was
->drvInst
.fdwOpen
& ACM_STREAMOPENF_ASYNC
) {
663 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_RESET
, (DWORD
)&was
->drvInst
, 0);
665 TRACE("=> (%d)\n", ret
);
669 /***********************************************************************
670 * acmStreamSize (MSACM32.43)
672 MMRESULT WINAPI
acmStreamSize(HACMSTREAM has
, DWORD cbInput
,
673 LPDWORD pdwOutputBytes
, DWORD fdwSize
)
676 ACMDRVSTREAMSIZE adss
;
679 TRACE("(0x%08x, %ld, %p, %ld)\n", has
, cbInput
, pdwOutputBytes
, fdwSize
);
681 if ((was
= ACM_GetStream(has
)) == NULL
) {
682 return MMSYSERR_INVALHANDLE
;
684 if ((fdwSize
& ~ACM_STREAMSIZEF_QUERYMASK
) != 0) {
685 return MMSYSERR_INVALFLAG
;
688 *pdwOutputBytes
= 0L;
690 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
691 case ACM_STREAMSIZEF_DESTINATION
:
692 adss
.cbDstLength
= cbInput
;
693 adss
.cbSrcLength
= 0;
695 case ACM_STREAMSIZEF_SOURCE
:
696 adss
.cbSrcLength
= cbInput
;
697 adss
.cbDstLength
= 0;
700 return MMSYSERR_INVALFLAG
;
703 adss
.cbStruct
= sizeof(adss
);
704 adss
.fdwSize
= fdwSize
;
705 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_SIZE
,
706 (DWORD
)&was
->drvInst
, (DWORD
)&adss
);
707 if (ret
== MMSYSERR_NOERROR
) {
708 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
709 case ACM_STREAMSIZEF_DESTINATION
:
710 *pdwOutputBytes
= adss
.cbSrcLength
;
712 case ACM_STREAMSIZEF_SOURCE
:
713 *pdwOutputBytes
= adss
.cbDstLength
;
717 TRACE("=> (%d) [%lu]\n", ret
, *pdwOutputBytes
);
721 /***********************************************************************
722 * acmStreamUnprepareHeader (MSACM32.44)
724 MMRESULT WINAPI
acmStreamUnprepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
728 MMRESULT ret
= MMSYSERR_NOERROR
;
729 PACMDRVSTREAMHEADER padsh
;
731 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwUnprepare
);
733 if ((was
= ACM_GetStream(has
)) == NULL
)
734 return MMSYSERR_INVALHANDLE
;
735 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
736 return MMSYSERR_INVALPARAM
;
738 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
739 return ACMERR_UNPREPARED
;
741 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
742 * size. some fields are private to msacm internals, and are exposed
743 * in ACMSTREAMHEADER in the dwReservedDriver array
745 padsh
= (PACMDRVSTREAMHEADER
)pash
;
747 /* check that pointers have not been modified */
748 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
749 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
750 padsh
->pbPreparedDst
!= padsh
->pbDst
||
751 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
752 return MMSYSERR_INVALPARAM
;
755 padsh
->fdwConvert
= fdwUnprepare
;
757 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_UNPREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
758 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
759 ret
= MMSYSERR_NOERROR
;
760 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
|ACMSTREAMHEADER_STATUSF_PREPARED
);
762 TRACE("=> (%d)\n", ret
);