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/
24 ***************************************************************************/
28 #include "wine/winbase.h"
29 #include "wine/windef.h"
30 #include "wine/winuser.h"
32 #include "wine/winestring.h"
33 #include "wine/driver.h"
34 #include "wine/winerror.h"
35 #include "wine/msacm.h"
36 #include "wine/msacmdrv.h"
47 #define OpenDriverA DrvOpen
48 #define CloseDriver DrvClose
50 static inline PWINE_ACMSTREAM
ACM_GetStream(HACMSTREAM has
)
52 return (PWINE_ACMSTREAM
)has
;
55 /***********************************************************************
56 * acmDriverAddA (MSACM32.2)
58 MMRESULT WINAPI
acmDriverAddA(PHACMDRIVERID phadid
, HINSTANCE hinstModule
,
59 LPARAM lParam
, DWORD dwPriority
, DWORD fdwAdd
)
62 return MMSYSERR_INVALPARAM
;
64 /* Check if any unknown flags */
66 ~(ACM_DRIVERADDF_FUNCTION
|ACM_DRIVERADDF_NOTIFYHWND
|
67 ACM_DRIVERADDF_GLOBAL
))
68 return MMSYSERR_INVALFLAG
;
70 /* Check if any incompatible flags */
71 if ((fdwAdd
& ACM_DRIVERADDF_FUNCTION
) &&
72 (fdwAdd
& ACM_DRIVERADDF_NOTIFYHWND
))
73 return MMSYSERR_INVALFLAG
;
75 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
76 * LoadDriver on it, to be sure we can call SendDriverMessage on the
79 *phadid
= (HACMDRIVERID
) MSACM_RegisterDriver(NULL
, 0, hinstModule
);
81 /* FIXME: lParam, dwPriority and fdwAdd ignored */
83 return MMSYSERR_NOERROR
;
86 /***********************************************************************
87 * acmDriverClose (MSACM32.4)
89 MMRESULT WINAPI
acmDriverClose(HACMDRIVER had
, DWORD fdwClose
)
95 return MMSYSERR_INVALFLAG
;
97 p
= MSACM_GetDriver(had
);
99 return MMSYSERR_INVALHANDLE
;
101 for (tp
= &(p
->obj
.pACMDriverID
->pACMDriverList
); *tp
; *tp
= (*tp
)->pNextACMDriver
) {
103 *tp
= (*tp
)->pNextACMDriver
;
108 if (p
->hDrvr
&& !p
->obj
.pACMDriverID
->pACMDriverList
)
109 CloseDriver(p
->hDrvr
);
111 HeapFree(MSACM_hHeap
, 0, p
);
113 return MMSYSERR_NOERROR
;
116 /***********************************************************************
117 * acmDriverEnum (MSACM32.7)
119 MMRESULT WINAPI
acmDriverEnum(ACMDRIVERENUMCB fnCallback
, DWORD dwInstance
, DWORD fdwEnum
)
125 return MMSYSERR_INVALPARAM
;
128 if (fdwEnum
&& ~(ACM_DRIVERENUMF_NOLOCAL
|ACM_DRIVERENUMF_DISABLED
)) {
129 return MMSYSERR_INVALFLAG
;
132 for (p
= MSACM_pFirstACMDriverID
; p
; p
= p
->pNextACMDriverID
) {
133 fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
135 if (fdwEnum
& ACM_DRIVERENUMF_DISABLED
)
136 fdwSupport
|= ACMDRIVERDETAILS_SUPPORTF_DISABLED
;
140 (*fnCallback
)((HACMDRIVERID
) p
, dwInstance
, fdwSupport
);
143 return MMSYSERR_NOERROR
;
146 /***********************************************************************
147 * acmDriverID (MSACM32.8)
149 MMRESULT WINAPI
acmDriverID(HACMOBJ hao
, PHACMDRIVERID phadid
, DWORD fdwDriverID
)
153 pao
= MSACM_GetObj(hao
);
155 return MMSYSERR_INVALHANDLE
;
158 return MMSYSERR_INVALPARAM
;
161 return MMSYSERR_INVALFLAG
;
163 *phadid
= (HACMDRIVERID
) pao
->pACMDriverID
;
165 return MMSYSERR_NOERROR
;
168 /***********************************************************************
169 * acmDriverMessage (MSACM32.9)
173 LRESULT WINAPI
acmDriverMessage(HACMDRIVER had
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
175 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
177 return MMSYSERR_INVALPARAM
;
179 /* FIXME: Check if uMsg legal */
181 if (!SendDriverMessage(pad
->hDrvr
, uMsg
, lParam1
, lParam2
))
182 return MMSYSERR_NOTSUPPORTED
;
184 return MMSYSERR_NOERROR
;
188 /***********************************************************************
189 * acmDriverOpen (MSACM32.10)
191 MMRESULT WINAPI
acmDriverOpen(PHACMDRIVER phad
, HACMDRIVERID hadid
, DWORD fdwOpen
)
193 PWINE_ACMDRIVERID padid
;
199 TRACE("(%p, %x, %08lu)\n", phad
, hadid
, fdwOpen
);
202 return MMSYSERR_INVALPARAM
;
204 padid
= MSACM_GetDriverID(hadid
);
206 return MMSYSERR_INVALHANDLE
;
209 return MMSYSERR_INVALFLAG
;
211 pad
= (PWINE_ACMDRIVER
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVER
));
213 return MMSYSERR_NOMEM
;
215 pad
->obj
.pACMDriverID
= padid
;
216 icopen
.fccType
= mmioFOURCC('a', 'u', 'd', 'c');
217 icopen
.fccHandler
= (long)padid
->pszFileName
;
218 icopen
.dwSize
= sizeof(ICOPEN
);
221 icopen
.pV1Reserved
= padid
->pszFileName
;
222 if (!padid
->hInstModule
)
223 pad
->hDrvr
= OpenDriverA((long)&icopen
);
225 pad
->hDrvr
= padid
->hInstModule
;
228 HeapFree(MSACM_hHeap
, 0, pad
);
229 return MMSYSERR_ERROR
;
232 pad
->pfnDriverProc
= GetProcAddress(pad
->hDrvr
, "DriverProc");
234 /* insert new pad at beg of list */
235 pad
->pNextACMDriver
= padid
->pACMDriverList
;
236 padid
->pACMDriverList
= pad
;
238 /* FIXME: Create a WINE_ACMDRIVER32 */
239 *phad
= (HACMDRIVER
)pad
;
241 return MMSYSERR_NOERROR
;
244 /***********************************************************************
245 * acmDriverRemove (MSACM32.12)
247 MMRESULT WINAPI
acmDriverRemove(HACMDRIVERID hadid
, DWORD fdwRemove
)
249 PWINE_ACMDRIVERID padid
;
251 padid
= MSACM_GetDriverID(hadid
);
253 return MMSYSERR_INVALHANDLE
;
256 return MMSYSERR_INVALFLAG
;
258 MSACM_UnregisterDriver(padid
);
260 return MMSYSERR_NOERROR
;
265 /**********************************************************************/
267 HANDLE MSACM_hHeap
= (HANDLE
) NULL
;
268 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID
= NULL
;
269 PWINE_ACMDRIVERID MSACM_pLastACMDriverID
= NULL
;
271 /***********************************************************************
272 * MSACM_RegisterDriver32()
274 PWINE_ACMDRIVERID
MSACM_RegisterDriver(const char* pszFileName
,
276 HINSTANCE hinstModule
)
278 PWINE_ACMDRIVERID padid
;
280 TRACE("('%s', '%x', 0x%08x)\n", pszFileName
, wFormatTag
, hinstModule
);
283 MSACM_hHeap
= GetProcessHeap();
285 padid
= (PWINE_ACMDRIVERID
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVERID
));
286 padid
->pszFileName
= malloc(strlen(pszFileName
)+1);
287 strcpy(padid
->pszFileName
, pszFileName
);
288 // 1~strdup(pszDriverAlias);
289 padid
->wFormatTag
= wFormatTag
;
290 padid
->hInstModule
= hinstModule
;
291 padid
->bEnabled
= TRUE
;
292 padid
->pACMDriverList
= NULL
;
293 padid
->pNextACMDriverID
= NULL
;
294 padid
->pPrevACMDriverID
= MSACM_pLastACMDriverID
;
295 if (MSACM_pLastACMDriverID
)
296 MSACM_pLastACMDriverID
->pNextACMDriverID
= padid
;
297 MSACM_pLastACMDriverID
= padid
;
298 if (!MSACM_pFirstACMDriverID
)
299 MSACM_pFirstACMDriverID
= padid
;
305 /***********************************************************************
306 * MSACM_UnregisterDriver32()
308 PWINE_ACMDRIVERID
MSACM_UnregisterDriver(PWINE_ACMDRIVERID p
)
310 PWINE_ACMDRIVERID pNextACMDriverID
;
312 while (p
->pACMDriverList
)
313 acmDriverClose((HACMDRIVER
) p
->pACMDriverList
, 0);
316 free(p
->pszFileName
);
318 if (p
== MSACM_pFirstACMDriverID
)
319 MSACM_pFirstACMDriverID
= p
->pNextACMDriverID
;
320 if (p
== MSACM_pLastACMDriverID
)
321 MSACM_pLastACMDriverID
= p
->pPrevACMDriverID
;
323 if (p
->pPrevACMDriverID
)
324 p
->pPrevACMDriverID
->pNextACMDriverID
= p
->pNextACMDriverID
;
325 if (p
->pNextACMDriverID
)
326 p
->pNextACMDriverID
->pPrevACMDriverID
= p
->pPrevACMDriverID
;
328 pNextACMDriverID
= p
->pNextACMDriverID
;
330 HeapFree(MSACM_hHeap
, 0, p
);
332 return pNextACMDriverID
;
335 /***********************************************************************
336 * MSACM_UnregisterAllDrivers32()
338 * Where should this function be called?
340 void MSACM_UnregisterAllDrivers(void)
344 for (p
= MSACM_pFirstACMDriverID
; p
; p
= MSACM_UnregisterDriver(p
));
347 /***********************************************************************
348 * MSACM_GetDriverID32()
350 PWINE_ACMDRIVERID
MSACM_GetDriverID(HACMDRIVERID hDriverID
)
352 return (PWINE_ACMDRIVERID
)hDriverID
;
355 /***********************************************************************
356 * MSACM_GetDriver32()
358 PWINE_ACMDRIVER
MSACM_GetDriver(HACMDRIVER hDriver
)
360 return (PWINE_ACMDRIVER
)hDriver
;
363 /***********************************************************************
366 PWINE_ACMOBJ
MSACM_GetObj(HACMOBJ hObj
)
368 return (PWINE_ACMOBJ
)hObj
;
373 /***********************************************************************
374 * acmStreamOpen (MSACM32.40)
376 MMRESULT WINAPI
acmStreamOpen(PHACMSTREAM phas
, HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
377 PWAVEFORMATEX pwfxDst
, PWAVEFILTER pwfltr
, DWORD dwCallback
,
378 DWORD dwInstance
, DWORD fdwOpen
)
386 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
387 phas
, had
, pwfxSrc
, pwfxDst
, pwfltr
, dwCallback
, dwInstance
, fdwOpen
);
389 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
390 pwfxSrc
->wFormatTag
, pwfxSrc
->nChannels
, pwfxSrc
->nSamplesPerSec
, pwfxSrc
->nAvgBytesPerSec
,
391 pwfxSrc
->nBlockAlign
, pwfxSrc
->wBitsPerSample
, pwfxSrc
->cbSize
);
393 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
394 pwfxDst
->wFormatTag
, pwfxDst
->nChannels
, pwfxDst
->nSamplesPerSec
, pwfxDst
->nAvgBytesPerSec
,
395 pwfxDst
->nBlockAlign
, pwfxDst
->wBitsPerSample
, pwfxDst
->cbSize
);
397 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
398 wfxSrcSize
= SIZEOF_WFX(pwfxSrc
);
399 wfxDstSize
= SIZEOF_WFX(pwfxDst
);
402 was
= (PWINE_ACMSTREAM
) HeapAlloc(MSACM_hHeap
, 0, sizeof(*was
) + wfxSrcSize
+ wfxDstSize
+ ((pwfltr
) ? sizeof(WAVEFILTER
) : 0));
404 return MMSYSERR_NOMEM
;
405 was
->drvInst
.cbStruct
= sizeof(was
->drvInst
);
406 was
->drvInst
.pwfxSrc
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
));
407 memcpy(was
->drvInst
.pwfxSrc
, pwfxSrc
, wfxSrcSize
);
408 // LHACM is checking for 0x1
409 // but if this will not help
410 // was->drvInst.pwfxSrc->wFormatTag = 1;
411 was
->drvInst
.pwfxDst
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
);
412 memcpy(was
->drvInst
.pwfxDst
, pwfxDst
, wfxDstSize
);
414 was
->drvInst
.pwfltr
= (PWAVEFILTER
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
+ wfxDstSize
);
415 memcpy(was
->drvInst
.pwfltr
, pwfltr
, sizeof(WAVEFILTER
));
417 was
->drvInst
.pwfltr
= NULL
;
419 was
->drvInst
.dwCallback
= dwCallback
;
420 was
->drvInst
.dwInstance
= dwInstance
;
421 was
->drvInst
.fdwOpen
= fdwOpen
;
422 was
->drvInst
.fdwDriver
= 0L;
423 was
->drvInst
.dwDriver
= 0L;
424 was
->drvInst
.has
= (HACMSTREAM
)was
;
427 if (!(wad
= MSACM_GetDriver(had
))) {
428 ret
= MMSYSERR_INVALPARAM
;
432 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
434 was
->hAcmDriver
= 0; /* not to close it in acmStreamClose */
436 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
437 if (ret
!= MMSYSERR_NOERROR
)
440 PWINE_ACMDRIVERID wadi
;
442 ret
= ACMERR_NOTPOSSIBLE
;
443 /* if(pwfxSrc->wFormatTag==1)//compression
444 drv_tag=pwfxDst->wFormatTag;
446 if(pwfxDst->wFormatTag==1)//decompression
447 drv_tag=pwfxSrc->wFormatTag;
451 ret=acmDriverOpen2(drv_tag);
452 if (ret == MMSYSERR_NOERROR) {
453 if ((wad = MSACM_GetDriver(had)) != 0) {
454 was->obj.pACMDriverID = wad->obj.pACMDriverID;
456 was->hAcmDriver = had;
458 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
459 if (ret == MMSYSERR_NOERROR) {
460 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
461 acmDriverClose(had, 0L);
466 acmDriverClose(had, 0L);*/
467 //if(MSACM_pFirstACMDriverID==NULL)
468 // MSACM_RegisterAllDrivers();
470 for (wadi
= MSACM_pFirstACMDriverID
; wadi
; wadi
= wadi
->pNextACMDriverID
)
473 if ((int)wadi
->wFormatTag
!= (int)pwfxSrc
->wFormatTag
) continue;
475 ret
= acmDriverOpen(&had
, (HACMDRIVERID
)wadi
, 0L);
476 if (ret
== MMSYSERR_NOERROR
) {
477 if ((wad
= MSACM_GetDriver(had
)) != 0) {
478 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
480 was
->hAcmDriver
= had
;
482 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
483 //lhacm - crash printf("RETOPEN %d\n", ret);
485 if (ret
== MMSYSERR_NOERROR
) {
486 if (fdwOpen
& ACM_STREAMOPENF_QUERY
) {
487 acmDriverClose(had
, 0L);
492 // no match, close this acm driver and try next one
493 acmDriverClose(had
, 0L);
496 if (ret
!= MMSYSERR_NOERROR
) {
497 ret
= ACMERR_NOTPOSSIBLE
;
501 ret
= MMSYSERR_NOERROR
;
502 if (!(fdwOpen
& ACM_STREAMOPENF_QUERY
)) {
504 *phas
= (HACMSTREAM
)was
;
505 TRACE("=> (%d)\n", ret
);
513 *phas
= (HACMSTREAM
)0;
514 HeapFree(MSACM_hHeap
, 0, was
);
515 TRACE("=> (%d)\n", ret
);
520 MMRESULT WINAPI
acmStreamClose(HACMSTREAM has
, DWORD fdwClose
)
525 TRACE("(0x%08x, %ld)\n", has
, fdwClose
);
527 if ((was
= ACM_GetStream(has
)) == NULL
) {
528 return MMSYSERR_INVALHANDLE
;
530 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CLOSE
, (DWORD
)&was
->drvInst
, 0);
531 if (ret
== MMSYSERR_NOERROR
) {
533 acmDriverClose(was
->hAcmDriver
, 0L);
534 HeapFree(MSACM_hHeap
, 0, was
);
539 TRACE("=> (%d)\n", ret
);
543 /***********************************************************************
544 * acmStreamConvert (MSACM32.38)
546 MMRESULT WINAPI
acmStreamConvert(HACMSTREAM has
, PACMSTREAMHEADER pash
,
550 MMRESULT ret
= MMSYSERR_NOERROR
;
551 PACMDRVSTREAMHEADER padsh
;
553 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwConvert
);
555 if ((was
= ACM_GetStream(has
)) == NULL
)
556 return MMSYSERR_INVALHANDLE
;
557 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
558 return MMSYSERR_INVALPARAM
;
560 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
561 return ACMERR_UNPREPARED
;
563 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
564 * size. some fields are private to msacm internals, and are exposed
565 * in ACMSTREAMHEADER in the dwReservedDriver array
567 padsh
= (PACMDRVSTREAMHEADER
)pash
;
569 /* check that pointers have not been modified */
570 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
571 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
572 padsh
->pbPreparedDst
!= padsh
->pbDst
||
573 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
574 return MMSYSERR_INVALPARAM
;
577 padsh
->fdwConvert
= fdwConvert
;
579 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CONVERT
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
580 if (ret
== MMSYSERR_NOERROR
) {
581 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_DONE
;
583 TRACE("=> (%d)\n", ret
);
588 /***********************************************************************
589 * acmStreamPrepareHeader (MSACM32.41)
591 MMRESULT WINAPI
acmStreamPrepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
595 MMRESULT ret
= MMSYSERR_NOERROR
;
596 PACMDRVSTREAMHEADER padsh
;
598 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwPrepare
);
600 if ((was
= ACM_GetStream(has
)) == NULL
)
601 return MMSYSERR_INVALHANDLE
;
602 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
603 return MMSYSERR_INVALPARAM
;
605 ret
= MMSYSERR_INVALFLAG
;
607 if (pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_DONE
)
608 return MMSYSERR_NOERROR
;
610 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
611 * size. some fields are private to msacm internals, and are exposed
612 * in ACMSTREAMHEADER in the dwReservedDriver array
614 padsh
= (PACMDRVSTREAMHEADER
)pash
;
616 padsh
->fdwConvert
= fdwPrepare
;
617 padsh
->padshNext
= NULL
;
618 padsh
->fdwDriver
= padsh
->dwDriver
= 0L;
620 padsh
->fdwPrepared
= 0;
621 padsh
->dwPrepared
= 0;
622 padsh
->pbPreparedSrc
= 0;
623 padsh
->cbPreparedSrcLength
= 0;
624 padsh
->pbPreparedDst
= 0;
625 padsh
->cbPreparedDstLength
= 0;
627 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_PREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
628 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
629 ret
= MMSYSERR_NOERROR
;
630 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
);
631 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_PREPARED
;
632 padsh
->fdwPrepared
= padsh
->fdwStatus
;
633 padsh
->dwPrepared
= 0;
634 padsh
->pbPreparedSrc
= padsh
->pbSrc
;
635 padsh
->cbPreparedSrcLength
= padsh
->cbSrcLength
;
636 padsh
->pbPreparedDst
= padsh
->pbDst
;
637 padsh
->cbPreparedDstLength
= padsh
->cbDstLength
;
639 padsh
->fdwPrepared
= 0;
640 padsh
->dwPrepared
= 0;
641 padsh
->pbPreparedSrc
= 0;
642 padsh
->cbPreparedSrcLength
= 0;
643 padsh
->pbPreparedDst
= 0;
644 padsh
->cbPreparedDstLength
= 0;
646 TRACE("=> (%d)\n", ret
);
650 /***********************************************************************
651 * acmStreamReset (MSACM32.42)
653 MMRESULT WINAPI
acmStreamReset(HACMSTREAM has
, DWORD fdwReset
)
656 MMRESULT ret
= MMSYSERR_NOERROR
;
658 TRACE("(0x%08x, %ld)\n", has
, fdwReset
);
661 ret
= MMSYSERR_INVALFLAG
;
662 } else if ((was
= ACM_GetStream(has
)) == NULL
) {
663 return MMSYSERR_INVALHANDLE
;
664 } else if (was
->drvInst
.fdwOpen
& ACM_STREAMOPENF_ASYNC
) {
665 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_RESET
, (DWORD
)&was
->drvInst
, 0);
667 TRACE("=> (%d)\n", ret
);
671 /***********************************************************************
672 * acmStreamSize (MSACM32.43)
674 MMRESULT WINAPI
acmStreamSize(HACMSTREAM has
, DWORD cbInput
,
675 LPDWORD pdwOutputBytes
, DWORD fdwSize
)
678 ACMDRVSTREAMSIZE adss
;
681 TRACE("(0x%08x, %ld, %p, %ld)\n", has
, cbInput
, pdwOutputBytes
, fdwSize
);
683 if ((was
= ACM_GetStream(has
)) == NULL
) {
684 return MMSYSERR_INVALHANDLE
;
686 if ((fdwSize
& ~ACM_STREAMSIZEF_QUERYMASK
) != 0) {
687 return MMSYSERR_INVALFLAG
;
690 *pdwOutputBytes
= 0L;
692 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
693 case ACM_STREAMSIZEF_DESTINATION
:
694 adss
.cbDstLength
= cbInput
;
695 adss
.cbSrcLength
= 0;
697 case ACM_STREAMSIZEF_SOURCE
:
698 adss
.cbSrcLength
= cbInput
;
699 adss
.cbDstLength
= 0;
702 return MMSYSERR_INVALFLAG
;
705 adss
.cbStruct
= sizeof(adss
);
706 adss
.fdwSize
= fdwSize
;
707 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_SIZE
,
708 (DWORD
)&was
->drvInst
, (DWORD
)&adss
);
709 if (ret
== MMSYSERR_NOERROR
) {
710 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
711 case ACM_STREAMSIZEF_DESTINATION
:
712 *pdwOutputBytes
= adss
.cbSrcLength
;
714 case ACM_STREAMSIZEF_SOURCE
:
715 *pdwOutputBytes
= adss
.cbDstLength
;
719 TRACE("=> (%d) [%lu]\n", ret
, *pdwOutputBytes
);
723 /***********************************************************************
724 * acmStreamUnprepareHeader (MSACM32.44)
726 MMRESULT WINAPI
acmStreamUnprepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
730 MMRESULT ret
= MMSYSERR_NOERROR
;
731 PACMDRVSTREAMHEADER padsh
;
733 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwUnprepare
);
735 if ((was
= ACM_GetStream(has
)) == NULL
)
736 return MMSYSERR_INVALHANDLE
;
737 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
738 return MMSYSERR_INVALPARAM
;
740 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
741 return ACMERR_UNPREPARED
;
743 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
744 * size. some fields are private to msacm internals, and are exposed
745 * in ACMSTREAMHEADER in the dwReservedDriver array
747 padsh
= (PACMDRVSTREAMHEADER
)pash
;
749 /* check that pointers have not been modified */
750 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
751 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
752 padsh
->pbPreparedDst
!= padsh
->pbDst
||
753 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
754 return MMSYSERR_INVALPARAM
;
757 padsh
->fdwConvert
= fdwUnprepare
;
759 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_UNPREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
760 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
761 ret
= MMSYSERR_NOERROR
;
762 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
|ACMSTREAMHEADER_STATUSF_PREPARED
);
764 TRACE("=> (%d)\n", ret
);