/*
 * Copyright 2002 Michael Günnewig
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS
#include <assert.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "winerror.h"
#include "mmsystem.h"
#include "vfw.h"
#include "msacm.h"

#include "avifile_private.h"
#include "extrachunk.h"

#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(avifile);

/***********************************************************************/

#define formtypeWAVE    mmioFOURCC('W','A','V','E')
#define ckidWAVEFORMAT  mmioFOURCC('f','m','t',' ')
#define ckidWAVEFACT    mmioFOURCC('f','a','c','t')
#define ckidWAVEDATA    mmioFOURCC('d','a','t','a')

/***********************************************************************/

#define ENDIAN_SWAPWORD(x)  ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8))
#define ENDIAN_SWAPDWORD(x) (ENDIAN_SWAPWORD((x >> 16) & 0xFFFF) | \
                             ENDIAN_SWAPWORD(x & 0xFFFF) << 16)

#ifdef WORDS_BIGENDIAN
#define BE2H_WORD(x)  (x)
#define BE2H_DWORD(x) (x)
#define LE2H_WORD(x)  ENDIAN_SWAPWORD(x)
#define LE2H_DWORD(x) ENDIAN_SWAPDWORD(x)
#else
#define BE2H_WORD(x)  ENDIAN_SWAPWORD(x)
#define BE2H_DWORD(x) ENDIAN_SWAPDWORD(x)
#define LE2H_WORD(x)  (x)
#define LE2H_DWORD(x) (x)
#endif

typedef struct {
  FOURCC  fccType;
  DWORD   offset;
  DWORD   size;
  INT     encoding;
  DWORD   sampleRate;
  DWORD   channels;
} SUNAUDIOHEADER;

#define AU_ENCODING_ULAW_8                 1
#define AU_ENCODING_PCM_8                  2
#define AU_ENCODING_PCM_16                 3
#define AU_ENCODING_PCM_24                 4
#define AU_ENCODING_PCM_32                 5
#define AU_ENCODING_FLOAT                  6
#define AU_ENCODING_DOUBLE                 7
#define AU_ENCODING_ADPCM_G721_32         23
#define AU_ENCODING_ADPCM_G722            24
#define AU_ENCODING_ADPCM_G723_24         25
#define AU_ENCODING_ADPCM_G723_5          26
#define AU_ENCODING_ALAW_8                27

/***********************************************************************/

typedef struct _IAVIFileImpl {
  IUnknown          IUnknown_inner;
  IAVIFile          IAVIFile_iface;
  IPersistFile      IPersistFile_iface;
  IAVIStream        IAVIStream_iface;
  IUnknown          *outer_unk;
  LONG              ref;
  /* IAVIFile, IAVIStream stuff... */
  AVIFILEINFOW      fInfo;
  AVISTREAMINFOW    sInfo;

  LPWAVEFORMATEX    lpFormat;
  LONG              cbFormat;

  MMCKINFO          ckData;

  EXTRACHUNKS       extra;

  /* IPersistFile stuff ... */
  HMMIO             hmmio;
  LPWSTR            szFileName;
  UINT              uMode;
  BOOL              fDirty;
} IAVIFileImpl;

/***********************************************************************/

static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This);
static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This);
static HRESULT AVIFILE_SaveFile(const IAVIFileImpl *This);

static inline IAVIFileImpl *impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, IAVIFileImpl, IUnknown_inner);
}

static HRESULT WINAPI IUnknown_fnQueryInterface(IUnknown *iface, REFIID riid, void **ret_iface)
{
    IAVIFileImpl *This = impl_from_IUnknown(iface);

    TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ret_iface);

    if (IsEqualGUID(&IID_IUnknown, riid))
        *ret_iface = &This->IUnknown_inner;
    else if (IsEqualGUID(&IID_IAVIFile, riid))
        *ret_iface = &This->IAVIFile_iface;
    else if (IsEqualGUID(&IID_IAVIStream, riid))
        *ret_iface = &This->IAVIStream_iface;
    else if (IsEqualGUID(&IID_IPersistFile, riid))
        *ret_iface = &This->IPersistFile_iface;
    else {
        WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ret_iface);
        *ret_iface = NULL;
        return E_NOINTERFACE;
    }

    /* Violation of the COM aggregation ref counting rule */
    IUnknown_AddRef(&This->IUnknown_inner);
    return S_OK;
}

