spec files have been renamed
[vlc.git] / loader / afl.c
blob421414874a1e77a222465e7a86bfd7af55360aa7
1 /*
2 * $Id$
4 * Copyright (C) 1998 Patrick Stridvall
5 * Copyright (C) 1999 Eric Pouech
7 * Originally distributed under LPGL 2.1 (or later) by the Wine project.
9 * Modified for use with MPlayer, detailed CVS changelog at
10 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
12 * File now distributed as part of VLC media player with no modifications.
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
29 /**************************************************************************
32 This file will contain an interface to ACM drivers.
33 Its content will be based mainly on wine/dlls/msacm32
34 actually, for audio decompression only the following functions
35 are needed:
37 acmStreamOpen ( takes formats of src and dest, returns stream handle )
38 acmStreamPrepareHeader ( takes stream handler and info on data )
39 acmStreamConvert ( the same as PrepareHeader )
40 acmStreamUnprepareHeader
41 acmStreamClose
42 acmStreamSize
43 maybe acmStreamReset
45 In future I'll also add functions for format enumeration,
46 but not right now.
48 Modified for use with MPlayer, detailed CVS changelog at
49 http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
51 ***************************************************************************/
52 #include "config.h"
54 #include "wine/winbase.h"
55 #include "wine/windef.h"
56 #include "wine/winuser.h"
57 #include "wine/vfw.h"
58 #include "wine/winestring.h"
59 #include "wine/driver.h"
60 #include "wine/winerror.h"
61 #include "wine/msacm.h"
62 #include "wine/msacmdrv.h"
63 #include "wineacm.h"
64 #ifndef __MINGW32__
65 #include "ext.h"
66 #endif
67 #include "driver.h"
69 #include <stdio.h>
70 #include <stdlib.h>
71 #include <string.h>
72 #pragma pack(1)
73 #define OpenDriverA DrvOpen
74 #define CloseDriver DrvClose
76 static inline PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
78 return (PWINE_ACMSTREAM)has;
81 /***********************************************************************
82 * acmDriverAddA (MSACM32.2)
84 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
85 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
87 if (!phadid)
88 return MMSYSERR_INVALPARAM;
90 /* Check if any unknown flags */
91 if (fdwAdd &
92 ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
93 ACM_DRIVERADDF_GLOBAL))
94 return MMSYSERR_INVALFLAG;
96 /* Check if any incompatible flags */
97 if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
98 (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
99 return MMSYSERR_INVALFLAG;
101 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
102 * LoadDriver on it, to be sure we can call SendDriverMessage on the
103 * hDrvr handle.
105 *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, 0, hinstModule);
107 /* FIXME: lParam, dwPriority and fdwAdd ignored */
109 return MMSYSERR_NOERROR;
112 /***********************************************************************
113 * acmDriverClose (MSACM32.4)
115 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
117 PWINE_ACMDRIVER p;
118 PWINE_ACMDRIVER* tp;
120 if (fdwClose)
121 return MMSYSERR_INVALFLAG;
123 p = MSACM_GetDriver(had);
124 if (!p)
125 return MMSYSERR_INVALHANDLE;
127 for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
128 if (*tp == p) {
129 *tp = (*tp)->pNextACMDriver;
130 break;
134 if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
135 CloseDriver(p->hDrvr);
137 HeapFree(MSACM_hHeap, 0, p);
139 return MMSYSERR_NOERROR;
142 /***********************************************************************
143 * acmDriverEnum (MSACM32.7)
145 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
147 PWINE_ACMDRIVERID p;
148 DWORD fdwSupport;
150 if (!fnCallback) {
151 return MMSYSERR_INVALPARAM;
154 if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
155 return MMSYSERR_INVALFLAG;
158 for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
159 fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
160 if (!p->bEnabled) {
161 if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
162 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
163 else
164 continue;
166 (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
169 return MMSYSERR_NOERROR;
172 /***********************************************************************
173 * acmDriverID (MSACM32.8)
175 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
177 PWINE_ACMOBJ pao;
179 pao = MSACM_GetObj(hao);
180 if (!pao)
181 return MMSYSERR_INVALHANDLE;
183 if (!phadid)
184 return MMSYSERR_INVALPARAM;
186 if (fdwDriverID)
187 return MMSYSERR_INVALFLAG;
189 *phadid = (HACMDRIVERID) pao->pACMDriverID;
191 return MMSYSERR_NOERROR;
194 /***********************************************************************
195 * acmDriverMessage (MSACM32.9)
196 * FIXME
197 * Not implemented
199 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
201 PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
202 if (!pad)
203 return MMSYSERR_INVALPARAM;
205 /* FIXME: Check if uMsg legal */
207 if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
208 return MMSYSERR_NOTSUPPORTED;
210 return MMSYSERR_NOERROR;
214 /***********************************************************************
215 * acmDriverOpen (MSACM32.10)
217 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
219 PWINE_ACMDRIVERID padid;
220 PWINE_ACMDRIVER pad;
221 ICOPEN icopen;
222 HDRVR hdrv;
225 TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
227 if (!phad)
228 return MMSYSERR_INVALPARAM;
230 padid = MSACM_GetDriverID(hadid);
231 if (!padid)
232 return MMSYSERR_INVALHANDLE;
234 if (fdwOpen)
235 return MMSYSERR_INVALFLAG;
237 pad = (PWINE_ACMDRIVER) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
238 if (!pad)
239 return MMSYSERR_NOMEM;
241 pad->obj.pACMDriverID = padid;
242 icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c');
243 icopen.fccHandler = (long)padid->pszFileName;
244 icopen.dwSize = sizeof(ICOPEN);
245 icopen.dwFlags = 0;
247 icopen.pV1Reserved = padid->pszFileName;
248 if (!padid->hInstModule)
249 pad->hDrvr = OpenDriverA((long)&icopen);
250 else
251 pad->hDrvr = padid->hInstModule;
253 if (!pad->hDrvr) {
254 HeapFree(MSACM_hHeap, 0, pad);
255 return MMSYSERR_ERROR;
258 pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
260 /* insert new pad at beg of list */
261 pad->pNextACMDriver = padid->pACMDriverList;
262 padid->pACMDriverList = pad;
264 /* FIXME: Create a WINE_ACMDRIVER32 */
265 *phad = (HACMDRIVER)pad;
267 return MMSYSERR_NOERROR;
270 /***********************************************************************
271 * acmDriverRemove (MSACM32.12)
273 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
275 PWINE_ACMDRIVERID padid;
277 padid = MSACM_GetDriverID(hadid);
278 if (!padid)
279 return MMSYSERR_INVALHANDLE;
281 if (fdwRemove)
282 return MMSYSERR_INVALFLAG;
284 MSACM_UnregisterDriver(padid);
286 return MMSYSERR_NOERROR;
291 /**********************************************************************/
293 HANDLE MSACM_hHeap = (HANDLE) NULL;
294 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
295 PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
297 /***********************************************************************
298 * MSACM_RegisterDriver32()
300 PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName,
301 WORD wFormatTag,
302 HINSTANCE hinstModule)
304 PWINE_ACMDRIVERID padid;
306 TRACE("('%s', '%x', 0x%08x)\n", pszFileName, wFormatTag, hinstModule);
308 #ifndef WIN32_LOADER
309 MSACM_hHeap = GetProcessHeap();
310 #endif
311 padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
312 padid->pszFileName = (char*)malloc(strlen(pszFileName)+1);
313 strcpy(padid->pszFileName, pszFileName);
314 // 1~strdup(pszDriverAlias);
315 padid->wFormatTag = wFormatTag;
316 padid->hInstModule = hinstModule;
317 padid->bEnabled = TRUE;
318 padid->pACMDriverList = NULL;
319 padid->pNextACMDriverID = NULL;
320 padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
321 if (MSACM_pLastACMDriverID)
322 MSACM_pLastACMDriverID->pNextACMDriverID = padid;
323 MSACM_pLastACMDriverID = padid;
324 if (!MSACM_pFirstACMDriverID)
325 MSACM_pFirstACMDriverID = padid;
327 return padid;
331 /***********************************************************************
332 * MSACM_UnregisterDriver32()
334 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
336 PWINE_ACMDRIVERID pNextACMDriverID;
338 while (p->pACMDriverList)
339 acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
341 if (p->pszFileName)
342 free(p->pszFileName);
344 if (p == MSACM_pFirstACMDriverID)
345 MSACM_pFirstACMDriverID = p->pNextACMDriverID;
346 if (p == MSACM_pLastACMDriverID)
347 MSACM_pLastACMDriverID = p->pPrevACMDriverID;
349 if (p->pPrevACMDriverID)
350 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
351 if (p->pNextACMDriverID)
352 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
354 pNextACMDriverID = p->pNextACMDriverID;
356 HeapFree(MSACM_hHeap, 0, p);
358 return pNextACMDriverID;
361 /***********************************************************************
362 * MSACM_UnregisterAllDrivers32()
363 * FIXME
364 * Where should this function be called?
366 void MSACM_UnregisterAllDrivers(void)
368 PWINE_ACMDRIVERID p;
370 for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
373 /***********************************************************************
374 * MSACM_GetDriverID32()
376 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
378 return (PWINE_ACMDRIVERID)hDriverID;
381 /***********************************************************************
382 * MSACM_GetDriver32()
384 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
386 return (PWINE_ACMDRIVER)hDriver;
389 /***********************************************************************
390 * MSACM_GetObj32()
392 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
394 return (PWINE_ACMOBJ)hObj;
399 /***********************************************************************
400 * acmStreamOpen (MSACM32.40)
402 MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
403 PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
404 DWORD dwInstance, DWORD fdwOpen)
406 PWINE_ACMSTREAM was;
407 PWINE_ACMDRIVER wad;
408 MMRESULT ret;
409 int wfxSrcSize;
410 int wfxDstSize;
412 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
413 phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
415 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
416 pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
417 pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
419 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
420 pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
421 pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
423 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
424 wfxSrcSize = SIZEOF_WFX(pwfxSrc);
425 wfxDstSize = SIZEOF_WFX(pwfxDst);
426 #undef SIZEOF_WFX
428 was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
429 if (was == NULL)
430 return MMSYSERR_NOMEM;
431 was->drvInst.cbStruct = sizeof(was->drvInst);
432 was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
433 memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
434 // LHACM is checking for 0x1
435 // but if this will not help
436 // was->drvInst.pwfxSrc->wFormatTag = 1;
437 was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
438 memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
439 if (pwfltr) {
440 was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
441 memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
442 } else {
443 was->drvInst.pwfltr = NULL;
445 was->drvInst.dwCallback = dwCallback;
446 was->drvInst.dwInstance = dwInstance;
447 was->drvInst.fdwOpen = fdwOpen;
448 was->drvInst.fdwDriver = 0L;
449 was->drvInst.dwDriver = 0L;
450 was->drvInst.has = (HACMSTREAM)was;
452 if (had) {
453 if (!(wad = MSACM_GetDriver(had))) {
454 ret = MMSYSERR_INVALPARAM;
455 goto errCleanUp;
458 was->obj.pACMDriverID = wad->obj.pACMDriverID;
459 was->pDrv = wad;
460 was->hAcmDriver = 0; /* not to close it in acmStreamClose */
462 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
463 if (ret != MMSYSERR_NOERROR)
464 goto errCleanUp;
465 } else {
466 PWINE_ACMDRIVERID wadi;
467 short drv_tag;
468 ret = ACMERR_NOTPOSSIBLE;
469 /* if(pwfxSrc->wFormatTag==1)//compression
470 drv_tag=pwfxDst->wFormatTag;
471 else
472 if(pwfxDst->wFormatTag==1)//decompression
473 drv_tag=pwfxSrc->wFormatTag;
474 else
475 goto errCleanUp;
477 ret=acmDriverOpen2(drv_tag);
478 if (ret == MMSYSERR_NOERROR) {
479 if ((wad = MSACM_GetDriver(had)) != 0) {
480 was->obj.pACMDriverID = wad->obj.pACMDriverID;
481 was->pDrv = wad;
482 was->hAcmDriver = had;
484 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
485 if (ret == MMSYSERR_NOERROR) {
486 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
487 acmDriverClose(had, 0L);
489 break;
492 acmDriverClose(had, 0L);*/
493 //if(MSACM_pFirstACMDriverID==NULL)
494 // MSACM_RegisterAllDrivers();
496 for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID)
498 /* Check Format */
499 if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue;
501 ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
502 if (ret == MMSYSERR_NOERROR) {
503 if ((wad = MSACM_GetDriver(had)) != 0) {
504 was->obj.pACMDriverID = wad->obj.pACMDriverID;
505 was->pDrv = wad;
506 was->hAcmDriver = had;
508 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
509 //lhacm - crash printf("RETOPEN %d\n", ret);
510 //ret = 0;
511 if (ret == MMSYSERR_NOERROR) {
512 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
513 acmDriverClose(had, 0L);
515 break;
518 // no match, close this acm driver and try next one
519 acmDriverClose(had, 0L);
522 if (ret != MMSYSERR_NOERROR) {
523 ret = ACMERR_NOTPOSSIBLE;
524 goto errCleanUp;
527 ret = MMSYSERR_NOERROR;
528 if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
529 if (phas)
530 *phas = (HACMSTREAM)was;
531 TRACE("=> (%d)\n", ret);
532 #ifdef WIN32_LOADER
533 CodecAlloc();
534 #endif
535 return ret;
537 errCleanUp:
538 if (phas)
539 *phas = (HACMSTREAM)0;
540 HeapFree(MSACM_hHeap, 0, was);
541 TRACE("=> (%d)\n", ret);
542 return ret;
546 MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
548 PWINE_ACMSTREAM was;
549 MMRESULT ret;
551 TRACE("(0x%08x, %ld)\n", has, fdwClose);
553 if ((was = ACM_GetStream(has)) == NULL) {
554 return MMSYSERR_INVALHANDLE;
556 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
557 if (ret == MMSYSERR_NOERROR) {
558 if (was->hAcmDriver)
559 acmDriverClose(was->hAcmDriver, 0L);
560 HeapFree(MSACM_hHeap, 0, was);
561 #ifdef WIN32_LOADER
562 CodecRelease();
563 #endif
565 TRACE("=> (%d)\n", ret);
566 return ret;
569 /***********************************************************************
570 * acmStreamConvert (MSACM32.38)
572 MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
573 DWORD fdwConvert)
575 PWINE_ACMSTREAM was;
576 MMRESULT ret = MMSYSERR_NOERROR;
577 PACMDRVSTREAMHEADER padsh;
579 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
581 if ((was = ACM_GetStream(has)) == NULL)
582 return MMSYSERR_INVALHANDLE;
583 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
584 return MMSYSERR_INVALPARAM;
586 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
587 return ACMERR_UNPREPARED;
589 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
590 * size. some fields are private to msacm internals, and are exposed
591 * in ACMSTREAMHEADER in the dwReservedDriver array
593 padsh = (PACMDRVSTREAMHEADER)pash;
595 /* check that pointers have not been modified */
596 if (padsh->pbPreparedSrc != padsh->pbSrc ||
597 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
598 padsh->pbPreparedDst != padsh->pbDst ||
599 padsh->cbPreparedDstLength < padsh->cbDstLength) {
600 return MMSYSERR_INVALPARAM;
603 padsh->fdwConvert = fdwConvert;
605 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
606 if (ret == MMSYSERR_NOERROR) {
607 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
609 TRACE("=> (%d)\n", ret);
610 return ret;
614 /***********************************************************************
615 * acmStreamPrepareHeader (MSACM32.41)
617 MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
618 DWORD fdwPrepare)
620 PWINE_ACMSTREAM was;
621 MMRESULT ret = MMSYSERR_NOERROR;
622 PACMDRVSTREAMHEADER padsh;
624 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
626 if ((was = ACM_GetStream(has)) == NULL)
627 return MMSYSERR_INVALHANDLE;
628 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
629 return MMSYSERR_INVALPARAM;
630 if (fdwPrepare)
631 ret = MMSYSERR_INVALFLAG;
633 if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
634 return MMSYSERR_NOERROR;
636 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
637 * size. some fields are private to msacm internals, and are exposed
638 * in ACMSTREAMHEADER in the dwReservedDriver array
640 padsh = (PACMDRVSTREAMHEADER)pash;
642 padsh->fdwConvert = fdwPrepare;
643 padsh->padshNext = NULL;
644 padsh->fdwDriver = padsh->dwDriver = 0L;
646 padsh->fdwPrepared = 0;
647 padsh->dwPrepared = 0;
648 padsh->pbPreparedSrc = 0;
649 padsh->cbPreparedSrcLength = 0;
650 padsh->pbPreparedDst = 0;
651 padsh->cbPreparedDstLength = 0;
653 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
654 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
655 ret = MMSYSERR_NOERROR;
656 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
657 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
658 padsh->fdwPrepared = padsh->fdwStatus;
659 padsh->dwPrepared = 0;
660 padsh->pbPreparedSrc = padsh->pbSrc;
661 padsh->cbPreparedSrcLength = padsh->cbSrcLength;
662 padsh->pbPreparedDst = padsh->pbDst;
663 padsh->cbPreparedDstLength = padsh->cbDstLength;
664 } else {
665 padsh->fdwPrepared = 0;
666 padsh->dwPrepared = 0;
667 padsh->pbPreparedSrc = 0;
668 padsh->cbPreparedSrcLength = 0;
669 padsh->pbPreparedDst = 0;
670 padsh->cbPreparedDstLength = 0;
672 TRACE("=> (%d)\n", ret);
673 return ret;
676 /***********************************************************************
677 * acmStreamReset (MSACM32.42)
679 MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
681 PWINE_ACMSTREAM was;
682 MMRESULT ret = MMSYSERR_NOERROR;
684 TRACE("(0x%08x, %ld)\n", has, fdwReset);
686 if (fdwReset) {
687 ret = MMSYSERR_INVALFLAG;
688 } else if ((was = ACM_GetStream(has)) == NULL) {
689 return MMSYSERR_INVALHANDLE;
690 } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
691 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
693 TRACE("=> (%d)\n", ret);
694 return ret;
697 /***********************************************************************
698 * acmStreamSize (MSACM32.43)
700 MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
701 LPDWORD pdwOutputBytes, DWORD fdwSize)
703 PWINE_ACMSTREAM was;
704 ACMDRVSTREAMSIZE adss;
705 MMRESULT ret;
707 TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
709 if ((was = ACM_GetStream(has)) == NULL) {
710 return MMSYSERR_INVALHANDLE;
712 if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
713 return MMSYSERR_INVALFLAG;
716 *pdwOutputBytes = 0L;
718 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
719 case ACM_STREAMSIZEF_DESTINATION:
720 adss.cbDstLength = cbInput;
721 adss.cbSrcLength = 0;
722 break;
723 case ACM_STREAMSIZEF_SOURCE:
724 adss.cbSrcLength = cbInput;
725 adss.cbDstLength = 0;
726 break;
727 default:
728 return MMSYSERR_INVALFLAG;
731 adss.cbStruct = sizeof(adss);
732 adss.fdwSize = fdwSize;
733 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE,
734 (DWORD)&was->drvInst, (DWORD)&adss);
735 if (ret == MMSYSERR_NOERROR) {
736 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
737 case ACM_STREAMSIZEF_DESTINATION:
738 *pdwOutputBytes = adss.cbSrcLength;
739 break;
740 case ACM_STREAMSIZEF_SOURCE:
741 *pdwOutputBytes = adss.cbDstLength;
742 break;
745 TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
746 return ret;
749 /***********************************************************************
750 * acmStreamUnprepareHeader (MSACM32.44)
752 MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
753 DWORD fdwUnprepare)
755 PWINE_ACMSTREAM was;
756 MMRESULT ret = MMSYSERR_NOERROR;
757 PACMDRVSTREAMHEADER padsh;
759 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
761 if ((was = ACM_GetStream(has)) == NULL)
762 return MMSYSERR_INVALHANDLE;
763 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
764 return MMSYSERR_INVALPARAM;
766 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
767 return ACMERR_UNPREPARED;
769 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
770 * size. some fields are private to msacm internals, and are exposed
771 * in ACMSTREAMHEADER in the dwReservedDriver array
773 padsh = (PACMDRVSTREAMHEADER)pash;
775 /* check that pointers have not been modified */
776 if (padsh->pbPreparedSrc != padsh->pbSrc ||
777 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
778 padsh->pbPreparedDst != padsh->pbDst ||
779 padsh->cbPreparedDstLength < padsh->cbDstLength) {
780 return MMSYSERR_INVALPARAM;
783 padsh->fdwConvert = fdwUnprepare;
785 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
786 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
787 ret = MMSYSERR_NOERROR;
788 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
790 TRACE("=> (%d)\n", ret);
791 return ret;