[MSACM32] Sync with Wine Staging 3.3. CORE-14434
[reactos.git] / dll / win32 / msacm32 / stream.c
index 44b9729..e06503a 100644 (file)
  *     + properly close ACM streams
  */
 
+#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 "wineacm.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(msacm);
+
 static PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
 {
     TRACE("(%p)\n", has);
@@ -37,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.@)
  */
@@ -95,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;
@@ -289,14 +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;
 
     /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
      * size. some fields are private to msacm internals, and are exposed
@@ -447,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;