static ULONG WINAPI IUnknown_fnAddRef(IUnknown *iface)
{
    IAVIFileImpl *This = impl_from_IUnknown(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI IUnknown_fnRelease(IUnknown *iface)
{
    IAVIFileImpl *This = impl_from_IUnknown(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if (!ref) {
        /* need to write headers to file */
        if (This->fDirty)
            AVIFILE_SaveFile(This);

        HeapFree(GetProcessHeap(), 0, This->lpFormat);
        This->lpFormat = NULL;
        This->cbFormat = 0;
        HeapFree(GetProcessHeap(), 0, This->extra.lp);
        This->extra.lp = NULL;
        This->extra.cb = 0;
        HeapFree(GetProcessHeap(), 0, This->szFileName);
        This->szFileName = NULL;
        if (This->hmmio) {
            mmioClose(This->hmmio, 0);
            This->hmmio = NULL;
        }
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static const IUnknownVtbl unk_vtbl =
{
    IUnknown_fnQueryInterface,
    IUnknown_fnAddRef,
    IUnknown_fnRelease
};

static inline IAVIFileImpl *impl_from_IAVIFile(IAVIFile *iface)
{
    return CONTAINING_RECORD(iface, IAVIFileImpl, IAVIFile_iface);
}

static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile *iface, REFIID riid, void **ret_iface)
{
    IAVIFileImpl *This = impl_from_IAVIFile(iface);

    return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface);
}

static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile *iface)
{
    IAVIFileImpl *This = impl_from_IAVIFile(iface);

    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI IAVIFile_fnRelease(IAVIFile *iface)
{
    IAVIFileImpl *This = impl_from_IAVIFile(iface);

    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile *iface, AVIFILEINFOW *afi, LONG size)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,%p,%d)\n",iface,afi,size);

  if (afi == NULL)
    return AVIERR_BADPARAM;
  if (size < 0)
    return AVIERR_BADSIZE;

  /* update file info */
  This->fInfo.dwFlags = 0;
  This->fInfo.dwCaps  = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
  if (This->lpFormat != NULL) {
    assert(This->sInfo.dwScale != 0);

    This->fInfo.dwStreams             = 1;
    This->fInfo.dwScale               = This->sInfo.dwScale;
    This->fInfo.dwRate                = This->sInfo.dwRate;
    This->fInfo.dwLength              = This->sInfo.dwLength;
    This->fInfo.dwSuggestedBufferSize = This->ckData.cksize;
    This->fInfo.dwMaxBytesPerSec =
      MulDiv(This->sInfo.dwSampleSize,This->sInfo.dwRate,This->sInfo.dwScale);
  }

  memcpy(afi, &This->fInfo, min((DWORD)size, sizeof(This->fInfo)));

  if ((DWORD)size < sizeof(This->fInfo))
    return AVIERR_BUFFERTOOSMALL;
  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile *iface, IAVIStream **avis, DWORD fccType,
        LONG lParam)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,%p,0x%08X,%d)\n", iface, avis, fccType, lParam);

  /* check parameter */
  if (avis == NULL)
    return AVIERR_BADPARAM;

  *avis = NULL;

  /* Does our stream exists? */
  if (lParam != 0 || This->fInfo.dwStreams == 0)
    return AVIERR_NODATA;
  if (fccType != 0 && fccType != streamtypeAUDIO)
    return AVIERR_NODATA;

  *avis = &This->IAVIStream_iface;
  IAVIStream_AddRef(*avis);

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile *iface, IAVIStream **avis,
        AVISTREAMINFOW *asi)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,%p,%p)\n", iface, avis, asi);

  /* check parameters */
  if (avis == NULL || asi == NULL)
    return AVIERR_BADPARAM;

  *avis = NULL;

  /* We only support one audio stream */
  if (This->fInfo.dwStreams != 0 || This->lpFormat != NULL)
    return AVIERR_UNSUPPORTED;
  if (asi->fccType != streamtypeAUDIO)
    return AVIERR_UNSUPPORTED;

  /* Does the user have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  This->cbFormat = 0;
  This->lpFormat = NULL;

  memcpy(&This->sInfo, asi, sizeof(This->sInfo));

  /* make sure streaminfo if okay for us */
  This->sInfo.fccHandler          = 0;
  This->sInfo.dwFlags             = 0;
  This->sInfo.dwCaps              = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
  This->sInfo.dwStart             = 0;
  This->sInfo.dwInitialFrames     = 0;
  This->sInfo.dwFormatChangeCount = 0;
  memset(&This->sInfo.rcFrame, 0, sizeof(This->sInfo.rcFrame));

  This->fInfo.dwStreams = 1;
  This->fInfo.dwScale   = This->sInfo.dwScale;
  This->fInfo.dwRate    = This->sInfo.dwRate;
  This->fInfo.dwLength  = This->sInfo.dwLength;

  This->ckData.dwDataOffset = 0;
  This->ckData.cksize       = 0;

  *avis = &This->IAVIStream_iface;
  IAVIStream_AddRef(*avis);

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile *iface, DWORD ckid, void *lpData, LONG size)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,0x%08X,%p,%d)\n", iface, ckid, lpData, size);

  /* check parameters */
  if (lpData == NULL)
    return AVIERR_BADPARAM;
  if (size < 0)
    return AVIERR_BADSIZE;

  /* Do we have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  This->fDirty = TRUE;

  return WriteExtraChunk(&This->extra, ckid, lpData, size);
}

static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile *iface, DWORD ckid, void *lpData, LONG *size)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,0x%08X,%p,%p)\n", iface, ckid, lpData, size);

  return ReadExtraChunk(&This->extra, ckid, lpData, size);
}

static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile *iface)
{
  TRACE("(%p)\n",iface);

  /* This is only needed for interleaved files.
   * We have only one stream, which can't be interleaved.
   */
  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile *iface, DWORD fccType, LONG lParam)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,0x%08X,%d)\n", iface, fccType, lParam);

  /* check parameter */
  if (lParam < 0)
    return AVIERR_BADPARAM;

  /* Do we have our audio stream? */
  if (lParam != 0 || This->fInfo.dwStreams == 0 ||
      (fccType != 0 && fccType != streamtypeAUDIO))
    return AVIERR_NODATA;

  /* Have user write permissions? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  HeapFree(GetProcessHeap(), 0, This->lpFormat);
  This->lpFormat = NULL;
  This->cbFormat = 0;

  /* update infos */
  This->ckData.dwDataOffset = 0;
  This->ckData.cksize       = 0;

  This->sInfo.dwScale   = 0;
  This->sInfo.dwRate    = 0;
  This->sInfo.dwLength  = 0;
  This->sInfo.dwSuggestedBufferSize = 0;

  This->fInfo.dwStreams = 0;
  This->fInfo.dwEditCount++;

  This->fDirty = TRUE;

  return AVIERR_OK;
}

