[MSACM32] Sync with Wine Staging 3.3. CORE-14434
[reactos.git] / dll / win32 / msacm32 / stream.c
index 3fef76f..e06503a 100644 (file)
  *     + properly close ACM streams
  */
 
-#define WIN32_NO_STATUS
-
-//#include <stdarg.h>
-//#include <string.h>
-//#include "windef.h"
-//#include "winbase.h"
-//#include "winerror.h"
-#include <wine/debug.h>
-//#include "mmsystem.h"
+#include <stdarg.h>
+#include <string.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "mmsystem.h"
 #define NOBITMAP
-//#include "mmreg.h"
-//#include "msacm.h"
-#include <msacmdrv.h>
+#include "mmreg.h"
+#include "msacm.h"
+#include "msacmdrv.h"
 #include "wineacm.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msacm);
@@ -52,6 +50,15 @@ static PWINE_ACMSTREAM       ACM_GetStream(HACMSTREAM has)
     return (PWINE_ACMSTREAM)has;
 }
 
+static BOOL ACM_ValidatePointers(PACMDRVSTREAMHEADER padsh)
+{
+    /* check that pointers have not been modified */
+    return !(padsh->pbPreparedSrc != padsh->pbSrc ||
+             padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
+             padsh->pbPreparedDst != padsh->pbDst ||
+             padsh->cbPreparedDstLength < padsh->cbDstLength);
+}
+
 /***********************************************************************
  *           acmStreamClose (MSACM32.@)
  */
@@ -110,13 +117,9 @@ MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
      */
     padsh = (PACMDRVSTREAMHEADER)pash;
 
-    /* check that pointers have not been modified */
-    if (padsh->pbPreparedSrc != padsh->pbSrc ||
-       padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
-       padsh->pbPreparedDst != padsh->pbDst ||
-       padsh->cbPreparedDstLength < padsh->cbDstLength) {
+    if (!ACM_ValidatePointers(padsh)) {
         WARN("invalid parameter\n");
-       return MMSYSERR_INVALPARAM;
+        return MMSYSERR_INVALPARAM;
     }
 
     padsh->fdwConvert = fdwConvert;
@@ -259,6 +262,7 @@ MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had,
                TRACE("%s => %08x\n", debugstr_w(wadi->pszDriverAlias), ret);
                if (ret == MMSYSERR_NOERROR) {
                    if (fdwOpen & ACM_STREAMOPENF_QUERY) {
+                       MSACM_Message((HACMDRIVER)wad, ACMDM_STREAM_CLOSE, (LPARAM)&was->drvInst, 0);
                        acmDriverClose(had, 0L);
                    }
                    break;
@@ -303,17 +307,23 @@ MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
 
     if ((was = ACM_GetStream(has)) == NULL) {
         WARN("invalid handle\n");
-       return MMSYSERR_INVALHANDLE;
+        return MMSYSERR_INVALHANDLE;
     }
     if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) {
         WARN("invalid parameter\n");
-       return MMSYSERR_INVALPARAM;
+        return MMSYSERR_INVALPARAM;
+    }
+    if (fdwPrepare) {
+        WARN("invalid use of reserved parameter\n");
+        return MMSYSERR_INVALFLAG;
+    }
+    if ((was->drvInst.pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM ||
+         was->drvInst.pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) &&
+        pash->cbSrcLength < was->drvInst.pwfxSrc->nBlockAlign) {
+        WARN("source smaller than block align (%d < %d)\n",
+             pash->cbSrcLength, was->drvInst.pwfxSrc->nBlockAlign);
+        return pash->cbSrcLength ? ACMERR_NOTPOSSIBLE : MMSYSERR_INVALPARAM;
     }
-    if (fdwPrepare)
-       ret = MMSYSERR_INVALFLAG;
-
-    if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
-       return MMSYSERR_NOERROR;
 
     /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
      * size. some fields are private to msacm internals, and are exposed
@@ -335,7 +345,7 @@ MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
     ret = MSACM_Message((HACMDRIVER)was->pDrv, ACMDM_STREAM_PREPARE, (LPARAM)&was->drvInst, (LPARAM)padsh);
     if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
        ret = MMSYSERR_NOERROR;
-       padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
+       padsh->fdwStatus &= ~ACMSTREAMHEADER_STATUSF_INQUEUE;
        padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
        padsh->fdwPrepared = padsh->fdwStatus;
        padsh->dwPrepared = 0;
@@ -464,13 +474,9 @@ MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
      */
     padsh = (PACMDRVSTREAMHEADER)pash;
 
-    /* check that pointers have not been modified */
-    if (padsh->pbPreparedSrc != padsh->pbSrc ||
-       padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
-       padsh->pbPreparedDst != padsh->pbDst ||
-       padsh->cbPreparedDstLength < padsh->cbDstLength) {
+    if (!ACM_ValidatePointers(padsh)) {
         WARN("invalid parameter\n");
-       return MMSYSERR_INVALPARAM;
+        return MMSYSERR_INVALPARAM;
     }
 
     padsh->fdwConvert = fdwUnprepare;
@@ -478,7 +484,7 @@ MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
     ret = MSACM_Message((HACMDRIVER)was->pDrv, ACMDM_STREAM_UNPREPARE, (LPARAM)&was->drvInst, (LPARAM)padsh);
     if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
        ret = MMSYSERR_NOERROR;
-       padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
+       padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
     }
     TRACE("=> (%d)\n", ret);
     return ret;