00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026
00027 #include "wine/winbase.h"
00028 #include "wine/windef.h"
00029 #include "wine/winuser.h"
00030 #include "wine/vfw.h"
00031 #include "wine/winestring.h"
00032 #include "wine/driver.h"
00033 #include "wine/winerror.h"
00034 #include "wine/msacm.h"
00035 #include "wine/msacmdrv.h"
00036 #include "wineacm.h"
00037 #ifndef __MINGW32__
00038 #include "ext.h"
00039 #endif
00040 #include "driver.h"
00041
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #pragma pack(1)
00046 #define OpenDriverA DrvOpen
00047 #define CloseDriver DrvClose
00048
00049 static inline PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
00050 {
00051 return (PWINE_ACMSTREAM)has;
00052 }
00053
00054
00055
00056
00057 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
00058 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
00059 {
00060 if (!phadid)
00061 return MMSYSERR_INVALPARAM;
00062
00063
00064 if (fdwAdd &
00065 ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
00066 ACM_DRIVERADDF_GLOBAL))
00067 return MMSYSERR_INVALFLAG;
00068
00069
00070 if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
00071 (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
00072 return MMSYSERR_INVALFLAG;
00073
00074
00075
00076
00077
00078 *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, 0, hinstModule);
00079
00080
00081
00082 return MMSYSERR_NOERROR;
00083 }
00084
00085
00086
00087
00088 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
00089 {
00090 PWINE_ACMDRIVER p;
00091 PWINE_ACMDRIVER* tp;
00092
00093 if (fdwClose)
00094 return MMSYSERR_INVALFLAG;
00095
00096 p = MSACM_GetDriver(had);
00097 if (!p)
00098 return MMSYSERR_INVALHANDLE;
00099
00100 for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
00101 if (*tp == p) {
00102 *tp = (*tp)->pNextACMDriver;
00103 break;
00104 }
00105 }
00106
00107 if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
00108 CloseDriver(p->hDrvr);
00109
00110 HeapFree(MSACM_hHeap, 0, p);
00111
00112 return MMSYSERR_NOERROR;
00113 }
00114
00115
00116
00117
00118 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
00119 {
00120 PWINE_ACMDRIVERID p;
00121 DWORD fdwSupport;
00122
00123 if (!fnCallback) {
00124 return MMSYSERR_INVALPARAM;
00125 }
00126
00127 if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
00128 return MMSYSERR_INVALFLAG;
00129 }
00130
00131 for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
00132 fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
00133 if (!p->bEnabled) {
00134 if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
00135 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
00136 else
00137 continue;
00138 }
00139 (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
00140 }
00141
00142 return MMSYSERR_NOERROR;
00143 }
00144
00145
00146
00147
00148 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
00149 {
00150 PWINE_ACMOBJ pao;
00151
00152 pao = MSACM_GetObj(hao);
00153 if (!pao)
00154 return MMSYSERR_INVALHANDLE;
00155
00156 if (!phadid)
00157 return MMSYSERR_INVALPARAM;
00158
00159 if (fdwDriverID)
00160 return MMSYSERR_INVALFLAG;
00161
00162 *phadid = (HACMDRIVERID) pao->pACMDriverID;
00163
00164 return MMSYSERR_NOERROR;
00165 }
00166
00167
00168
00169
00170
00171
00172 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
00173 {
00174 PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
00175 if (!pad)
00176 return MMSYSERR_INVALPARAM;
00177
00178
00179
00180 if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
00181 return MMSYSERR_NOTSUPPORTED;
00182
00183 return MMSYSERR_NOERROR;
00184 }
00185
00186
00187
00188
00189
00190 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
00191 {
00192 PWINE_ACMDRIVERID padid;
00193 PWINE_ACMDRIVER pad;
00194 ICOPEN icopen;
00195 HDRVR hdrv;
00196
00197
00198 TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
00199
00200 if (!phad)
00201 return MMSYSERR_INVALPARAM;
00202
00203 padid = MSACM_GetDriverID(hadid);
00204 if (!padid)
00205 return MMSYSERR_INVALHANDLE;
00206
00207 if (fdwOpen)
00208 return MMSYSERR_INVALFLAG;
00209
00210 pad = (PWINE_ACMDRIVER) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
00211 if (!pad)
00212 return MMSYSERR_NOMEM;
00213
00214 pad->obj.pACMDriverID = padid;
00215 icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c');
00216 icopen.fccHandler = (long)padid->pszFileName;
00217 icopen.dwSize = sizeof(ICOPEN);
00218 icopen.dwFlags = 0;
00219
00220 icopen.pV1Reserved = padid->pszFileName;
00221 if (!padid->hInstModule)
00222 pad->hDrvr = OpenDriverA((long)&icopen);
00223 else
00224 pad->hDrvr = padid->hInstModule;
00225
00226 if (!pad->hDrvr) {
00227 HeapFree(MSACM_hHeap, 0, pad);
00228 return MMSYSERR_ERROR;
00229 }
00230
00231 pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
00232
00233
00234 pad->pNextACMDriver = padid->pACMDriverList;
00235 padid->pACMDriverList = pad;
00236
00237
00238 *phad = (HACMDRIVER)pad;
00239
00240 return MMSYSERR_NOERROR;
00241 }
00242
00243
00244
00245
00246 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
00247 {
00248 PWINE_ACMDRIVERID padid;
00249
00250 padid = MSACM_GetDriverID(hadid);
00251 if (!padid)
00252 return MMSYSERR_INVALHANDLE;
00253
00254 if (fdwRemove)
00255 return MMSYSERR_INVALFLAG;
00256
00257 MSACM_UnregisterDriver(padid);
00258
00259 return MMSYSERR_NOERROR;
00260 }
00261
00262
00263
00264
00265
00266 HANDLE MSACM_hHeap = (HANDLE) NULL;
00267 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
00268 PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
00269
00270
00271
00272
00273 PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName,
00274 WORD wFormatTag,
00275 HINSTANCE hinstModule)
00276 {
00277 PWINE_ACMDRIVERID padid;
00278
00279 TRACE("('%s', '%x', 0x%08x)\n", pszFileName, wFormatTag, hinstModule);
00280
00281 #ifndef WIN32_LOADER
00282 MSACM_hHeap = GetProcessHeap();
00283 #endif
00284 padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
00285 padid->pszFileName = (char*)malloc(strlen(pszFileName)+1);
00286 strcpy(padid->pszFileName, pszFileName);
00287
00288 padid->wFormatTag = wFormatTag;
00289 padid->hInstModule = hinstModule;
00290 padid->bEnabled = TRUE;
00291 padid->pACMDriverList = NULL;
00292 padid->pNextACMDriverID = NULL;
00293 padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
00294 if (MSACM_pLastACMDriverID)
00295 MSACM_pLastACMDriverID->pNextACMDriverID = padid;
00296 MSACM_pLastACMDriverID = padid;
00297 if (!MSACM_pFirstACMDriverID)
00298 MSACM_pFirstACMDriverID = padid;
00299
00300 return padid;
00301 }
00302
00303
00304
00305
00306
00307 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
00308 {
00309 PWINE_ACMDRIVERID pNextACMDriverID;
00310
00311 while (p->pACMDriverList)
00312 acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
00313
00314 if (p->pszFileName)
00315 free(p->pszFileName);
00316
00317 if (p == MSACM_pFirstACMDriverID)
00318 MSACM_pFirstACMDriverID = p->pNextACMDriverID;
00319 if (p == MSACM_pLastACMDriverID)
00320 MSACM_pLastACMDriverID = p->pPrevACMDriverID;
00321
00322 if (p->pPrevACMDriverID)
00323 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
00324 if (p->pNextACMDriverID)
00325 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
00326
00327 pNextACMDriverID = p->pNextACMDriverID;
00328
00329 HeapFree(MSACM_hHeap, 0, p);
00330
00331 return pNextACMDriverID;
00332 }
00333
00334
00335
00336
00337
00338
00339 void MSACM_UnregisterAllDrivers(void)
00340 {
00341 PWINE_ACMDRIVERID p;
00342
00343 for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
00344 }
00345
00346
00347
00348
00349 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
00350 {
00351 return (PWINE_ACMDRIVERID)hDriverID;
00352 }
00353
00354
00355
00356
00357 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
00358 {
00359 return (PWINE_ACMDRIVER)hDriver;
00360 }
00361
00362
00363
00364
00365 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
00366 {
00367 return (PWINE_ACMOBJ)hObj;
00368 }
00369
00370
00371
00372
00373
00374
00375 MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
00376 PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
00377 DWORD dwInstance, DWORD fdwOpen)
00378 {
00379 PWINE_ACMSTREAM was;
00380 PWINE_ACMDRIVER wad;
00381 MMRESULT ret;
00382 int wfxSrcSize;
00383 int wfxDstSize;
00384
00385 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
00386 phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
00387
00388 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
00389 pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
00390 pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
00391
00392 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
00393 pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
00394 pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
00395
00396 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
00397 wfxSrcSize = SIZEOF_WFX(pwfxSrc);
00398 wfxDstSize = SIZEOF_WFX(pwfxDst);
00399 #undef SIZEOF_WFX
00400
00401 was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
00402 if (was == NULL)
00403 return MMSYSERR_NOMEM;
00404 was->drvInst.cbStruct = sizeof(was->drvInst);
00405 was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
00406 memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
00407
00408
00409
00410 was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
00411 memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
00412 if (pwfltr) {
00413 was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
00414 memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
00415 } else {
00416 was->drvInst.pwfltr = NULL;
00417 }
00418 was->drvInst.dwCallback = dwCallback;
00419 was->drvInst.dwInstance = dwInstance;
00420 was->drvInst.fdwOpen = fdwOpen;
00421 was->drvInst.fdwDriver = 0L;
00422 was->drvInst.dwDriver = 0L;
00423 was->drvInst.has = (HACMSTREAM)was;
00424
00425 if (had) {
00426 if (!(wad = MSACM_GetDriver(had))) {
00427 ret = MMSYSERR_INVALPARAM;
00428 goto errCleanUp;
00429 }
00430
00431 was->obj.pACMDriverID = wad->obj.pACMDriverID;
00432 was->pDrv = wad;
00433 was->hAcmDriver = 0;
00434
00435 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
00436 if (ret != MMSYSERR_NOERROR)
00437 goto errCleanUp;
00438 } else {
00439 PWINE_ACMDRIVERID wadi;
00440 short drv_tag;
00441 ret = ACMERR_NOTPOSSIBLE;
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID)
00470 {
00471
00472 if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue;
00473
00474 ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
00475 if (ret == MMSYSERR_NOERROR) {
00476 if ((wad = MSACM_GetDriver(had)) != 0) {
00477 was->obj.pACMDriverID = wad->obj.pACMDriverID;
00478 was->pDrv = wad;
00479 was->hAcmDriver = had;
00480
00481 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
00482
00483
00484 if (ret == MMSYSERR_NOERROR) {
00485 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
00486 acmDriverClose(had, 0L);
00487 }
00488 break;
00489 }
00490 }
00491
00492 acmDriverClose(had, 0L);
00493 }
00494 }
00495 if (ret != MMSYSERR_NOERROR) {
00496 ret = ACMERR_NOTPOSSIBLE;
00497 goto errCleanUp;
00498 }
00499 }
00500 ret = MMSYSERR_NOERROR;
00501 if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
00502 if (phas)
00503 *phas = (HACMSTREAM)was;
00504 TRACE("=> (%d)\n", ret);
00505 #ifdef WIN32_LOADER
00506 CodecAlloc();
00507 #endif
00508 return ret;
00509 }
00510 errCleanUp:
00511 if (phas)
00512 *phas = (HACMSTREAM)0;
00513 HeapFree(MSACM_hHeap, 0, was);
00514 TRACE("=> (%d)\n", ret);
00515 return ret;
00516 }
00517
00518
00519 MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
00520 {
00521 PWINE_ACMSTREAM was;
00522 MMRESULT ret;
00523
00524 TRACE("(0x%08x, %ld)\n", has, fdwClose);
00525
00526 if ((was = ACM_GetStream(has)) == NULL) {
00527 return MMSYSERR_INVALHANDLE;
00528 }
00529 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
00530 if (ret == MMSYSERR_NOERROR) {
00531 if (was->hAcmDriver)
00532 acmDriverClose(was->hAcmDriver, 0L);
00533 HeapFree(MSACM_hHeap, 0, was);
00534 #ifdef WIN32_LOADER
00535 CodecRelease();
00536 #endif
00537 }
00538 TRACE("=> (%d)\n", ret);
00539 return ret;
00540 }
00541
00542
00543
00544
00545 MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
00546 DWORD fdwConvert)
00547 {
00548 PWINE_ACMSTREAM was;
00549 MMRESULT ret = MMSYSERR_NOERROR;
00550 PACMDRVSTREAMHEADER padsh;
00551
00552 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
00553
00554 if ((was = ACM_GetStream(has)) == NULL)
00555 return MMSYSERR_INVALHANDLE;
00556 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
00557 return MMSYSERR_INVALPARAM;
00558
00559 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
00560 return ACMERR_UNPREPARED;
00561
00562
00563
00564
00565
00566 padsh = (PACMDRVSTREAMHEADER)pash;
00567
00568
00569 if (padsh->pbPreparedSrc != padsh->pbSrc ||
00570 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
00571 padsh->pbPreparedDst != padsh->pbDst ||
00572 padsh->cbPreparedDstLength < padsh->cbDstLength) {
00573 return MMSYSERR_INVALPARAM;
00574 }
00575
00576 padsh->fdwConvert = fdwConvert;
00577
00578 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
00579 if (ret == MMSYSERR_NOERROR) {
00580 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
00581 }
00582 TRACE("=> (%d)\n", ret);
00583 return ret;
00584 }
00585
00586
00587
00588
00589
00590 MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
00591 DWORD fdwPrepare)
00592 {
00593 PWINE_ACMSTREAM was;
00594 MMRESULT ret = MMSYSERR_NOERROR;
00595 PACMDRVSTREAMHEADER padsh;
00596
00597 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
00598
00599 if ((was = ACM_GetStream(has)) == NULL)
00600 return MMSYSERR_INVALHANDLE;
00601 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
00602 return MMSYSERR_INVALPARAM;
00603 if (fdwPrepare)
00604 ret = MMSYSERR_INVALFLAG;
00605
00606 if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
00607 return MMSYSERR_NOERROR;
00608
00609
00610
00611
00612
00613 padsh = (PACMDRVSTREAMHEADER)pash;
00614
00615 padsh->fdwConvert = fdwPrepare;
00616 padsh->padshNext = NULL;
00617 padsh->fdwDriver = padsh->dwDriver = 0L;
00618
00619 padsh->fdwPrepared = 0;
00620 padsh->dwPrepared = 0;
00621 padsh->pbPreparedSrc = 0;
00622 padsh->cbPreparedSrcLength = 0;
00623 padsh->pbPreparedDst = 0;
00624 padsh->cbPreparedDstLength = 0;
00625
00626 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
00627 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
00628 ret = MMSYSERR_NOERROR;
00629 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
00630 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
00631 padsh->fdwPrepared = padsh->fdwStatus;
00632 padsh->dwPrepared = 0;
00633 padsh->pbPreparedSrc = padsh->pbSrc;
00634 padsh->cbPreparedSrcLength = padsh->cbSrcLength;
00635 padsh->pbPreparedDst = padsh->pbDst;
00636 padsh->cbPreparedDstLength = padsh->cbDstLength;
00637 } else {
00638 padsh->fdwPrepared = 0;
00639 padsh->dwPrepared = 0;
00640 padsh->pbPreparedSrc = 0;
00641 padsh->cbPreparedSrcLength = 0;
00642 padsh->pbPreparedDst = 0;
00643 padsh->cbPreparedDstLength = 0;
00644 }
00645 TRACE("=> (%d)\n", ret);
00646 return ret;
00647 }
00648
00649
00650
00651
00652 MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
00653 {
00654 PWINE_ACMSTREAM was;
00655 MMRESULT ret = MMSYSERR_NOERROR;
00656
00657 TRACE("(0x%08x, %ld)\n", has, fdwReset);
00658
00659 if (fdwReset) {
00660 ret = MMSYSERR_INVALFLAG;
00661 } else if ((was = ACM_GetStream(has)) == NULL) {
00662 return MMSYSERR_INVALHANDLE;
00663 } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
00664 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
00665 }
00666 TRACE("=> (%d)\n", ret);
00667 return ret;
00668 }
00669
00670
00671
00672
00673 MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
00674 LPDWORD pdwOutputBytes, DWORD fdwSize)
00675 {
00676 PWINE_ACMSTREAM was;
00677 ACMDRVSTREAMSIZE adss;
00678 MMRESULT ret;
00679
00680 TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
00681
00682 if ((was = ACM_GetStream(has)) == NULL) {
00683 return MMSYSERR_INVALHANDLE;
00684 }
00685 if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
00686 return MMSYSERR_INVALFLAG;
00687 }
00688
00689 *pdwOutputBytes = 0L;
00690
00691 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
00692 case ACM_STREAMSIZEF_DESTINATION:
00693 adss.cbDstLength = cbInput;
00694 adss.cbSrcLength = 0;
00695 break;
00696 case ACM_STREAMSIZEF_SOURCE:
00697 adss.cbSrcLength = cbInput;
00698 adss.cbDstLength = 0;
00699 break;
00700 default:
00701 return MMSYSERR_INVALFLAG;
00702 }
00703
00704 adss.cbStruct = sizeof(adss);
00705 adss.fdwSize = fdwSize;
00706 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE,
00707 (DWORD)&was->drvInst, (DWORD)&adss);
00708 if (ret == MMSYSERR_NOERROR) {
00709 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
00710 case ACM_STREAMSIZEF_DESTINATION:
00711 *pdwOutputBytes = adss.cbSrcLength;
00712 break;
00713 case ACM_STREAMSIZEF_SOURCE:
00714 *pdwOutputBytes = adss.cbDstLength;
00715 break;
00716 }
00717 }
00718 TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
00719 return ret;
00720 }
00721
00722
00723
00724
00725 MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
00726 DWORD fdwUnprepare)
00727 {
00728 PWINE_ACMSTREAM was;
00729 MMRESULT ret = MMSYSERR_NOERROR;
00730 PACMDRVSTREAMHEADER padsh;
00731
00732 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
00733
00734 if ((was = ACM_GetStream(has)) == NULL)
00735 return MMSYSERR_INVALHANDLE;
00736 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
00737 return MMSYSERR_INVALPARAM;
00738
00739 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
00740 return ACMERR_UNPREPARED;
00741
00742
00743
00744
00745
00746 padsh = (PACMDRVSTREAMHEADER)pash;
00747
00748
00749 if (padsh->pbPreparedSrc != padsh->pbSrc ||
00750 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
00751 padsh->pbPreparedDst != padsh->pbDst ||
00752 padsh->cbPreparedDstLength < padsh->cbDstLength) {
00753 return MMSYSERR_INVALPARAM;
00754 }
00755
00756 padsh->fdwConvert = fdwUnprepare;
00757
00758 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
00759 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
00760 ret = MMSYSERR_NOERROR;
00761 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
00762 }
00763 TRACE("=> (%d)\n", ret);
00764 return ret;
00765 }