static const struct IAVIFileVtbl iwavft = {
    IAVIFile_fnQueryInterface,
    IAVIFile_fnAddRef,
    IAVIFile_fnRelease,
    IAVIFile_fnInfo,
    IAVIFile_fnGetStream,
    IAVIFile_fnCreateStream,
    IAVIFile_fnWriteData,
    IAVIFile_fnReadData,
    IAVIFile_fnEndRecord,
    IAVIFile_fnDeleteStream
};

/***********************************************************************/

static inline IAVIFileImpl *impl_from_IPersistFile(IPersistFile *iface)
{
    return CONTAINING_RECORD(iface, IAVIFileImpl, IPersistFile_iface);
}

static HRESULT WINAPI IPersistFile_fnQueryInterface(IPersistFile *iface, REFIID riid,
        void **ret_iface)
{
    IAVIFileImpl *This = impl_from_IPersistFile(iface);

    return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface);
}

static ULONG   WINAPI IPersistFile_fnAddRef(IPersistFile *iface)
{
    IAVIFileImpl *This = impl_from_IPersistFile(iface);

    return IUnknown_AddRef(This->outer_unk);
}

static ULONG   WINAPI IPersistFile_fnRelease(IPersistFile *iface)
{
    IAVIFileImpl *This = impl_from_IPersistFile(iface);

    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile *iface,
						LPCLSID pClassID)
{
  TRACE("(%p,%p)\n", iface, pClassID);

  if (pClassID == NULL)
    return AVIERR_BADPARAM;

  *pClassID = CLSID_WAVFile;

  return AVIERR_OK;
}

static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile *iface)
{
    IAVIFileImpl *This = impl_from_IPersistFile(iface);

    TRACE("(%p)\n", iface);

    return (This->fDirty ? S_OK : S_FALSE);
}

static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, LPCOLESTR pszFileName, DWORD dwMode)
{
  IAVIFileImpl *This = impl_from_IPersistFile(iface);
  WCHAR wszStreamFmt[50];
  INT   len;

  TRACE("(%p,%s,0x%08X)\n", iface, debugstr_w(pszFileName), dwMode);

  /* check parameter */
  if (pszFileName == NULL)
    return AVIERR_BADPARAM;

  if (This->hmmio != NULL)
    return AVIERR_ERROR; /* No reuse of this object for another file! */

  /* remember mode and name */
  This->uMode = dwMode;

  len = lstrlenW(pszFileName) + 1;
  This->szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
  if (This->szFileName == NULL)
    return AVIERR_MEMORY;
  lstrcpyW(This->szFileName, pszFileName);

  /* try to open the file */
  This->hmmio = mmioOpenW(This->szFileName, NULL, MMIO_ALLOCBUF | dwMode);
  if (This->hmmio == NULL) {
    /* mmioOpenW not in native DLLs of Win9x -- try mmioOpenA */
    LPSTR szFileName;
    len = WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1,
                              NULL, 0, NULL, NULL);
    szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR));
    if (szFileName == NULL)
      return AVIERR_MEMORY;

    WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, szFileName,
			len, NULL, NULL);

    This->hmmio = mmioOpenA(szFileName, NULL, MMIO_ALLOCBUF | dwMode);
    HeapFree(GetProcessHeap(), 0, szFileName);
    if (This->hmmio == NULL)
      return AVIERR_FILEOPEN;
  }

  memset(& This->fInfo, 0, sizeof(This->fInfo));
  memset(& This->sInfo, 0, sizeof(This->sInfo));

  LoadStringW(AVIFILE_hModule, IDS_WAVEFILETYPE, This->fInfo.szFileType,
	      sizeof(This->fInfo.szFileType)/sizeof(This->fInfo.szFileType[0]));
  if (LoadStringW(AVIFILE_hModule, IDS_WAVESTREAMFORMAT,
		  wszStreamFmt, sizeof(wszStreamFmt)/sizeof(wszStreamFmt[0])) > 0) {
    wsprintfW(This->sInfo.szName, wszStreamFmt,
	      AVIFILE_BasenameW(This->szFileName));
  }

  /* should we create a new file? */
  if (dwMode & OF_CREATE) {
    /* nothing more to do */
    return AVIERR_OK;
  } else
    return AVIFILE_LoadFile(This);
}

