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);
313 free(p
->pszFileName
);
315 if (p
== MSACM_pFirstACMDriverID
)
316 MSACM_pFirstACMDriverID
= p
->pNextACMDriverID
;
317 if (p
== MSACM_pLastACMDriverID
)
318 MSACM_pLastACMDriverID
= p
->pPrevACMDriverID
;
320 if (p
->pPrevACMDriverID
)
321 p
->pPrevACMDriverID
->pNextACMDriverID
= p
->pNextACMDriverID
;
322 if (p
->pNextACMDriverID
)
323 p
->pNextACMDriverID
->pPrevACMDriverID
= p
->pPrevACMDriverID
;
325 pNextACMDriverID
= p
->pNextACMDriverID
;
327 HeapFree(MSACM_hHeap
, 0, p
);
329 return pNextACMDriverID
;
332 /***********************************************************************
333 * MSACM_UnregisterAllDrivers32()
335 * Where should this function be called?
337 void MSACM_UnregisterAllDrivers(void)
341 for (p
= MSACM_pFirstACMDriverID
; p
; p
= MSACM_UnregisterDriver(p
));
344 /***********************************************************************
345 * MSACM_GetDriverID32()
347 PWINE_ACMDRIVERID
MSACM_GetDriverID(HACMDRIVERID hDriverID
)
349 return (PWINE_ACMDRIVERID
)hDriverID
;
352 /***********************************************************************
353 * MSACM_GetDriver32()
355 PWINE_ACMDRIVER
MSACM_GetDriver(HACMDRIVER hDriver
)
357 return (PWINE_ACMDRIVER
)hDriver
;
360 /***********************************************************************
363 PWINE_ACMOBJ
MSACM_GetObj(HACMOBJ hObj
)
365 return (PWINE_ACMOBJ
)hObj
;
370 /***********************************************************************
371 * acmStreamOpen (MSACM32.40)
373 MMRESULT WINAPI
acmStreamOpen(PHACMSTREAM phas
, HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
374 PWAVEFORMATEX pwfxDst
, PWAVEFILTER pwfltr
, DWORD dwCallback
,
375 DWORD dwInstance
, DWORD fdwOpen
)
383 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
384 phas
, had
, pwfxSrc
, pwfxDst
, pwfltr
, dwCallback
, dwInstance
, fdwOpen
);
386 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
387 pwfxSrc
->wFormatTag
, pwfxSrc
->nChannels
, pwfxSrc
->nSamplesPerSec
, pwfxSrc
->nAvgBytesPerSec
,
388 pwfxSrc
->nBlockAlign
, pwfxSrc
->wBitsPerSample
, pwfxSrc
->cbSize
);
390 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
391 pwfxDst
->wFormatTag
, pwfxDst
->nChannels
, pwfxDst
->nSamplesPerSec
, pwfxDst
->nAvgBytesPerSec
,
392 pwfxDst
->nBlockAlign
, pwfxDst
->wBitsPerSample
, pwfxDst
->cbSize
);
394 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
395 wfxSrcSize
= SIZEOF_WFX(pwfxSrc
);
396 wfxDstSize
= SIZEOF_WFX(pwfxDst
);
399 was
= (PWINE_ACMSTREAM
) HeapAlloc(MSACM_hHeap
, 0, sizeof(*was
) + wfxSrcSize
+ wfxDstSize
+ ((pwfltr
) ? sizeof(WAVEFILTER
) : 0));
401 return MMSYSERR_NOMEM
;
402 was
->drvInst
.cbStruct
= sizeof(was
->drvInst
);
403 was
->drvInst
.pwfxSrc
= (PWAVEFORMATEX
)(was
+ 1);
404 memcpy(was
->drvInst
.pwfxSrc
, pwfxSrc
, wfxSrcSize
);
405 // LHACM is checking for 0x1
406 // but if this will not help
407 // was->drvInst.pwfxSrc->wFormatTag = 1;
408 was
->drvInst
.pwfxDst
= (PWAVEFORMATEX
)((LPSTR
)(was
+ 1) + wfxSrcSize
);
409 memcpy(was
->drvInst
.pwfxDst
, pwfxDst
, wfxDstSize
);
411 was
->drvInst
.pwfltr
= (PWAVEFILTER
)((LPSTR
)(was
+ 1) + wfxSrcSize
+ wfxDstSize
);
412 memcpy(was
->drvInst
.pwfltr
, pwfltr
, sizeof(WAVEFILTER
));
414 was
->drvInst
.pwfltr
= NULL
;
416 was
->drvInst
.dwCallback
= dwCallback
;
417 was
->drvInst
.dwInstance
= dwInstance
;
418 was
->drvInst
.fdwOpen
= fdwOpen
;
419 was
->drvInst
.fdwDriver
= 0L;
420 was
->drvInst
.dwDriver
= 0L;
421 was
->drvInst
.has
= (HACMSTREAM
)was
;
424 if (!(wad
= MSACM_GetDriver(had
))) {
425 ret
= MMSYSERR_INVALPARAM
;
429 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
431 was
->hAcmDriver
= 0; /* not to close it in acmStreamClose */
433 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
434 if (ret
!= MMSYSERR_NOERROR
)
437 PWINE_ACMDRIVERID wadi
;
439 ret
= ACMERR_NOTPOSSIBLE
;
440 /* if(pwfxSrc->wFormatTag==1)//compression
441 drv_tag=pwfxDst->wFormatTag;
443 if(pwfxDst->wFormatTag==1)//decompression
444 drv_tag=pwfxSrc->wFormatTag;
448 ret=acmDriverOpen2(drv_tag);
449 if (ret == MMSYSERR_NOERROR) {
450 if ((wad = MSACM_GetDriver(had)) != 0) {
451 was->obj.pACMDriverID = wad->obj.pACMDriverID;
453 was->hAcmDriver = had;
455 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
456 if (ret == MMSYSERR_NOERROR) {
457 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
458 acmDriverClose(had, 0L);
463 acmDriverClose(had, 0L);*/
464 //if(MSACM_pFirstACMDriverID==NULL)
465 // MSACM_RegisterAllDrivers();
467 for (wadi
= MSACM_pFirstACMDriverID
; wadi
; wadi
= wadi
->pNextACMDriverID
)
470 if ((int)wadi
->wFormatTag
!= (int)pwfxSrc
->wFormatTag
) continue;
472 ret
= acmDriverOpen(&had
, (HACMDRIVERID
)wadi
, 0L);
473 if (ret
== MMSYSERR_NOERROR
) {
474 if ((wad
= MSACM_GetDriver(had
)) != 0) {
475 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
477 was
->hAcmDriver
= had
;
479 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
480 //lhacm - crash printf("RETOPEN %d\n", ret);
482 if (ret
== MMSYSERR_NOERROR
) {
483 if (fdwOpen
& ACM_STREAMOPENF_QUERY
) {
484 acmDriverClose(had
, 0L);
489 // no match, close this acm driver and try next one
490 acmDriverClose(had
, 0L);
493 if (ret
!= MMSYSERR_NOERROR
) {
494 ret
= ACMERR_NOTPOSSIBLE
;
498 ret
= MMSYSERR_NOERROR
;
499 if (!(fdwOpen
& ACM_STREAMOPENF_QUERY
)) {
501 *phas
= (HACMSTREAM
)was
;
502 TRACE("=> (%d)\n", ret
);
510 *phas
= (HACMSTREAM
)0;
511 HeapFree(MSACM_hHeap
, 0, was
);
512 TRACE("=> (%d)\n", ret
);
517 MMRESULT WINAPI
acmStreamClose(HACMSTREAM has
, DWORD fdwClose
)
522 TRACE("(0x%08x, %ld)\n", has
, fdwClose
);
524 if ((was
= ACM_GetStream(has
)) == NULL
) {
525 return MMSYSERR_INVALHANDLE
;
527 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CLOSE
, (DWORD
)&was
->drvInst
, 0);
528 if (ret
== MMSYSERR_NOERROR
) {
530 acmDriverClose(was
->hAcmDriver
, 0L);
531 HeapFree(MSACM_hHeap
, 0, was
);
536 TRACE("=> (%d)\n", ret
);
540 /***********************************************************************
541 * acmStreamConvert (MSACM32.38)
543 MMRESULT WINAPI
acmStreamConvert(HACMSTREAM has
, PACMSTREAMHEADER pash
,
547 MMRESULT ret
= MMSYSERR_NOERROR
;
548 PACMDRVSTREAMHEADER padsh
;
550 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwConvert
);
552 if ((was
= ACM_GetStream(has
)) == NULL
)
553 return MMSYSERR_INVALHANDLE
;
554 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
555 return MMSYSERR_INVALPARAM
;
557 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
558 return ACMERR_UNPREPARED
;
560 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
561 * size. some fields are private to msacm internals, and are exposed
562 * in ACMSTREAMHEADER in the dwReservedDriver array
564 padsh
= (PACMDRVSTREAMHEADER
)pash
;
566 /* check that pointers have not been modified */
567 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
568 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
569 padsh
->pbPreparedDst
!= padsh
->pbDst
||
570 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
571 return MMSYSERR_INVALPARAM
;
574 padsh
->fdwConvert
= fdwConvert
;
576 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CONVERT
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
577 if (ret
== MMSYSERR_NOERROR
) {
578 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_DONE
;
580 TRACE("=> (%d)\n", ret
);
585 /***********************************************************************
586 * acmStreamPrepareHeader (MSACM32.41)
588 MMRESULT WINAPI
acmStreamPrepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
592 MMRESULT ret
= MMSYSERR_NOERROR
;
593 PACMDRVSTREAMHEADER padsh
;
595 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwPrepare
);
597 if ((was
= ACM_GetStream(has
)) == NULL
)
598 return MMSYSERR_INVALHANDLE
;
599 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
600 return MMSYSERR_INVALPARAM
;
602 ret
= MMSYSERR_INVALFLAG
;
604 if (pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_DONE
)
605 return MMSYSERR_NOERROR
;
607 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
608 * size. some fields are private to msacm internals, and are exposed
609 * in ACMSTREAMHEADER in the dwReservedDriver array
611 padsh
= (PACMDRVSTREAMHEADER
)pash
;
613 padsh
->fdwConvert
= fdwPrepare
;
614 padsh
->padshNext
= NULL
;
615 padsh
->fdwDriver
= padsh
->dwDriver
= 0L;
617 padsh
->fdwPrepared
= 0;
618 padsh
->dwPrepared
= 0;
619 padsh
->pbPreparedSrc
= 0;
620 padsh
->cbPreparedSrcLength
= 0;
621 padsh
->pbPreparedDst
= 0;
622 padsh
->cbPreparedDstLength
= 0;
624 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_PREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
625 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
626 ret
= MMSYSERR_NOERROR
;
627 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
);
628 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_PREPARED
;
629 padsh
->fdwPrepared
= padsh
->fdwStatus
;
630 padsh
->dwPrepared
= 0;
631 padsh
->pbPreparedSrc
= padsh
->pbSrc
;
632 padsh
->cbPreparedSrcLength
= padsh
->cbSrcLength
;
633 padsh
->pbPreparedDst
= padsh
->pbDst
;
634 padsh
->cbPreparedDstLength
= padsh
->cbDstLength
;
636 padsh
->fdwPrepared
= 0;
637 padsh
->dwPrepared
= 0;
638 padsh
->pbPreparedSrc
= 0;
639 padsh
->cbPreparedSrcLength
= 0;
640 padsh
->pbPreparedDst
= 0;
641 padsh
->cbPreparedDstLength
= 0;
643 TRACE("=> (%d)\n", ret
);
647 /***********************************************************************
648 * acmStreamReset (MSACM32.42)
650 MMRESULT WINAPI
acmStreamReset(HACMSTREAM has
, DWORD fdwReset
)
653 MMRESULT ret
= MMSYSERR_NOERROR
;
655 TRACE("(0x%08x, %ld)\n", has
, fdwReset
);
658 ret
= MMSYSERR_INVALFLAG
;
659 } else if ((was
= ACM_GetStream(has
)) == NULL
) {
660 return MMSYSERR_INVALHANDLE
;
661 } else if (was
->drvInst
.fdwOpen
& ACM_STREAMOPENF_ASYNC
) {
662 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_RESET
, (DWORD
)&was
->drvInst
, 0);
664 TRACE("=> (%d)\n", ret
);
668 /***********************************************************************
669 * acmStreamSize (MSACM32.43)
671 MMRESULT WINAPI
acmStreamSize(HACMSTREAM has
, DWORD cbInput
,
672 LPDWORD pdwOutputBytes
, DWORD fdwSize
)
675 ACMDRVSTREAMSIZE adss
;
678 TRACE("(0x%08x, %ld, %p, %ld)\n", has
, cbInput
, pdwOutputBytes
, fdwSize
);
680 if ((was
= ACM_GetStream(has
)) == NULL
) {
681 return MMSYSERR_INVALHANDLE
;
683 if ((fdwSize
& ~ACM_STREAMSIZEF_QUERYMASK
) != 0) {
684 return MMSYSERR_INVALFLAG
;
687 *pdwOutputBytes
= 0L;
689 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
690 case ACM_STREAMSIZEF_DESTINATION
:
691 adss
.cbDstLength
= cbInput
;
692 adss
.cbSrcLength
= 0;
694 case ACM_STREAMSIZEF_SOURCE
:
695 adss
.cbSrcLength
= cbInput
;
696 adss
.cbDstLength
= 0;
699 return MMSYSERR_INVALFLAG
;
702 adss
.cbStruct
= sizeof(adss
);
703 adss
.fdwSize
= fdwSize
;
704 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_SIZE
,
705 (DWORD
)&was
->drvInst
, (DWORD
)&adss
);
706 if (ret
== MMSYSERR_NOERROR
) {
707 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
708 case ACM_STREAMSIZEF_DESTINATION
:
709 *pdwOutputBytes
= adss
.cbSrcLength
;
711 case ACM_STREAMSIZEF_SOURCE
:
712 *pdwOutputBytes
= adss
.cbDstLength
;
716 TRACE("=> (%d) [%lu]\n", ret
, *pdwOutputBytes
);
720 /***********************************************************************
721 * acmStreamUnprepareHeader (MSACM32.44)
723 MMRESULT WINAPI
acmStreamUnprepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
727 MMRESULT ret
= MMSYSERR_NOERROR
;
728 PACMDRVSTREAMHEADER padsh
;
730 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwUnprepare
);
732 if ((was
= ACM_GetStream(has
)) == NULL
)
733 return MMSYSERR_INVALHANDLE
;
734 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
735 return MMSYSERR_INVALPARAM
;
737 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
738 return ACMERR_UNPREPARED
;
740 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
741 * size. some fields are private to msacm internals, and are exposed
742 * in ACMSTREAMHEADER in the dwReservedDriver array
744 padsh
= (PACMDRVSTREAMHEADER
)pash
;
746 /* check that pointers have not been modified */
747 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
748 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
749 padsh
->pbPreparedDst
!= padsh
->pbDst
||
750 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
751 return MMSYSERR_INVALPARAM
;
754 padsh
->fdwConvert
= fdwUnprepare
;
756 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_UNPREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
757 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
758 ret
= MMSYSERR_NOERROR
;
759 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
|ACMSTREAMHEADER_STATUSF_PREPARED
);
761 TRACE("=> (%d)\n", ret
);