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,
21 ***************************************************************************/
24 #include "wine/winbase.h"
25 #include "wine/windef.h"
26 #include "wine/winuser.h"
28 #include "wine/winestring.h"
29 #include "wine/driver.h"
30 #include "wine/winerror.h"
31 #include "wine/msacm.h"
32 #include "wine/msacmdrv.h"
43 #define OpenDriverA DrvOpen
44 #define CloseDriver DrvClose
46 static inline PWINE_ACMSTREAM
ACM_GetStream(HACMSTREAM has
)
48 return (PWINE_ACMSTREAM
)has
;
51 /***********************************************************************
52 * acmDriverAddA (MSACM32.2)
54 MMRESULT WINAPI
acmDriverAddA(PHACMDRIVERID phadid
, HINSTANCE hinstModule
,
55 LPARAM lParam
, DWORD dwPriority
, DWORD fdwAdd
)
58 return MMSYSERR_INVALPARAM
;
60 /* Check if any unknown flags */
62 ~(ACM_DRIVERADDF_FUNCTION
|ACM_DRIVERADDF_NOTIFYHWND
|
63 ACM_DRIVERADDF_GLOBAL
))
64 return MMSYSERR_INVALFLAG
;
66 /* Check if any incompatible flags */
67 if ((fdwAdd
& ACM_DRIVERADDF_FUNCTION
) &&
68 (fdwAdd
& ACM_DRIVERADDF_NOTIFYHWND
))
69 return MMSYSERR_INVALFLAG
;
71 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
72 * LoadDriver on it, to be sure we can call SendDriverMessage on the
75 *phadid
= (HACMDRIVERID
) MSACM_RegisterDriver(NULL
, 0, hinstModule
);
77 /* FIXME: lParam, dwPriority and fdwAdd ignored */
79 return MMSYSERR_NOERROR
;
82 /***********************************************************************
83 * acmDriverClose (MSACM32.4)
85 MMRESULT WINAPI
acmDriverClose(HACMDRIVER had
, DWORD fdwClose
)
91 return MMSYSERR_INVALFLAG
;
93 p
= MSACM_GetDriver(had
);
95 return MMSYSERR_INVALHANDLE
;
97 for (tp
= &(p
->obj
.pACMDriverID
->pACMDriverList
); *tp
; *tp
= (*tp
)->pNextACMDriver
) {
99 *tp
= (*tp
)->pNextACMDriver
;
104 if (p
->hDrvr
&& !p
->obj
.pACMDriverID
->pACMDriverList
)
105 CloseDriver(p
->hDrvr
);
107 HeapFree(MSACM_hHeap
, 0, p
);
109 return MMSYSERR_NOERROR
;
112 /***********************************************************************
113 * acmDriverEnum (MSACM32.7)
115 MMRESULT WINAPI
acmDriverEnum(ACMDRIVERENUMCB fnCallback
, DWORD dwInstance
, DWORD fdwEnum
)
121 return MMSYSERR_INVALPARAM
;
124 if (fdwEnum
&& ~(ACM_DRIVERENUMF_NOLOCAL
|ACM_DRIVERENUMF_DISABLED
)) {
125 return MMSYSERR_INVALFLAG
;
128 for (p
= MSACM_pFirstACMDriverID
; p
; p
= p
->pNextACMDriverID
) {
129 fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
131 if (fdwEnum
& ACM_DRIVERENUMF_DISABLED
)
132 fdwSupport
|= ACMDRIVERDETAILS_SUPPORTF_DISABLED
;
136 (*fnCallback
)((HACMDRIVERID
) p
, dwInstance
, fdwSupport
);
139 return MMSYSERR_NOERROR
;
142 /***********************************************************************
143 * acmDriverID (MSACM32.8)
145 MMRESULT WINAPI
acmDriverID(HACMOBJ hao
, PHACMDRIVERID phadid
, DWORD fdwDriverID
)
149 pao
= MSACM_GetObj(hao
);
151 return MMSYSERR_INVALHANDLE
;
154 return MMSYSERR_INVALPARAM
;
157 return MMSYSERR_INVALFLAG
;
159 *phadid
= (HACMDRIVERID
) pao
->pACMDriverID
;
161 return MMSYSERR_NOERROR
;
164 /***********************************************************************
165 * acmDriverMessage (MSACM32.9)
169 LRESULT WINAPI
acmDriverMessage(HACMDRIVER had
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
171 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
173 return MMSYSERR_INVALPARAM
;
175 /* FIXME: Check if uMsg legal */
177 if (!SendDriverMessage(pad
->hDrvr
, uMsg
, lParam1
, lParam2
))
178 return MMSYSERR_NOTSUPPORTED
;
180 return MMSYSERR_NOERROR
;
184 /***********************************************************************
185 * acmDriverOpen (MSACM32.10)
187 MMRESULT WINAPI
acmDriverOpen(PHACMDRIVER phad
, HACMDRIVERID hadid
, DWORD fdwOpen
)
189 PWINE_ACMDRIVERID padid
;
195 TRACE("(%p, %x, %08lu)\n", phad
, hadid
, fdwOpen
);
198 return MMSYSERR_INVALPARAM
;
200 padid
= MSACM_GetDriverID(hadid
);
202 return MMSYSERR_INVALHANDLE
;
205 return MMSYSERR_INVALFLAG
;
207 pad
= (PWINE_ACMDRIVER
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVER
));
209 return MMSYSERR_NOMEM
;
211 pad
->obj
.pACMDriverID
= padid
;
212 icopen
.fccType
= mmioFOURCC('a', 'u', 'd', 'c');
213 icopen
.fccHandler
= (long)padid
->pszFileName
;
214 icopen
.dwSize
= sizeof(ICOPEN
);
217 icopen
.pV1Reserved
= padid
->pszFileName
;
218 if (!padid
->hInstModule
)
219 pad
->hDrvr
= OpenDriverA((long)&icopen
);
221 pad
->hDrvr
= padid
->hInstModule
;
224 HeapFree(MSACM_hHeap
, 0, pad
);
225 return MMSYSERR_ERROR
;
228 pad
->pfnDriverProc
= GetProcAddress(pad
->hDrvr
, "DriverProc");
230 /* insert new pad at beg of list */
231 pad
->pNextACMDriver
= padid
->pACMDriverList
;
232 padid
->pACMDriverList
= pad
;
234 /* FIXME: Create a WINE_ACMDRIVER32 */
235 *phad
= (HACMDRIVER
)pad
;
237 return MMSYSERR_NOERROR
;
240 /***********************************************************************
241 * acmDriverRemove (MSACM32.12)
243 MMRESULT WINAPI
acmDriverRemove(HACMDRIVERID hadid
, DWORD fdwRemove
)
245 PWINE_ACMDRIVERID padid
;
247 padid
= MSACM_GetDriverID(hadid
);
249 return MMSYSERR_INVALHANDLE
;
252 return MMSYSERR_INVALFLAG
;
254 MSACM_UnregisterDriver(padid
);
256 return MMSYSERR_NOERROR
;
261 /**********************************************************************/
263 HANDLE MSACM_hHeap
= (HANDLE
) NULL
;
264 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID
= NULL
;
265 PWINE_ACMDRIVERID MSACM_pLastACMDriverID
= NULL
;
267 /***********************************************************************
268 * MSACM_RegisterDriver32()
270 PWINE_ACMDRIVERID
MSACM_RegisterDriver(const char* pszFileName
,
272 HINSTANCE hinstModule
)
274 PWINE_ACMDRIVERID padid
;
276 TRACE("('%s', '%x', 0x%08x)\n", pszFileName
, wFormatTag
, hinstModule
);
279 MSACM_hHeap
= GetProcessHeap();
281 padid
= (PWINE_ACMDRIVERID
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVERID
));
282 padid
->pszFileName
= (char*)malloc(strlen(pszFileName
)+1);
283 strcpy(padid
->pszFileName
, pszFileName
);
284 // 1~strdup(pszDriverAlias);
285 padid
->wFormatTag
= wFormatTag
;
286 padid
->hInstModule
= hinstModule
;
287 padid
->bEnabled
= TRUE
;
288 padid
->pACMDriverList
= NULL
;
289 padid
->pNextACMDriverID
= NULL
;
290 padid
->pPrevACMDriverID
= MSACM_pLastACMDriverID
;
291 if (MSACM_pLastACMDriverID
)
292 MSACM_pLastACMDriverID
->pNextACMDriverID
= padid
;
293 MSACM_pLastACMDriverID
= padid
;
294 if (!MSACM_pFirstACMDriverID
)
295 MSACM_pFirstACMDriverID
= padid
;
301 /***********************************************************************
302 * MSACM_UnregisterDriver32()
304 PWINE_ACMDRIVERID
MSACM_UnregisterDriver(PWINE_ACMDRIVERID p
)
306 PWINE_ACMDRIVERID pNextACMDriverID
;
308 while (p
->pACMDriverList
)
309 acmDriverClose((HACMDRIVER
) p
->pACMDriverList
, 0);
312 free(p
->pszFileName
);
314 if (p
== MSACM_pFirstACMDriverID
)
315 MSACM_pFirstACMDriverID
= p
->pNextACMDriverID
;
316 if (p
== MSACM_pLastACMDriverID
)
317 MSACM_pLastACMDriverID
= p
->pPrevACMDriverID
;
319 if (p
->pPrevACMDriverID
)
320 p
->pPrevACMDriverID
->pNextACMDriverID
= p
->pNextACMDriverID
;
321 if (p
->pNextACMDriverID
)
322 p
->pNextACMDriverID
->pPrevACMDriverID
= p
->pPrevACMDriverID
;
324 pNextACMDriverID
= p
->pNextACMDriverID
;
326 HeapFree(MSACM_hHeap
, 0, p
);
328 return pNextACMDriverID
;
331 /***********************************************************************
332 * MSACM_UnregisterAllDrivers32()
334 * Where should this function be called?
336 void MSACM_UnregisterAllDrivers(void)
340 for (p
= MSACM_pFirstACMDriverID
; p
; p
= MSACM_UnregisterDriver(p
));
343 /***********************************************************************
344 * MSACM_GetDriverID32()
346 PWINE_ACMDRIVERID
MSACM_GetDriverID(HACMDRIVERID hDriverID
)
348 return (PWINE_ACMDRIVERID
)hDriverID
;
351 /***********************************************************************
352 * MSACM_GetDriver32()
354 PWINE_ACMDRIVER
MSACM_GetDriver(HACMDRIVER hDriver
)
356 return (PWINE_ACMDRIVER
)hDriver
;
359 /***********************************************************************
362 PWINE_ACMOBJ
MSACM_GetObj(HACMOBJ hObj
)
364 return (PWINE_ACMOBJ
)hObj
;
369 /***********************************************************************
370 * acmStreamOpen (MSACM32.40)
372 MMRESULT WINAPI
acmStreamOpen(PHACMSTREAM phas
, HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
373 PWAVEFORMATEX pwfxDst
, PWAVEFILTER pwfltr
, DWORD dwCallback
,
374 DWORD dwInstance
, DWORD fdwOpen
)
382 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
383 phas
, had
, pwfxSrc
, pwfxDst
, pwfltr
, dwCallback
, dwInstance
, fdwOpen
);
385 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
386 pwfxSrc
->wFormatTag
, pwfxSrc
->nChannels
, pwfxSrc
->nSamplesPerSec
, pwfxSrc
->nAvgBytesPerSec
,
387 pwfxSrc
->nBlockAlign
, pwfxSrc
->wBitsPerSample
, pwfxSrc
->cbSize
);
389 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
390 pwfxDst
->wFormatTag
, pwfxDst
->nChannels
, pwfxDst
->nSamplesPerSec
, pwfxDst
->nAvgBytesPerSec
,
391 pwfxDst
->nBlockAlign
, pwfxDst
->wBitsPerSample
, pwfxDst
->cbSize
);
393 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
394 wfxSrcSize
= SIZEOF_WFX(pwfxSrc
);
395 wfxDstSize
= SIZEOF_WFX(pwfxDst
);
398 was
= (PWINE_ACMSTREAM
) HeapAlloc(MSACM_hHeap
, 0, sizeof(*was
) + wfxSrcSize
+ wfxDstSize
+ ((pwfltr
) ? sizeof(WAVEFILTER
) : 0));
400 return MMSYSERR_NOMEM
;
401 was
->drvInst
.cbStruct
= sizeof(was
->drvInst
);
402 was
->drvInst
.pwfxSrc
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
));
403 memcpy(was
->drvInst
.pwfxSrc
, pwfxSrc
, wfxSrcSize
);
404 // LHACM is checking for 0x1
405 // but if this will not help
406 // was->drvInst.pwfxSrc->wFormatTag = 1;
407 was
->drvInst
.pwfxDst
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
);
408 memcpy(was
->drvInst
.pwfxDst
, pwfxDst
, wfxDstSize
);
410 was
->drvInst
.pwfltr
= (PWAVEFILTER
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
+ wfxDstSize
);
411 memcpy(was
->drvInst
.pwfltr
, pwfltr
, sizeof(WAVEFILTER
));
413 was
->drvInst
.pwfltr
= NULL
;
415 was
->drvInst
.dwCallback
= dwCallback
;
416 was
->drvInst
.dwInstance
= dwInstance
;
417 was
->drvInst
.fdwOpen
= fdwOpen
;
418 was
->drvInst
.fdwDriver
= 0L;
419 was
->drvInst
.dwDriver
= 0L;
420 was
->drvInst
.has
= (HACMSTREAM
)was
;
423 if (!(wad
= MSACM_GetDriver(had
))) {
424 ret
= MMSYSERR_INVALPARAM
;
428 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
430 was
->hAcmDriver
= 0; /* not to close it in acmStreamClose */
432 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
433 if (ret
!= MMSYSERR_NOERROR
)
436 PWINE_ACMDRIVERID wadi
;
438 ret
= ACMERR_NOTPOSSIBLE
;
439 /* if(pwfxSrc->wFormatTag==1)//compression
440 drv_tag=pwfxDst->wFormatTag;
442 if(pwfxDst->wFormatTag==1)//decompression
443 drv_tag=pwfxSrc->wFormatTag;
447 ret=acmDriverOpen2(drv_tag);
448 if (ret == MMSYSERR_NOERROR) {
449 if ((wad = MSACM_GetDriver(had)) != 0) {
450 was->obj.pACMDriverID = wad->obj.pACMDriverID;
452 was->hAcmDriver = had;
454 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
455 if (ret == MMSYSERR_NOERROR) {
456 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
457 acmDriverClose(had, 0L);
462 acmDriverClose(had, 0L);*/
463 //if(MSACM_pFirstACMDriverID==NULL)
464 // MSACM_RegisterAllDrivers();
466 for (wadi
= MSACM_pFirstACMDriverID
; wadi
; wadi
= wadi
->pNextACMDriverID
)
469 if ((int)wadi
->wFormatTag
!= (int)pwfxSrc
->wFormatTag
) continue;
471 ret
= acmDriverOpen(&had
, (HACMDRIVERID
)wadi
, 0L);
472 if (ret
== MMSYSERR_NOERROR
) {
473 if ((wad
= MSACM_GetDriver(had
)) != 0) {
474 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
476 was
->hAcmDriver
= had
;
478 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
479 //lhacm - crash printf("RETOPEN %d\n", ret);
481 if (ret
== MMSYSERR_NOERROR
) {
482 if (fdwOpen
& ACM_STREAMOPENF_QUERY
) {
483 acmDriverClose(had
, 0L);
488 // no match, close this acm driver and try next one
489 acmDriverClose(had
, 0L);
492 if (ret
!= MMSYSERR_NOERROR
) {
493 ret
= ACMERR_NOTPOSSIBLE
;
497 ret
= MMSYSERR_NOERROR
;
498 if (!(fdwOpen
& ACM_STREAMOPENF_QUERY
)) {
500 *phas
= (HACMSTREAM
)was
;
501 TRACE("=> (%d)\n", ret
);
509 *phas
= (HACMSTREAM
)0;
510 HeapFree(MSACM_hHeap
, 0, was
);
511 TRACE("=> (%d)\n", ret
);
516 MMRESULT WINAPI
acmStreamClose(HACMSTREAM has
, DWORD fdwClose
)
521 TRACE("(0x%08x, %ld)\n", has
, fdwClose
);
523 if ((was
= ACM_GetStream(has
)) == NULL
) {
524 return MMSYSERR_INVALHANDLE
;
526 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CLOSE
, (DWORD
)&was
->drvInst
, 0);
527 if (ret
== MMSYSERR_NOERROR
) {
529 acmDriverClose(was
->hAcmDriver
, 0L);
530 HeapFree(MSACM_hHeap
, 0, was
);
535 TRACE("=> (%d)\n", ret
);
539 /***********************************************************************
540 * acmStreamConvert (MSACM32.38)
542 MMRESULT WINAPI
acmStreamConvert(HACMSTREAM has
, PACMSTREAMHEADER pash
,
546 MMRESULT ret
= MMSYSERR_NOERROR
;
547 PACMDRVSTREAMHEADER padsh
;
549 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwConvert
);
551 if ((was
= ACM_GetStream(has
)) == NULL
)
552 return MMSYSERR_INVALHANDLE
;
553 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
554 return MMSYSERR_INVALPARAM
;
556 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
557 return ACMERR_UNPREPARED
;
559 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
560 * size. some fields are private to msacm internals, and are exposed
561 * in ACMSTREAMHEADER in the dwReservedDriver array
563 padsh
= (PACMDRVSTREAMHEADER
)pash
;
565 /* check that pointers have not been modified */
566 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
567 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
568 padsh
->pbPreparedDst
!= padsh
->pbDst
||
569 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
570 return MMSYSERR_INVALPARAM
;
573 padsh
->fdwConvert
= fdwConvert
;
575 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CONVERT
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
576 if (ret
== MMSYSERR_NOERROR
) {
577 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_DONE
;
579 TRACE("=> (%d)\n", ret
);
584 /***********************************************************************
585 * acmStreamPrepareHeader (MSACM32.41)
587 MMRESULT WINAPI
acmStreamPrepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
591 MMRESULT ret
= MMSYSERR_NOERROR
;
592 PACMDRVSTREAMHEADER padsh
;
594 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwPrepare
);
596 if ((was
= ACM_GetStream(has
)) == NULL
)
597 return MMSYSERR_INVALHANDLE
;
598 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
599 return MMSYSERR_INVALPARAM
;
601 ret
= MMSYSERR_INVALFLAG
;
603 if (pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_DONE
)
604 return MMSYSERR_NOERROR
;
606 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
607 * size. some fields are private to msacm internals, and are exposed
608 * in ACMSTREAMHEADER in the dwReservedDriver array
610 padsh
= (PACMDRVSTREAMHEADER
)pash
;
612 padsh
->fdwConvert
= fdwPrepare
;
613 padsh
->padshNext
= NULL
;
614 padsh
->fdwDriver
= padsh
->dwDriver
= 0L;
616 padsh
->fdwPrepared
= 0;
617 padsh
->dwPrepared
= 0;
618 padsh
->pbPreparedSrc
= 0;
619 padsh
->cbPreparedSrcLength
= 0;
620 padsh
->pbPreparedDst
= 0;
621 padsh
->cbPreparedDstLength
= 0;
623 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_PREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
624 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
625 ret
= MMSYSERR_NOERROR
;
626 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
);
627 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_PREPARED
;
628 padsh
->fdwPrepared
= padsh
->fdwStatus
;
629 padsh
->dwPrepared
= 0;
630 padsh
->pbPreparedSrc
= padsh
->pbSrc
;
631 padsh
->cbPreparedSrcLength
= padsh
->cbSrcLength
;
632 padsh
->pbPreparedDst
= padsh
->pbDst
;
633 padsh
->cbPreparedDstLength
= padsh
->cbDstLength
;
635 padsh
->fdwPrepared
= 0;
636 padsh
->dwPrepared
= 0;
637 padsh
->pbPreparedSrc
= 0;
638 padsh
->cbPreparedSrcLength
= 0;
639 padsh
->pbPreparedDst
= 0;
640 padsh
->cbPreparedDstLength
= 0;
642 TRACE("=> (%d)\n", ret
);
646 /***********************************************************************
647 * acmStreamReset (MSACM32.42)
649 MMRESULT WINAPI
acmStreamReset(HACMSTREAM has
, DWORD fdwReset
)
652 MMRESULT ret
= MMSYSERR_NOERROR
;
654 TRACE("(0x%08x, %ld)\n", has
, fdwReset
);
657 ret
= MMSYSERR_INVALFLAG
;
658 } else if ((was
= ACM_GetStream(has
)) == NULL
) {
659 return MMSYSERR_INVALHANDLE
;
660 } else if (was
->drvInst
.fdwOpen
& ACM_STREAMOPENF_ASYNC
) {
661 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_RESET
, (DWORD
)&was
->drvInst
, 0);
663 TRACE("=> (%d)\n", ret
);
667 /***********************************************************************
668 * acmStreamSize (MSACM32.43)
670 MMRESULT WINAPI
acmStreamSize(HACMSTREAM has
, DWORD cbInput
,
671 LPDWORD pdwOutputBytes
, DWORD fdwSize
)
674 ACMDRVSTREAMSIZE adss
;
677 TRACE("(0x%08x, %ld, %p, %ld)\n", has
, cbInput
, pdwOutputBytes
, fdwSize
);
679 if ((was
= ACM_GetStream(has
)) == NULL
) {
680 return MMSYSERR_INVALHANDLE
;
682 if ((fdwSize
& ~ACM_STREAMSIZEF_QUERYMASK
) != 0) {
683 return MMSYSERR_INVALFLAG
;
686 *pdwOutputBytes
= 0L;
688 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
689 case ACM_STREAMSIZEF_DESTINATION
:
690 adss
.cbDstLength
= cbInput
;
691 adss
.cbSrcLength
= 0;
693 case ACM_STREAMSIZEF_SOURCE
:
694 adss
.cbSrcLength
= cbInput
;
695 adss
.cbDstLength
= 0;
698 return MMSYSERR_INVALFLAG
;
701 adss
.cbStruct
= sizeof(adss
);
702 adss
.fdwSize
= fdwSize
;
703 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_SIZE
,
704 (DWORD
)&was
->drvInst
, (DWORD
)&adss
);
705 if (ret
== MMSYSERR_NOERROR
) {
706 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
707 case ACM_STREAMSIZEF_DESTINATION
:
708 *pdwOutputBytes
= adss
.cbSrcLength
;
710 case ACM_STREAMSIZEF_SOURCE
:
711 *pdwOutputBytes
= adss
.cbDstLength
;
715 TRACE("=> (%d) [%lu]\n", ret
, *pdwOutputBytes
);
719 /***********************************************************************
720 * acmStreamUnprepareHeader (MSACM32.44)
722 MMRESULT WINAPI
acmStreamUnprepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
726 MMRESULT ret
= MMSYSERR_NOERROR
;
727 PACMDRVSTREAMHEADER padsh
;
729 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwUnprepare
);
731 if ((was
= ACM_GetStream(has
)) == NULL
)
732 return MMSYSERR_INVALHANDLE
;
733 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
734 return MMSYSERR_INVALPARAM
;
736 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
737 return ACMERR_UNPREPARED
;
739 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
740 * size. some fields are private to msacm internals, and are exposed
741 * in ACMSTREAMHEADER in the dwReservedDriver array
743 padsh
= (PACMDRVSTREAMHEADER
)pash
;
745 /* check that pointers have not been modified */
746 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
747 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
748 padsh
->pbPreparedDst
!= padsh
->pbDst
||
749 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
750 return MMSYSERR_INVALPARAM
;
753 padsh
->fdwConvert
= fdwUnprepare
;
755 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_UNPREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
756 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
757 ret
= MMSYSERR_NOERROR
;
758 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
|ACMSTREAMHEADER_STATUSF_PREPARED
);
760 TRACE("=> (%d)\n", ret
);