static HRESULT WINAPI IPersistFile_fnSave(IPersistFile *iface,
					  LPCOLESTR pszFileName,BOOL fRemember)
{
  TRACE("(%p,%s,%d)\n", iface, debugstr_w(pszFileName), fRemember);

  /* We write directly to disk, so nothing to do. */

  return AVIERR_OK;
}

static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile *iface,
						   LPCOLESTR pszFileName)
{
  TRACE("(%p,%s)\n", iface, debugstr_w(pszFileName));

  /* We write directly to disk, so nothing to do. */

  return AVIERR_OK;
}

static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile *iface, LPOLESTR *ppszFileName)
{
  IAVIFileImpl *This = impl_from_IPersistFile(iface);

  TRACE("(%p,%p)\n", iface, ppszFileName);

  if (ppszFileName == NULL)
    return AVIERR_BADPARAM;

  *ppszFileName = NULL;

  if (This->szFileName) {
    int len = lstrlenW(This->szFileName) + 1;

    *ppszFileName = CoTaskMemAlloc(len * sizeof(WCHAR));
    if (*ppszFileName == NULL)
      return AVIERR_MEMORY;

    strcpyW(*ppszFileName, This->szFileName);
  }

  return AVIERR_OK;
}

static const struct IPersistFileVtbl iwavpft = {
    IPersistFile_fnQueryInterface,
    IPersistFile_fnAddRef,
    IPersistFile_fnRelease,
    IPersistFile_fnGetClassID,
    IPersistFile_fnIsDirty,
    IPersistFile_fnLoad,
    IPersistFile_fnSave,
    IPersistFile_fnSaveCompleted,
    IPersistFile_fnGetCurFile
};

/***********************************************************************/

static inline IAVIFileImpl *impl_from_IAVIStream(IAVIStream *iface)
{
    return CONTAINING_RECORD(iface, IAVIFileImpl, IAVIStream_iface);
}

static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream *iface, REFIID riid, void **ret_iface)
{
    IAVIFileImpl *This = impl_from_IAVIStream(iface);

    return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface);
}

static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream *iface)
{
    IAVIFileImpl *This = impl_from_IAVIStream(iface);

    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface)
{
    IAVIFileImpl *This = impl_from_IAVIStream(iface);

    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream *iface, LPARAM lParam1,
					  LPARAM lParam2)
{
  TRACE("(%p,0x%08lX,0x%08lX)\n", iface, lParam1, lParam2);

  /* This IAVIStream interface needs an WAVFile */
  return AVIERR_UNSUPPORTED;
}

static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream *iface, AVISTREAMINFOW *psi, LONG size)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%p,%d)\n", iface, psi, size);

  if (psi == NULL)
    return AVIERR_BADPARAM;
  if (size < 0)
    return AVIERR_BADSIZE;

  memcpy(psi, &This->sInfo, min((DWORD)size, sizeof(This->sInfo)));

  if ((DWORD)size < sizeof(This->sInfo))
    return AVIERR_BUFFERTOOSMALL;
  return AVIERR_OK;
}

static LONG WINAPI IAVIStream_fnFindSample(IAVIStream *iface, LONG pos, LONG flags)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%d,0x%08X)\n",iface,pos,flags);

  /* Do we have data? */
  if (This->lpFormat == NULL)
    return -1;

  /* We don't have an index */
  if (flags & FIND_INDEX)
    return -1;

  if (flags & FIND_FROM_START) {
    pos = This->sInfo.dwStart;
    flags &= ~(FIND_FROM_START|FIND_PREV);
    flags |= FIND_NEXT;
  }

  if (flags & FIND_FORMAT) {
    if ((flags & FIND_NEXT) && pos > 0)
      pos = -1;
    else
      pos = 0;
  }

  if ((flags & FIND_RET) == FIND_LENGTH ||
      (flags & FIND_RET) == FIND_SIZE)
    return This->sInfo.dwSampleSize;
  if ((flags & FIND_RET) == FIND_OFFSET)
    return This->ckData.dwDataOffset + pos * This->sInfo.dwSampleSize;

  return pos;
}

