comparison loader/afl.c @ 1:3b5f5d1c5041

Initial revision
author arpi_esp
date Sat, 24 Feb 2001 20:28:24 +0000
parents
children d8c1b0b38edc
comparison
equal deleted inserted replaced
0:c1bb2c071d63 1:3b5f5d1c5041
1 /**************************************************************************
2
3
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
7 are needed:
8
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
13 acmStreamClose
14 acmStreamSize
15 maybe acmStreamReset
16
17 In future I'll also add functions for format enumeration,
18 but not right now.
19
20
21 ***************************************************************************/
22 #include <config.h>
23
24 #include <stdio.h>
25 #include <string.h>
26
27 #include <wine/winbase.h>
28 #include <wine/windef.h>
29 #include <wine/winuser.h>
30 #include <wine/vfw.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>
36 #include "wineacm.h"
37 #pragma pack(1)
38 #define OpenDriverA DrvOpen
39 extern HDRVR VFWAPI DrvOpen(long);
40 #define CloseDriver DrvClose
41 extern HDRVR VFWAPI DrvClose(long);
42
43 static PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
44 {
45 return (PWINE_ACMSTREAM)has;
46 }
47
48 /***********************************************************************
49 * acmDriverAddA (MSACM32.2)
50 */
51 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
52 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
53 {
54 if (!phadid)
55 return MMSYSERR_INVALPARAM;
56
57 /* Check if any unknown flags */
58 if (fdwAdd &
59 ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
60 ACM_DRIVERADDF_GLOBAL))
61 return MMSYSERR_INVALFLAG;
62
63 /* Check if any incompatible flags */
64 if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
65 (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
66 return MMSYSERR_INVALFLAG;
67
68 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
69 * LoadDriver on it, to be sure we can call SendDriverMessage on the
70 * hDrvr handle.
71 */
72 *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule);
73
74 /* FIXME: lParam, dwPriority and fdwAdd ignored */
75
76 return MMSYSERR_NOERROR;
77 }
78
79 /***********************************************************************
80 * acmDriverClose (MSACM32.4)
81 */
82 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
83 {
84 PWINE_ACMDRIVER p;
85 PWINE_ACMDRIVER* tp;
86
87 if (fdwClose)
88 return MMSYSERR_INVALFLAG;
89
90 p = MSACM_GetDriver(had);
91 if (!p)
92 return MMSYSERR_INVALHANDLE;
93
94 for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
95 if (*tp == p) {
96 *tp = (*tp)->pNextACMDriver;
97 break;
98 }
99 }
100
101 if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
102 CloseDriver(p->hDrvr);
103
104 HeapFree(MSACM_hHeap, 0, p);
105
106 return MMSYSERR_NOERROR;
107 }
108
109 /***********************************************************************
110 * acmDriverEnum (MSACM32.7)
111 */
112 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
113 {
114 PWINE_ACMDRIVERID p;
115 DWORD fdwSupport;
116
117 if (!fnCallback) {
118 return MMSYSERR_INVALPARAM;
119 }
120
121 if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
122 return MMSYSERR_INVALFLAG;
123 }
124
125 for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
126 fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
127 if (!p->bEnabled) {
128 if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
129 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
130 else
131 continue;
132 }
133 (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
134 }
135
136 return MMSYSERR_NOERROR;
137 }
138
139 /***********************************************************************
140 * acmDriverID (MSACM32.8)
141 */
142 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
143 {
144 PWINE_ACMOBJ pao;
145
146 pao = MSACM_GetObj(hao);
147 if (!pao)
148 return MMSYSERR_INVALHANDLE;
149
150 if (!phadid)
151 return MMSYSERR_INVALPARAM;
152
153 if (fdwDriverID)
154 return MMSYSERR_INVALFLAG;
155
156 *phadid = (HACMDRIVERID) pao->pACMDriverID;
157
158 return MMSYSERR_NOERROR;
159 }
160
161 /***********************************************************************
162 * acmDriverMessage (MSACM32.9)
163 * FIXME
164 * Not implemented
165 */
166 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
167 {
168 PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
169 if (!pad)
170 return MMSYSERR_INVALPARAM;
171
172 /* FIXME: Check if uMsg legal */
173
174 if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
175 return MMSYSERR_NOTSUPPORTED;
176
177 return MMSYSERR_NOERROR;
178 }
179
180
181 /***********************************************************************
182 * acmDriverOpen (MSACM32.10)
183 */
184 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
185 {
186 PWINE_ACMDRIVERID padid;
187 PWINE_ACMDRIVER pad;
188 ICOPEN icopen;
189 HDRVR hdrv;
190
191
192
193 TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
194
195 if (!phad)
196 return MMSYSERR_INVALPARAM;
197
198 padid = MSACM_GetDriverID(hadid);
199 if (!padid)
200 return MMSYSERR_INVALHANDLE;
201
202 if (fdwOpen)
203 return MMSYSERR_INVALFLAG;
204
205 pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
206 if (!pad) return MMSYSERR_NOMEM;
207
208 pad->obj.pACMDriverID = padid;
209 icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c');
210 icopen.fccHandler = (long)padid->pszFileName;
211 icopen.dwSize = sizeof(ICOPEN);
212 icopen.dwFlags = 0;
213
214 if (!padid->hInstModule)
215 pad->hDrvr = OpenDriverA((long)&icopen);
216 else
217 pad->hDrvr = padid->hInstModule;
218
219 if (!pad->hDrvr) {
220 HeapFree(MSACM_hHeap, 0, pad);
221 return MMSYSERR_ERROR;
222 }
223
224 pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
225
226 /* insert new pad at beg of list */
227 pad->pNextACMDriver = padid->pACMDriverList;
228 padid->pACMDriverList = pad;
229
230 /* FIXME: Create a WINE_ACMDRIVER32 */
231 *phad = (HACMDRIVER)pad;
232
233 return MMSYSERR_NOERROR;
234 }
235
236 /***********************************************************************
237 * acmDriverRemove (MSACM32.12)
238 */
239 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
240 {
241 PWINE_ACMDRIVERID padid;
242
243 padid = MSACM_GetDriverID(hadid);
244 if (!padid)
245 return MMSYSERR_INVALHANDLE;
246
247 if (fdwRemove)
248 return MMSYSERR_INVALFLAG;
249
250 MSACM_UnregisterDriver(padid);
251
252 return MMSYSERR_NOERROR;
253 }
254
255
256
257 /**********************************************************************/
258
259 HANDLE MSACM_hHeap = (HANDLE) NULL;
260 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
261 PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
262
263 /***********************************************************************
264 * MSACM_RegisterDriver32()
265 */
266 PWINE_ACMDRIVERID MSACM_RegisterDriver(LPSTR pszDriverAlias, LPSTR pszFileName,
267 HINSTANCE hinstModule)
268 //
269 // File names are stored in driver.c. I reuse this variable to store driver ID
270 // in it. If it's <0x10000, it is primary codec for corresponding format.
271 //
272 {
273 PWINE_ACMDRIVERID padid;
274
275 TRACE("('%s', '%x', 0x%08x)\n", pszDriverAlias, pszFileName, hinstModule);
276
277 padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
278 padid->pszDriverAlias = (char*)malloc(strlen(pszDriverAlias)+1);
279 strcpy(padid->pszDriverAlias, pszDriverAlias);
280 // 1~strdup(pszDriverAlias);
281 padid->pszFileName = pszFileName;
282 padid->hInstModule = hinstModule;
283 padid->bEnabled = TRUE;
284 padid->pACMDriverList = NULL;
285 padid->pNextACMDriverID = NULL;
286 padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
287 if (MSACM_pLastACMDriverID)
288 MSACM_pLastACMDriverID->pNextACMDriverID = padid;
289 MSACM_pLastACMDriverID = padid;
290 if (!MSACM_pFirstACMDriverID)
291 MSACM_pFirstACMDriverID = padid;
292
293 return padid;
294 }
295
296 /***********************************************************************
297 * MSACM_RegisterAllDrivers32()
298 */
299 void MSACM_RegisterAllDrivers(void)
300 {
301 LPSTR pszBuffer;
302 DWORD dwBufferLength;
303
304 if (MSACM_pFirstACMDriverID)
305 return;
306
307 MSACM_RegisterDriver("divxa32", (LPSTR)0x161, 0); // DivX/WMA [07]
308 MSACM_RegisterDriver("msadp32", (LPSTR)0x2, 0); // MS ADPCM [08]
309 MSACM_RegisterDriver("l3codeca", (LPSTR)0x55, 0); // MPEG Layer-3 [12]
310 // MSACM_RegisterDriver("imaadp32", (LPSTR)0x11, 0); // IMA ADPCM [13]
311 // MSACM_RegisterDriver("msgsm32", (LPSTR)0x32, 0); // MS GSM 6.10 [14]
312 }
313
314 /***********************************************************************
315 * MSACM_UnregisterDriver32()
316 */
317 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
318 {
319 PWINE_ACMDRIVERID pNextACMDriverID;
320
321 while (p->pACMDriverList)
322 acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
323
324 if (p->pszDriverAlias)
325 HeapFree(MSACM_hHeap, 0, p->pszDriverAlias);
326 // if (p->pszFileName)
327 // HeapFree(MSACM_hHeap, 0, p->pszFileName);
328
329 if (p == MSACM_pFirstACMDriverID)
330 MSACM_pFirstACMDriverID = p->pNextACMDriverID;
331 if (p == MSACM_pLastACMDriverID)
332 MSACM_pLastACMDriverID = p->pPrevACMDriverID;
333
334 if (p->pPrevACMDriverID)
335 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
336 if (p->pNextACMDriverID)
337 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
338
339 pNextACMDriverID = p->pNextACMDriverID;
340
341 HeapFree(MSACM_hHeap, 0, p);
342
343 return pNextACMDriverID;
344 }
345
346 /***********************************************************************
347 * MSACM_UnregisterAllDrivers32()
348 * FIXME
349 * Where should this function be called?
350 */
351 void MSACM_UnregisterAllDrivers(void)
352 {
353 PWINE_ACMDRIVERID p;
354
355 for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
356 }
357
358 /***********************************************************************
359 * MSACM_GetDriverID32()
360 */
361 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
362 {
363 return (PWINE_ACMDRIVERID)hDriverID;
364 }
365
366 /***********************************************************************
367 * MSACM_GetDriver32()
368 */
369 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
370 {
371 return (PWINE_ACMDRIVER)hDriver;
372 }
373
374 /***********************************************************************
375 * MSACM_GetObj32()
376 */
377 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
378 {
379 return (PWINE_ACMOBJ)hObj;
380 }
381
382
383
384 /***********************************************************************
385 * acmStreamOpen (MSACM32.40)
386 */
387 MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
388 PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
389 DWORD dwInstance, DWORD fdwOpen)
390 {
391 PWINE_ACMSTREAM was;
392 PWINE_ACMDRIVER wad;
393 MMRESULT ret;
394 int wfxSrcSize;
395 int wfxDstSize;
396
397 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
398 phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
399
400 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
401 pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
402 pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
403
404 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
405 pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
406 pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
407
408 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
409 wfxSrcSize = SIZEOF_WFX(pwfxSrc);
410 wfxDstSize = SIZEOF_WFX(pwfxDst);
411 #undef SIZEOF_WFX
412
413 was = HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
414 if (was == NULL)
415 return MMSYSERR_NOMEM;
416
417 was->drvInst.cbStruct = sizeof(was->drvInst);
418 was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
419 memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
420 was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
421 memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
422 if (pwfltr) {
423 was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
424 memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
425 } else {
426 was->drvInst.pwfltr = NULL;
427 }
428 was->drvInst.dwCallback = dwCallback;
429 was->drvInst.dwInstance = dwInstance;
430 was->drvInst.fdwOpen = fdwOpen;
431 was->drvInst.fdwDriver = 0L;
432 was->drvInst.dwDriver = 0L;
433 was->drvInst.has = (HACMSTREAM)was;
434
435 if (had) {
436 if (!(wad = MSACM_GetDriver(had))) {
437 ret = MMSYSERR_INVALPARAM;
438 goto errCleanUp;
439 }
440
441 was->obj.pACMDriverID = wad->obj.pACMDriverID;
442 was->pDrv = wad;
443 was->hAcmDriver = 0; /* not to close it in acmStreamClose */
444
445 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
446 if (ret != MMSYSERR_NOERROR)
447 goto errCleanUp;
448 } else {
449 PWINE_ACMDRIVERID wadi;
450 short drv_tag;
451 ret = ACMERR_NOTPOSSIBLE;
452 /* if(pwfxSrc->wFormatTag==1)//compression
453 drv_tag=pwfxDst->wFormatTag;
454 else
455 if(pwfxDst->wFormatTag==1)//decompression
456 drv_tag=pwfxSrc->wFormatTag;
457 else
458 goto errCleanUp;
459
460 ret=acmDriverOpen2(drv_tag);
461 if (ret == MMSYSERR_NOERROR) {
462 if ((wad = MSACM_GetDriver(had)) != 0) {
463 was->obj.pACMDriverID = wad->obj.pACMDriverID;
464 was->pDrv = wad;
465 was->hAcmDriver = had;
466
467 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
468 if (ret == MMSYSERR_NOERROR) {
469 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
470 acmDriverClose(had, 0L);
471 }
472 break;
473 }
474 }
475 acmDriverClose(had, 0L);*/
476 if(MSACM_pFirstACMDriverID==NULL)
477 MSACM_RegisterAllDrivers();
478
479 for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID) {
480 ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
481 if (ret == MMSYSERR_NOERROR) {
482 if ((wad = MSACM_GetDriver(had)) != 0) {
483 was->obj.pACMDriverID = wad->obj.pACMDriverID;
484 was->pDrv = wad;
485 was->hAcmDriver = had;
486
487 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
488 if (ret == MMSYSERR_NOERROR) {
489 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
490 acmDriverClose(had, 0L);
491 }
492 break;
493 }
494 }
495 // no match, close this acm driver and try next one
496 acmDriverClose(had, 0L);
497 }
498 }
499 if (ret != MMSYSERR_NOERROR) {
500 ret = ACMERR_NOTPOSSIBLE;
501 goto errCleanUp;
502 }
503 }
504 ret = MMSYSERR_NOERROR;
505 if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
506 if (phas)
507 *phas = (HACMSTREAM)was;
508 TRACE("=> (%d)\n", ret);
509 return ret;
510 }
511 errCleanUp:
512 if (phas)
513 *phas = (HACMSTREAM)0;
514 HeapFree(MSACM_hHeap, 0, was);
515 TRACE("=> (%d)\n", ret);
516 return ret;
517 }
518
519
520 MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
521 {
522 PWINE_ACMSTREAM was;
523 MMRESULT ret;
524
525 TRACE("(0x%08x, %ld)\n", has, fdwClose);
526
527 if ((was = ACM_GetStream(has)) == NULL) {
528 return MMSYSERR_INVALHANDLE;
529 }
530 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
531 if (ret == MMSYSERR_NOERROR) {
532 if (was->hAcmDriver)
533 acmDriverClose(was->hAcmDriver, 0L);
534 HeapFree(MSACM_hHeap, 0, was);
535 }
536 TRACE("=> (%d)\n", ret);
537 return ret;
538 }
539
540 /***********************************************************************
541 * acmStreamConvert (MSACM32.38)
542 */
543 MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
544 DWORD fdwConvert)
545 {
546 PWINE_ACMSTREAM was;
547 MMRESULT ret = MMSYSERR_NOERROR;
548 PACMDRVSTREAMHEADER padsh;
549
550 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
551
552 if ((was = ACM_GetStream(has)) == NULL)
553 return MMSYSERR_INVALHANDLE;
554 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
555 return MMSYSERR_INVALPARAM;
556
557 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
558 return ACMERR_UNPREPARED;
559
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
563 */
564 padsh = (PACMDRVSTREAMHEADER)pash;
565
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;
572 }
573
574 padsh->fdwConvert = fdwConvert;
575
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;
579 }
580 TRACE("=> (%d)\n", ret);
581 return ret;
582 }
583
584
585 /***********************************************************************
586 * acmStreamPrepareHeader (MSACM32.41)
587 */
588 MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
589 DWORD fdwPrepare)
590 {
591 PWINE_ACMSTREAM was;
592 MMRESULT ret = MMSYSERR_NOERROR;
593 PACMDRVSTREAMHEADER padsh;
594
595 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
596
597 if ((was = ACM_GetStream(has)) == NULL)
598 return MMSYSERR_INVALHANDLE;
599 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
600 return MMSYSERR_INVALPARAM;
601 if (fdwPrepare)
602 ret = MMSYSERR_INVALFLAG;
603
604 if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
605 return MMSYSERR_NOERROR;
606
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
610 */
611 padsh = (PACMDRVSTREAMHEADER)pash;
612
613 padsh->fdwConvert = fdwPrepare;
614 padsh->padshNext = NULL;
615 padsh->fdwDriver = padsh->dwDriver = 0L;
616
617 padsh->fdwPrepared = 0;
618 padsh->dwPrepared = 0;
619 padsh->pbPreparedSrc = 0;
620 padsh->cbPreparedSrcLength = 0;
621 padsh->pbPreparedDst = 0;
622 padsh->cbPreparedDstLength = 0;
623
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;
635 } else {
636 padsh->fdwPrepared = 0;
637 padsh->dwPrepared = 0;
638 padsh->pbPreparedSrc = 0;
639 padsh->cbPreparedSrcLength = 0;
640 padsh->pbPreparedDst = 0;
641 padsh->cbPreparedDstLength = 0;
642 }
643 TRACE("=> (%d)\n", ret);
644 return ret;
645 }
646
647 /***********************************************************************
648 * acmStreamReset (MSACM32.42)
649 */
650 MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
651 {
652 PWINE_ACMSTREAM was;
653 MMRESULT ret = MMSYSERR_NOERROR;
654
655 TRACE("(0x%08x, %ld)\n", has, fdwReset);
656
657 if (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);
663 }
664 TRACE("=> (%d)\n", ret);
665 return ret;
666 }
667
668 /***********************************************************************
669 * acmStreamSize (MSACM32.43)
670 */
671 MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
672 LPDWORD pdwOutputBytes, DWORD fdwSize)
673 {
674 PWINE_ACMSTREAM was;
675 ACMDRVSTREAMSIZE adss;
676 MMRESULT ret;
677
678 TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
679
680 if ((was = ACM_GetStream(has)) == NULL) {
681 return MMSYSERR_INVALHANDLE;
682 }
683 if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
684 return MMSYSERR_INVALFLAG;
685 }
686
687 *pdwOutputBytes = 0L;
688
689 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
690 case ACM_STREAMSIZEF_DESTINATION:
691 adss.cbDstLength = cbInput;
692 adss.cbSrcLength = 0;
693 break;
694 case ACM_STREAMSIZEF_SOURCE:
695 adss.cbSrcLength = cbInput;
696 adss.cbDstLength = 0;
697 break;
698 default:
699 return MMSYSERR_INVALFLAG;
700 }
701
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;
710 break;
711 case ACM_STREAMSIZEF_SOURCE:
712 *pdwOutputBytes = adss.cbDstLength;
713 break;
714 }
715 }
716 TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
717 return ret;
718 }
719
720 /***********************************************************************
721 * acmStreamUnprepareHeader (MSACM32.44)
722 */
723 MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
724 DWORD fdwUnprepare)
725 {
726 PWINE_ACMSTREAM was;
727 MMRESULT ret = MMSYSERR_NOERROR;
728 PACMDRVSTREAMHEADER padsh;
729
730 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
731
732 if ((was = ACM_GetStream(has)) == NULL)
733 return MMSYSERR_INVALHANDLE;
734 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
735 return MMSYSERR_INVALPARAM;
736
737 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
738 return ACMERR_UNPREPARED;
739
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
743 */
744 padsh = (PACMDRVSTREAMHEADER)pash;
745
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;
752 }
753
754 padsh->fdwConvert = fdwUnprepare;
755
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);
760 }
761 TRACE("=> (%d)\n", ret);
762 return ret;
763 }