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 ***************************************************************************/
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
;
198 TRACE("(%p, %x, %08lu)\n", phad
, hadid
, fdwOpen
);
201 return MMSYSERR_INVALPARAM
;
203 padid
= MSACM_GetDriverID(hadid
);
205 return MMSYSERR_INVALHANDLE
;
208 return MMSYSERR_INVALFLAG
;
210 pad
= (PWINE_ACMDRIVER
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVER
));
212 return MMSYSERR_NOMEM
;
214 pad
->obj
.pACMDriverID
= padid
;
215 icopen
.fccType
= mmioFOURCC('a', 'u', 'd', 'c');
216 icopen
.fccHandler
= (long)padid
->pszFileName
;
217 icopen
.dwSize
= sizeof(ICOPEN
);
220 icopen
.pV1Reserved
= padid
->pszFileName
;
221 if (!padid
->hInstModule
)
222 pad
->hDrvr
= OpenDriverA((long)&icopen
);
224 pad
->hDrvr
= padid
->hInstModule
;
227 HeapFree(MSACM_hHeap
, 0, pad
);
228 return MMSYSERR_ERROR
;
231 pad
->pfnDriverProc
= GetProcAddress(pad
->hDrvr
, "DriverProc");
233 /* insert new pad at beg of list */
234 pad
->pNextACMDriver
= padid
->pACMDriverList
;
235 padid
->pACMDriverList
= pad
;
237 /* FIXME: Create a WINE_ACMDRIVER32 */
238 *phad
= (HACMDRIVER
)pad
;
240 return MMSYSERR_NOERROR
;
243 /***********************************************************************
244 * acmDriverRemove (MSACM32.12)
246 MMRESULT WINAPI
acmDriverRemove(HACMDRIVERID hadid
, DWORD fdwRemove
)
248 PWINE_ACMDRIVERID padid
;
250 padid
= MSACM_GetDriverID(hadid
);
252 return MMSYSERR_INVALHANDLE
;
255 return MMSYSERR_INVALFLAG
;
257 MSACM_UnregisterDriver(padid
);
259 return MMSYSERR_NOERROR
;
264 /**********************************************************************/
266 HANDLE MSACM_hHeap
= (HANDLE
) NULL
;
267 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID
= NULL
;
268 PWINE_ACMDRIVERID MSACM_pLastACMDriverID
= NULL
;
270 /***********************************************************************
271 * MSACM_RegisterDriver32()
273 PWINE_ACMDRIVERID
MSACM_RegisterDriver(const char* pszFileName
,
275 HINSTANCE hinstModule
)
277 PWINE_ACMDRIVERID padid
;
279 TRACE("('%s', '%x', 0x%08x)\n", pszFileName
, wFormatTag
, hinstModule
);
282 MSACM_hHeap
= GetProcessHeap();
284 padid
= (PWINE_ACMDRIVERID
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVERID
));
285 padid
->pszFileName
= malloc(strlen(pszFileName
)+1);
286 strcpy(padid
->pszFileName
, pszFileName
);
287 // 1~strdup(pszDriverAlias);
288 padid
->wFormatTag
= wFormatTag
;
289 padid
->hInstModule
= hinstModule
;
290 padid
->bEnabled
= TRUE
;
291 padid
->pACMDriverList
= NULL
;
292 padid
->pNextACMDriverID
= NULL
;
293 padid
->pPrevACMDriverID
= MSACM_pLastACMDriverID
;
294 if (MSACM_pLastACMDriverID
)
295 MSACM_pLastACMDriverID
->pNextACMDriverID
= padid
;
296 MSACM_pLastACMDriverID
= padid
;
297 if (!MSACM_pFirstACMDriverID
)
298 MSACM_pFirstACMDriverID
= padid
;
304 /***********************************************************************
305 * MSACM_UnregisterDriver32()
307 PWINE_ACMDRIVERID
MSACM_UnregisterDriver(PWINE_ACMDRIVERID p
)
309 PWINE_ACMDRIVERID pNextACMDriverID
;
311 while (p
->pACMDriverList
)
312 acmDriverClose((HACMDRIVER
) p
->pACMDriverList
, 0);
315 free(p
->pszFileName
);
317 if (p
== MSACM_pFirstACMDriverID
)
318 MSACM_pFirstACMDriverID
= p
->pNextACMDriverID
;
319 if (p
== MSACM_pLastACMDriverID
)
320 MSACM_pLastACMDriverID
= p
->pPrevACMDriverID
;
322 if (p
->pPrevACMDriverID
)
323 p
->pPrevACMDriverID
->pNextACMDriverID
= p
->pNextACMDriverID
;
324 if (p
->pNextACMDriverID
)
325 p
->pNextACMDriverID
->pPrevACMDriverID
= p
->pPrevACMDriverID
;
327 pNextACMDriverID
= p
->pNextACMDriverID
;
329 HeapFree(MSACM_hHeap
, 0, p
);
331 return pNextACMDriverID
;
334 /***********************************************************************
335 * MSACM_UnregisterAllDrivers32()
337 * Where should this function be called?
339 void MSACM_UnregisterAllDrivers(void)
343 for (p
= MSACM_pFirstACMDriverID
; p
; p
= MSACM_UnregisterDriver(p
));
346 /***********************************************************************
347 * MSACM_GetDriverID32()
349 PWINE_ACMDRIVERID
MSACM_GetDriverID(HACMDRIVERID hDriverID
)
351 return (PWINE_ACMDRIVERID
)hDriverID
;
354 /***********************************************************************
355 * MSACM_GetDriver32()
357 PWINE_ACMDRIVER
MSACM_GetDriver(HACMDRIVER hDriver
)
359 return (PWINE_ACMDRIVER
)hDriver
;
362 /***********************************************************************
365 PWINE_ACMOBJ
MSACM_GetObj(HACMOBJ hObj
)
367 return (PWINE_ACMOBJ
)hObj
;
372 /***********************************************************************
373 * acmStreamOpen (MSACM32.40)
375 MMRESULT WINAPI
acmStreamOpen(PHACMSTREAM phas
, HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
376 PWAVEFORMATEX pwfxDst
, PWAVEFILTER pwfltr
, DWORD dwCallback
,
377 DWORD dwInstance
, DWORD fdwOpen
)
385 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
386 phas
, had
, pwfxSrc
, pwfxDst
, pwfltr
, dwCallback
, dwInstance
, fdwOpen
);
388 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
389 pwfxSrc
->wFormatTag
, pwfxSrc
->nChannels
, pwfxSrc
->nSamplesPerSec
, pwfxSrc
->nAvgBytesPerSec
,
390 pwfxSrc
->nBlockAlign
, pwfxSrc
->wBitsPerSample
, pwfxSrc
->cbSize
);
392 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
393 pwfxDst
->wFormatTag
, pwfxDst
->nChannels
, pwfxDst
->nSamplesPerSec
, pwfxDst
->nAvgBytesPerSec
,
394 pwfxDst
->nBlockAlign
, pwfxDst
->wBitsPerSample
, pwfxDst
->cbSize
);
396 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
397 wfxSrcSize
= SIZEOF_WFX(pwfxSrc
);
398 wfxDstSize
= SIZEOF_WFX(pwfxDst
);
401 was
= (PWINE_ACMSTREAM
) HeapAlloc(MSACM_hHeap
, 0, sizeof(*was
) + wfxSrcSize
+ wfxDstSize
+ ((pwfltr
) ? sizeof(WAVEFILTER
) : 0));
403 return MMSYSERR_NOMEM
;
404 was
->drvInst
.cbStruct
= sizeof(was
->drvInst
);
405 was
->drvInst
.pwfxSrc
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
));
406 memcpy(was
->drvInst
.pwfxSrc
, pwfxSrc
, wfxSrcSize
);
407 // LHACM is checking for 0x1
408 // but if this will not help
409 // was->drvInst.pwfxSrc->wFormatTag = 1;
410 was
->drvInst
.pwfxDst
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
);
411 memcpy(was
->drvInst
.pwfxDst
, pwfxDst
, wfxDstSize
);
413 was
->drvInst
.pwfltr
= (PWAVEFILTER
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
+ wfxDstSize
);
414 memcpy(was
->drvInst
.pwfltr
, pwfltr
, sizeof(WAVEFILTER
));
416 was
->drvInst
.pwfltr
= NULL
;
418 was
->drvInst
.dwCallback
= dwCallback
;
419 was
->drvInst
.dwInstance
= dwInstance
;
420 was
->drvInst
.fdwOpen
= fdwOpen
;
421 was
->drvInst
.fdwDriver
= 0L;
422 was
->drvInst
.dwDriver
= 0L;
423 was
->drvInst
.has
= (HACMSTREAM
)was
;
426 if (!(wad
= MSACM_GetDriver(had
))) {
427 ret
= MMSYSERR_INVALPARAM
;
431 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
433 was
->hAcmDriver
= 0; /* not to close it in acmStreamClose */
435 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
436 if (ret
!= MMSYSERR_NOERROR
)
439 PWINE_ACMDRIVERID wadi
;
441 ret
= ACMERR_NOTPOSSIBLE
;
442 /* if(pwfxSrc->wFormatTag==1)//compression
443 drv_tag=pwfxDst->wFormatTag;
445 if(pwfxDst->wFormatTag==1)//decompression
446 drv_tag=pwfxSrc->wFormatTag;
450 ret=acmDriverOpen2(drv_tag);
451 if (ret == MMSYSERR_NOERROR) {
452 if ((wad = MSACM_GetDriver(had)) != 0) {
453 was->obj.pACMDriverID = wad->obj.pACMDriverID;
455 was->hAcmDriver = had;
457 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
458 if (ret == MMSYSERR_NOERROR) {
459 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
460 acmDriverClose(had, 0L);
465 acmDriverClose(had, 0L);*/
466 //if(MSACM_pFirstACMDriverID==NULL)
467 // MSACM_RegisterAllDrivers();
469 for (wadi
= MSACM_pFirstACMDriverID
; wadi
; wadi
= wadi
->pNextACMDriverID
)
472 if ((int)wadi
->wFormatTag
!= (int)pwfxSrc
->wFormatTag
) continue;
474 ret
= acmDriverOpen(&had
, (HACMDRIVERID
)wadi
, 0L);
475 if (ret
== MMSYSERR_NOERROR
) {
476 if ((wad
= MSACM_GetDriver(had
)) != 0) {
477 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
479 was
->hAcmDriver
= had
;
481 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
482 //lhacm - crash printf("RETOPEN %d\n", ret);
484 if (ret
== MMSYSERR_NOERROR
) {
485 if (fdwOpen
& ACM_STREAMOPENF_QUERY
) {
486 acmDriverClose(had
, 0L);
491 // no match, close this acm driver and try next one
492 acmDriverClose(had
, 0L);
495 if (ret
!= MMSYSERR_NOERROR
) {
496 ret
= ACMERR_NOTPOSSIBLE
;
500 ret
= MMSYSERR_NOERROR
;
501 if (!(fdwOpen
& ACM_STREAMOPENF_QUERY
)) {
503 *phas
= (HACMSTREAM
)was
;
504 TRACE("=> (%d)\n", ret
);
512 *phas
= (HACMSTREAM
)0;
513 HeapFree(MSACM_hHeap
, 0, was
);
514 TRACE("=> (%d)\n", ret
);
519 MMRESULT WINAPI
acmStreamClose(HACMSTREAM has
, DWORD fdwClose
)
524 TRACE("(0x%08x, %ld)\n", has
, fdwClose
);
526 if ((was
= ACM_GetStream(has
)) == NULL
) {
527 return MMSYSERR_INVALHANDLE
;
529 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CLOSE
, (DWORD
)&was
->drvInst
, 0);
530 if (ret
== MMSYSERR_NOERROR
) {
532 acmDriverClose(was
->hAcmDriver
, 0L);
533 HeapFree(MSACM_hHeap
, 0, was
);
538 TRACE("=> (%d)\n", ret
);
542 /***********************************************************************
543 * acmStreamConvert (MSACM32.38)
545 MMRESULT WINAPI
acmStreamConvert(HACMSTREAM has
, PACMSTREAMHEADER pash
,
549 MMRESULT ret
= MMSYSERR_NOERROR
;
550 PACMDRVSTREAMHEADER padsh
;
552 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwConvert
);
554 if ((was
= ACM_GetStream(has
)) == NULL
)
555 return MMSYSERR_INVALHANDLE
;
556 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
557 return MMSYSERR_INVALPARAM
;
559 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
560 return ACMERR_UNPREPARED
;
562 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
563 * size. some fields are private to msacm internals, and are exposed
564 * in ACMSTREAMHEADER in the dwReservedDriver array
566 padsh
= (PACMDRVSTREAMHEADER
)pash
;
568 /* check that pointers have not been modified */
569 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
570 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
571 padsh
->pbPreparedDst
!= padsh
->pbDst
||
572 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
573 return MMSYSERR_INVALPARAM
;
576 padsh
->fdwConvert
= fdwConvert
;
578 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CONVERT
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
579 if (ret
== MMSYSERR_NOERROR
) {
580 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_DONE
;
582 TRACE("=> (%d)\n", ret
);
587 /***********************************************************************
588 * acmStreamPrepareHeader (MSACM32.41)
590 MMRESULT WINAPI
acmStreamPrepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
594 MMRESULT ret
= MMSYSERR_NOERROR
;
595 PACMDRVSTREAMHEADER padsh
;
597 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwPrepare
);
599 if ((was
= ACM_GetStream(has
)) == NULL
)
600 return MMSYSERR_INVALHANDLE
;
601 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
602 return MMSYSERR_INVALPARAM
;
604 ret
= MMSYSERR_INVALFLAG
;
606 if (pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_DONE
)
607 return MMSYSERR_NOERROR
;
609 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
610 * size. some fields are private to msacm internals, and are exposed
611 * in ACMSTREAMHEADER in the dwReservedDriver array
613 padsh
= (PACMDRVSTREAMHEADER
)pash
;
615 padsh
->fdwConvert
= fdwPrepare
;
616 padsh
->padshNext
= NULL
;
617 padsh
->fdwDriver
= padsh
->dwDriver
= 0L;
619 padsh
->fdwPrepared
= 0;
620 padsh
->dwPrepared
= 0;
621 padsh
->pbPreparedSrc
= 0;
622 padsh
->cbPreparedSrcLength
= 0;
623 padsh
->pbPreparedDst
= 0;
624 padsh
->cbPreparedDstLength
= 0;
626 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_PREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
627 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
628 ret
= MMSYSERR_NOERROR
;
629 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
);
630 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_PREPARED
;
631 padsh
->fdwPrepared
= padsh
->fdwStatus
;
632 padsh
->dwPrepared
= 0;
633 padsh
->pbPreparedSrc
= padsh
->pbSrc
;
634 padsh
->cbPreparedSrcLength
= padsh
->cbSrcLength
;
635 padsh
->pbPreparedDst
= padsh
->pbDst
;
636 padsh
->cbPreparedDstLength
= padsh
->cbDstLength
;
638 padsh
->fdwPrepared
= 0;
639 padsh
->dwPrepared
= 0;
640 padsh
->pbPreparedSrc
= 0;
641 padsh
->cbPreparedSrcLength
= 0;
642 padsh
->pbPreparedDst
= 0;
643 padsh
->cbPreparedDstLength
= 0;
645 TRACE("=> (%d)\n", ret
);
649 /***********************************************************************
650 * acmStreamReset (MSACM32.42)
652 MMRESULT WINAPI
acmStreamReset(HACMSTREAM has
, DWORD fdwReset
)
655 MMRESULT ret
= MMSYSERR_NOERROR
;
657 TRACE("(0x%08x, %ld)\n", has
, fdwReset
);
660 ret
= MMSYSERR_INVALFLAG
;
661 } else if ((was
= ACM_GetStream(has
)) == NULL
) {
662 return MMSYSERR_INVALHANDLE
;
663 } else if (was
->drvInst
.fdwOpen
& ACM_STREAMOPENF_ASYNC
) {
664 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_RESET
, (DWORD
)&was
->drvInst
, 0);
666 TRACE("=> (%d)\n", ret
);
670 /***********************************************************************
671 * acmStreamSize (MSACM32.43)
673 MMRESULT WINAPI
acmStreamSize(HACMSTREAM has
, DWORD cbInput
,
674 LPDWORD pdwOutputBytes
, DWORD fdwSize
)
677 ACMDRVSTREAMSIZE adss
;
680 TRACE("(0x%08x, %ld, %p, %ld)\n", has
, cbInput
, pdwOutputBytes
, fdwSize
);
682 if ((was
= ACM_GetStream(has
)) == NULL
) {
683 return MMSYSERR_INVALHANDLE
;
685 if ((fdwSize
& ~ACM_STREAMSIZEF_QUERYMASK
) != 0) {
686 return MMSYSERR_INVALFLAG
;
689 *pdwOutputBytes
= 0L;
691 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
692 case ACM_STREAMSIZEF_DESTINATION
:
693 adss
.cbDstLength
= cbInput
;
694 adss
.cbSrcLength
= 0;
696 case ACM_STREAMSIZEF_SOURCE
:
697 adss
.cbSrcLength
= cbInput
;
698 adss
.cbDstLength
= 0;
701 return MMSYSERR_INVALFLAG
;
704 adss
.cbStruct
= sizeof(adss
);
705 adss
.fdwSize
= fdwSize
;
706 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_SIZE
,
707 (DWORD
)&was
->drvInst
, (DWORD
)&adss
);
708 if (ret
== MMSYSERR_NOERROR
) {
709 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
710 case ACM_STREAMSIZEF_DESTINATION
:
711 *pdwOutputBytes
= adss
.cbSrcLength
;
713 case ACM_STREAMSIZEF_SOURCE
:
714 *pdwOutputBytes
= adss
.cbDstLength
;
718 TRACE("=> (%d) [%lu]\n", ret
, *pdwOutputBytes
);
722 /***********************************************************************
723 * acmStreamUnprepareHeader (MSACM32.44)
725 MMRESULT WINAPI
acmStreamUnprepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
729 MMRESULT ret
= MMSYSERR_NOERROR
;
730 PACMDRVSTREAMHEADER padsh
;
732 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwUnprepare
);
734 if ((was
= ACM_GetStream(has
)) == NULL
)
735 return MMSYSERR_INVALHANDLE
;
736 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
737 return MMSYSERR_INVALPARAM
;
739 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
740 return ACMERR_UNPREPARED
;
742 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
743 * size. some fields are private to msacm internals, and are exposed
744 * in ACMSTREAMHEADER in the dwReservedDriver array
746 padsh
= (PACMDRVSTREAMHEADER
)pash
;
748 /* check that pointers have not been modified */
749 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
750 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
751 padsh
->pbPreparedDst
!= padsh
->pbDst
||
752 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
753 return MMSYSERR_INVALPARAM
;
756 padsh
->fdwConvert
= fdwUnprepare
;
758 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_UNPREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
759 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
760 ret
= MMSYSERR_NOERROR
;
761 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
|ACMSTREAMHEADER_STATUSF_PREPARED
);
763 TRACE("=> (%d)\n", ret
);