static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream *iface, LONG pos, void *format,
        LONG *formatsize)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%d,%p,%p)\n", iface, pos, format, formatsize);

  if (formatsize == NULL)
    return AVIERR_BADPARAM;

  /* only interested in needed buffersize? */
  if (format == NULL || *formatsize <= 0) {
    *formatsize = This->cbFormat;

    return AVIERR_OK;
  }

  /* copy initial format (only as much as will fit) */
  memcpy(format, This->lpFormat, min(*formatsize, This->cbFormat));
  if (*formatsize < This->cbFormat) {
    *formatsize = This->cbFormat;
    return AVIERR_BUFFERTOOSMALL;
  }

  *formatsize = This->cbFormat;
  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos, void *format,
        LONG formatsize)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%d,%p,%d)\n", iface, pos, format, formatsize);

  /* check parameters */
  if (format == NULL || formatsize <= sizeof(PCMWAVEFORMAT))
    return AVIERR_BADPARAM;

  /* We can only do this to an empty wave file, but ignore call
   * if still same format */
  if (This->lpFormat != NULL) {
    if (formatsize != This->cbFormat ||
	memcmp(format, This->lpFormat, formatsize) != 0)
      return AVIERR_UNSUPPORTED;

    return AVIERR_OK;
  }

  /* only support start at position 0 */
  if (pos != 0)
    return AVIERR_UNSUPPORTED;

  /* Do we have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  /* get memory for format and copy it */
  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, formatsize);
  if (This->lpFormat == NULL)
    return AVIERR_MEMORY;

  This->cbFormat = formatsize;
  memcpy(This->lpFormat, format, formatsize);

  /* update info's about 'data' chunk */
  This->ckData.dwDataOffset = formatsize + 7 * sizeof(DWORD);
  This->ckData.cksize       = 0;

  /* for non-pcm format we need also a 'fact' chunk */
  if (This->lpFormat->wFormatTag != WAVE_FORMAT_PCM)
    This->ckData.dwDataOffset += 3 * sizeof(DWORD);

  /* update stream and file info */
  This->sInfo.dwSampleSize = This->lpFormat->nBlockAlign;
  This->sInfo.dwScale      = This->lpFormat->nBlockAlign;
  This->sInfo.dwRate       = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwLength     = 0;
  This->sInfo.dwSuggestedBufferSize = 0;

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnRead(IAVIStream *iface, LONG start, LONG samples, void *buffer,
        LONG buffersize, LONG *bytesread, LONG *samplesread)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", iface, start, samples, buffer,
	buffersize, bytesread, samplesread);

  /* clear return parameters if given */
  if (bytesread != NULL)
    *bytesread = 0;
  if (samplesread != NULL)
    *samplesread = 0;

  /* positions without data */
  if (start < 0 || (DWORD)start > This->sInfo.dwLength)
    return AVIERR_OK;

  /* check samples */
  if (samples < 0)
    samples = 0;
  if (buffersize > 0) {
    if (samples > 0)
      samples = min((DWORD)samples, buffersize / This->sInfo.dwSampleSize);
    else
      samples = buffersize / This->sInfo.dwSampleSize;
  }

  /* limit to end of stream */
  if ((DWORD)(start + samples) > This->sInfo.dwLength)
    samples = This->sInfo.dwLength - start;

  /* request only the sizes? */
  if (buffer == NULL || buffersize <= 0) {
    /* then I need at least one parameter for it */
    if (bytesread == NULL && samplesread == NULL)
      return AVIERR_BADPARAM;

    if (bytesread != NULL)
      *bytesread = samples * This->sInfo.dwSampleSize;
    if (samplesread != NULL)
      *samplesread = samples;

    return AVIERR_OK;
  }

  /* nothing to read? */
  if (samples == 0)
    return AVIERR_OK;

  /* Can I read at least one sample? */
  if ((DWORD)buffersize < This->sInfo.dwSampleSize)
    return AVIERR_BUFFERTOOSMALL;

  buffersize = samples * This->sInfo.dwSampleSize;

  if (mmioSeek(This->hmmio, This->ckData.dwDataOffset
	       + start * This->sInfo.dwSampleSize, SEEK_SET) == -1)
    return AVIERR_FILEREAD;
  if (mmioRead(This->hmmio, buffer, buffersize) != buffersize)
    return AVIERR_FILEREAD;

  /* fill out return parameters if given */
  if (bytesread != NULL)
    *bytesread = buffersize;
  if (samplesread != NULL)
    *samplesread = samples;  

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream *iface, LONG start, LONG samples, void *buffer,
        LONG buffersize, DWORD flags, LONG *sampwritten, LONG *byteswritten)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%d,%d,%p,%d,0x%08X,%p,%p)\n", iface, start, samples,
	buffer, buffersize, flags, sampwritten, byteswritten);

  /* clear return parameters if given */
  if (sampwritten != NULL)
    *sampwritten = 0;
  if (byteswritten != NULL)
    *byteswritten = 0;

  /* check parameters */
  if (buffer == NULL && (buffersize > 0 || samples > 0))
    return AVIERR_BADPARAM;

  /* Do we have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  /* < 0 means "append" */
  if (start < 0)
    start = This->sInfo.dwStart + This->sInfo.dwLength;

  /* check buffersize -- must multiple of samplesize */
  if (buffersize & ~(This->sInfo.dwSampleSize - 1))
    return AVIERR_BADSIZE;

  /* do we have anything to write? */
  if (buffer != NULL && buffersize > 0) {
    This->fDirty = TRUE;

    if (mmioSeek(This->hmmio, This->ckData.dwDataOffset +
		 start * This->sInfo.dwSampleSize, SEEK_SET) == -1)
      return AVIERR_FILEWRITE;
    if (mmioWrite(This->hmmio, buffer, buffersize) != buffersize)
      return AVIERR_FILEWRITE;

    This->sInfo.dwLength = max(This->sInfo.dwLength, (DWORD)start + samples);
    This->ckData.cksize  = max(This->ckData.cksize,
			       start * This->sInfo.dwSampleSize + buffersize);

    /* fill out return parameters if given */
    if (sampwritten != NULL)
      *sampwritten = samples;
    if (byteswritten != NULL)
      *byteswritten = buffersize;
  }

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream *iface, LONG start, LONG samples)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%d,%d)\n", iface, start, samples);

  /* check parameters */
  if (start < 0 || samples < 0)
    return AVIERR_BADPARAM;

  /* Delete before start of stream? */
  if ((DWORD)(start + samples) < This->sInfo.dwStart)
    return AVIERR_OK;

  /* Delete after end of stream? */
  if ((DWORD)start > This->sInfo.dwLength)
    return AVIERR_OK;

  /* For the rest we need write permissions */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  if ((DWORD)(start + samples) >= This->sInfo.dwLength) {
    /* deletion at end */
    samples = This->sInfo.dwLength - start;
    This->sInfo.dwLength -= samples;
    This->ckData.cksize  -= samples * This->sInfo.dwSampleSize;
  } else if ((DWORD)start <= This->sInfo.dwStart) {
    /* deletion at start */
    samples = This->sInfo.dwStart - start;
    start   = This->sInfo.dwStart;
    This->ckData.dwDataOffset += samples * This->sInfo.dwSampleSize;
    This->ckData.cksize       -= samples * This->sInfo.dwSampleSize;
  } else {
    /* deletion inside stream -- needs playlist and cue's */
    FIXME(": deletion inside of stream not supported!\n");

    return AVIERR_UNSUPPORTED;
  }

  This->fDirty = TRUE;

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream *iface, DWORD fcc, void *lp, LONG *lpread)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  return IAVIFile_ReadData(&This->IAVIFile_iface, fcc, lp, lpread);
}

static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream *iface, DWORD fcc, void *lp, LONG size)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  return IAVIFile_WriteData(&This->IAVIFile_iface, fcc, lp, size);
}

static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream *iface,
					   LPAVISTREAMINFOW info, LONG infolen)
{
  FIXME("(%p,%p,%d): stub\n", iface, info, infolen);

  return E_FAIL;
}

static const struct IAVIStreamVtbl iwavst = {
    IAVIStream_fnQueryInterface,
    IAVIStream_fnAddRef,
    IAVIStream_fnRelease,
    IAVIStream_fnCreate,
    IAVIStream_fnInfo,
    IAVIStream_fnFindSample,
    IAVIStream_fnReadFormat,
    IAVIStream_fnSetFormat,
    IAVIStream_fnRead,
    IAVIStream_fnWrite,
    IAVIStream_fnDelete,
    IAVIStream_fnReadData,
    IAVIStream_fnWriteData,
    IAVIStream_fnSetInfo
};

HRESULT AVIFILE_CreateWAVFile(IUnknown *outer_unk, REFIID riid, void **ret_iface)
{
    IAVIFileImpl *pfile;
    HRESULT hr;

    *ret_iface = NULL;

    pfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pfile));
    if (!pfile)
        return AVIERR_MEMORY;

    pfile->IUnknown_inner.lpVtbl = &unk_vtbl;
    pfile->IAVIFile_iface.lpVtbl = &iwavft;
    pfile->IPersistFile_iface.lpVtbl = &iwavpft;
    pfile->IAVIStream_iface.lpVtbl = &iwavst;
    pfile->ref = 1;
    if (outer_unk)
        pfile->outer_unk = outer_unk;
    else
        pfile->outer_unk = &pfile->IUnknown_inner;

    hr = IUnknown_QueryInterface(&pfile->IUnknown_inner, riid, ret_iface);
    IUnknown_Release(&pfile->IUnknown_inner);

    return hr;
}

/***********************************************************************/

static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This)
{
  MMCKINFO ckRIFF;
  MMCKINFO ck;

  This->sInfo.dwLength = 0; /* just to be sure */
  This->fDirty = FALSE;

  /* search for RIFF chunk */
  ckRIFF.fccType = 0; /* find any */
  if (mmioDescend(This->hmmio, &ckRIFF, NULL, MMIO_FINDRIFF) != S_OK) {
    return AVIFILE_LoadSunFile(This);
  }

  if (ckRIFF.fccType != formtypeWAVE)
    return AVIERR_BADFORMAT;

  /* search WAVE format chunk */
  ck.ckid = ckidWAVEFORMAT;
  if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck,
			     &ckRIFF, MMIO_FINDCHUNK) != S_OK)
    return AVIERR_FILEREAD;

  /* get memory for format and read it */
  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, ck.cksize);
  if (This->lpFormat == NULL)
    return AVIERR_FILEREAD;
  This->cbFormat = ck.cksize;

  if (mmioRead(This->hmmio, (HPSTR)This->lpFormat, ck.cksize) != ck.cksize)
    return AVIERR_FILEREAD;
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEREAD;

  /* Non-pcm formats have a fact chunk.
   * We don't need it, so simply add it to the extra chunks.
   */

  /* find the big data chunk */
  This->ckData.ckid = ckidWAVEDATA;
  if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &This->ckData,
			     &ckRIFF, MMIO_FINDCHUNK) != S_OK)
    return AVIERR_FILEREAD;

  memset(&This->sInfo, 0, sizeof(This->sInfo));
  This->sInfo.fccType      = streamtypeAUDIO;
  This->sInfo.dwRate       = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwSampleSize =
    This->sInfo.dwScale    = This->lpFormat->nBlockAlign;
  This->sInfo.dwLength     = This->ckData.cksize / This->lpFormat->nBlockAlign;
  This->sInfo.dwSuggestedBufferSize = This->ckData.cksize;

  This->fInfo.dwStreams = 1;

  if (mmioAscend(This->hmmio, &This->ckData, 0) != S_OK) {
    /* seems to be truncated */
    WARN(": file seems to be truncated!\n");
    This->ckData.cksize  = mmioSeek(This->hmmio, 0, SEEK_END) -
      This->ckData.dwDataOffset;
    This->sInfo.dwLength = This->ckData.cksize / This->lpFormat->nBlockAlign;
    This->sInfo.dwSuggestedBufferSize = This->ckData.cksize;
  }

  /* ignore errors */
  FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck, &ckRIFF, 0);

  return AVIERR_OK;
}

static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This)
{
  SUNAUDIOHEADER auhdr;

  mmioSeek(This->hmmio, 0, SEEK_SET);
  if (mmioRead(This->hmmio, (HPSTR)&auhdr, sizeof(auhdr)) != sizeof(auhdr))
    return AVIERR_FILEREAD;

  if (auhdr.fccType == 0x0064732E) {
    /* header in little endian */
    This->ckData.dwDataOffset = LE2H_DWORD(auhdr.offset);
    This->ckData.cksize       = LE2H_DWORD(auhdr.size);

    auhdr.encoding   = LE2H_DWORD(auhdr.encoding);
    auhdr.sampleRate = LE2H_DWORD(auhdr.sampleRate);
    auhdr.channels   = LE2H_DWORD(auhdr.channels);
  } else if (auhdr.fccType == mmioFOURCC('.','s','n','d')) {
    /* header in big endian */
    This->ckData.dwDataOffset = BE2H_DWORD(auhdr.offset);
    This->ckData.cksize       = BE2H_DWORD(auhdr.size);

    auhdr.encoding   = BE2H_DWORD(auhdr.encoding);
    auhdr.sampleRate = BE2H_DWORD(auhdr.sampleRate);
    auhdr.channels   = BE2H_DWORD(auhdr.channels);
  } else
    return AVIERR_FILEREAD;

  if (auhdr.channels < 1)
    return AVIERR_BADFORMAT;

  /* get size of header */
  switch(auhdr.encoding) {
  case AU_ENCODING_ADPCM_G721_32:
    This->cbFormat = sizeof(G721_ADPCMWAVEFORMAT); break;
  case AU_ENCODING_ADPCM_G723_24:
    This->cbFormat = sizeof(G723_ADPCMWAVEFORMAT); break;
  case AU_ENCODING_ADPCM_G722:
  case AU_ENCODING_ADPCM_G723_5:
    WARN("unsupported Sun audio format %d\n", auhdr.encoding);
    return AVIERR_UNSUPPORTED; /* FIXME */
  default:
    This->cbFormat = sizeof(WAVEFORMATEX); break;
  };

  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, This->cbFormat);
  if (This->lpFormat == NULL)
    return AVIERR_MEMORY;

  This->lpFormat->nChannels      = auhdr.channels;
  This->lpFormat->nSamplesPerSec = auhdr.sampleRate;
  switch(auhdr.encoding) {
  case AU_ENCODING_ULAW_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_MULAW;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_PCM_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_PCM_16:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 16;
    break;
  case AU_ENCODING_PCM_24:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 24;
    break;
  case AU_ENCODING_PCM_32:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 32;
    break;
  case AU_ENCODING_ALAW_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_ALAW;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_ADPCM_G721_32:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_G721_ADPCM;
    This->lpFormat->wBitsPerSample = (3*5*8);
    This->lpFormat->nBlockAlign    = 15*15*8;
    This->lpFormat->cbSize         = sizeof(WORD);
    ((LPG721_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
    break;
  case AU_ENCODING_ADPCM_G723_24:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_G723_ADPCM;
    This->lpFormat->wBitsPerSample = (3*5*8);
    This->lpFormat->nBlockAlign    = 15*15*8;
    This->lpFormat->cbSize         = 2*sizeof(WORD);
    ((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->cbExtraSize   = 0;
    ((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
    break;
  default:
    WARN("unsupported Sun audio format %d\n", auhdr.encoding);
    return AVIERR_UNSUPPORTED;
  };

  This->lpFormat->nBlockAlign =
    (This->lpFormat->nChannels * This->lpFormat->wBitsPerSample) / 8;
  if (This->lpFormat->nBlockAlign == 0 && This->lpFormat->wBitsPerSample < 8)
    This->lpFormat->nBlockAlign++;
  This->lpFormat->nAvgBytesPerSec =
    This->lpFormat->nBlockAlign * This->lpFormat->nSamplesPerSec;

  This->fDirty = FALSE;

  This->sInfo.fccType               = streamtypeAUDIO;
  This->sInfo.fccHandler            = 0;
  This->sInfo.dwFlags               = 0;
  This->sInfo.wPriority             = 0;
  This->sInfo.wLanguage             = 0;
  This->sInfo.dwInitialFrames       = 0;
  This->sInfo.dwScale               = This->lpFormat->nBlockAlign;
  This->sInfo.dwRate                = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwStart               = 0;
  This->sInfo.dwLength              =
    This->ckData.cksize / This->lpFormat->nBlockAlign;
  This->sInfo.dwSuggestedBufferSize = This->sInfo.dwLength;
  This->sInfo.dwSampleSize          = This->lpFormat->nBlockAlign;

  This->fInfo.dwStreams = 1;
  This->fInfo.dwScale   = 1;
  This->fInfo.dwRate    = This->lpFormat->nSamplesPerSec;
  This->fInfo.dwLength  =
    MulDiv(This->ckData.cksize, This->lpFormat->nSamplesPerSec,
	   This->lpFormat->nAvgBytesPerSec);

  return AVIERR_OK;
}

static HRESULT AVIFILE_SaveFile(const IAVIFileImpl *This)
{
  MMCKINFO ckRIFF;
  MMCKINFO ck;

  mmioSeek(This->hmmio, 0, SEEK_SET);

  /* create the RIFF chunk with formtype WAVE */
  ckRIFF.fccType = formtypeWAVE;
  ckRIFF.cksize  = 0;
  if (mmioCreateChunk(This->hmmio, &ckRIFF, MMIO_CREATERIFF) != S_OK)
    return AVIERR_FILEWRITE;

  /* the next chunk is the format */
  ck.ckid   = ckidWAVEFORMAT;
  ck.cksize = This->cbFormat;
  if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (This->lpFormat != NULL && This->cbFormat > 0) {
    if (mmioWrite(This->hmmio, (HPSTR)This->lpFormat, ck.cksize) != ck.cksize)
      return AVIERR_FILEWRITE;
  }
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;

  /* fact chunk is needed for non-pcm waveforms */
  if (This->lpFormat != NULL && This->cbFormat > sizeof(PCMWAVEFORMAT) &&
      This->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
    WAVEFORMATEX wfx;
    DWORD        dwFactLength;
    HACMSTREAM   has;

    /* try to open an appropriate audio codec to figure out
     * data for fact-chunk */
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    if (acmFormatSuggest(NULL, This->lpFormat, &wfx,
			 sizeof(wfx), ACM_FORMATSUGGESTF_WFORMATTAG)) {
      acmStreamOpen(&has, NULL, This->lpFormat, &wfx, NULL,
		    0, 0, ACM_STREAMOPENF_NONREALTIME);
      acmStreamSize(has, This->ckData.cksize, &dwFactLength,
		    ACM_STREAMSIZEF_SOURCE);
      dwFactLength /= wfx.nBlockAlign;
      acmStreamClose(has, 0);

      /* create the fact chunk */
      ck.ckid   = ckidWAVEFACT;
      ck.cksize = sizeof(dwFactLength);

      /* test for enough space before data chunk */
      if (mmioSeek(This->hmmio, 0, SEEK_CUR) > This->ckData.dwDataOffset
	  - ck.cksize - 4 * sizeof(DWORD))
	return AVIERR_FILEWRITE;
      if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
	return AVIERR_FILEWRITE;
      if (mmioWrite(This->hmmio, (HPSTR)&dwFactLength, ck.cksize) != ck.cksize)
	return AVIERR_FILEWRITE;
      if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
	return AVIERR_FILEWRITE;
    } else
      ERR(": fact chunk is needed for non-pcm files -- currently no codec found, so skipped!\n");
  }

  /* if there was extra stuff, we need to fill it with JUNK */
  if (mmioSeek(This->hmmio, 0, SEEK_CUR) + 2 * sizeof(DWORD) < This->ckData.dwDataOffset) {
    ck.ckid   = ckidAVIPADDING;
    ck.cksize = 0;
    if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
      return AVIERR_FILEWRITE;

    if (mmioSeek(This->hmmio, This->ckData.dwDataOffset
		 - 2 * sizeof(DWORD), SEEK_SET) == -1)
      return AVIERR_FILEWRITE;
    if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
      return AVIERR_FILEWRITE;
  }

  /* create the data chunk */
  ck.ckid   = ckidWAVEDATA;
  ck.cksize = This->ckData.cksize;
  if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (mmioSeek(This->hmmio, This->ckData.cksize, SEEK_CUR) == -1)
    return AVIERR_FILEWRITE;
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;

  /* some optional extra chunks? */
  if (This->extra.lp != NULL && This->extra.cb > 0) {
    /* chunk headers are already in structure */
    if (mmioWrite(This->hmmio, This->extra.lp, This->extra.cb) != This->extra.cb)
      return AVIERR_FILEWRITE;
  }

  /* close RIFF chunk */
  if (mmioAscend(This->hmmio, &ckRIFF, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (mmioFlush(This->hmmio, 0) != S_OK)
    return AVIERR_FILEWRITE;

  return AVIERR_OK;
}
