/*
 * MMIO functions
 *
 * Copyright 1998 Andrew Taylor
 * Copyright 1998 Ove Kåven
 * Copyright 2000,2002 Eric Pouech
 *
 * 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
 */

/* Still to be done:
 * 	+ correct handling of global/local IOProcs (and temporary IOProcs)
 *	+ mode of mmio objects is not used (read vs write vs readwrite)
 *	+ thread safeness
 *      + 32 A <=> W message mapping
 */


#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>

#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "mmsystem.h"
#include "winemm.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(mmio);

static WINE_MMIO *MMIOList;

/**************************************************************************
 *               	mmioDosIOProc           		[internal]
 */
static LRESULT CALLBACK mmioDosIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage,
				      LPARAM lParam1, LPARAM lParam2)
{
    LRESULT	ret = MMSYSERR_NOERROR;

    TRACE("(%p, %X, 0x%lx, 0x%lx);\n", lpmmioinfo, uMessage, lParam1, lParam2);

    switch (uMessage) {
    case MMIOM_OPEN:
	{
	    /* Parameters:
	     * lParam1 = szFileName parameter from mmioOpen
	     * lParam2 = reserved
	     * Returns: zero on success, error code on error
	     * NOTE: lDiskOffset automatically set to zero
	     */
	    LPCSTR      szFileName = (LPCSTR)lParam1;

	    if (lpmmioinfo->dwFlags & MMIO_GETTEMP) {
		FIXME("MMIO_GETTEMP not implemented\n");
		return MMIOERR_CANNOTOPEN;
	    }

	    /* if filename NULL, assume open file handle in adwInfo[0] */
	    if (szFileName) {
                OFSTRUCT    ofs;
                lpmmioinfo->adwInfo[0] = OpenFile(szFileName, &ofs, lpmmioinfo->dwFlags & 0xFFFF);
            }
	    if (lpmmioinfo->adwInfo[0] == HFILE_ERROR)
		ret = MMIOERR_FILENOTFOUND;
	}
	break;

    case MMIOM_CLOSE:
	/* Parameters:
	 * lParam1 = wFlags parameter from mmioClose
	 * lParam2 = unused
	 * Returns: zero on success, error code on error
	 */
	if (!(lParam1 & MMIO_FHOPEN))
	    _lclose((HFILE)lpmmioinfo->adwInfo[0]);
	break;

    case MMIOM_READ:
	/* Parameters:
	 * lParam1 = huge pointer to read buffer
	 * lParam2 = number of bytes to read
	 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
	 *	   in wErrorRet)
	 */
	ret = _lread((HFILE)lpmmioinfo->adwInfo[0], (HPSTR)lParam1, (LONG)lParam2);
	if (ret != -1)
	    lpmmioinfo->lDiskOffset += ret;

	break;

    case MMIOM_WRITE:
    case MMIOM_WRITEFLUSH:
	/* no internal buffering, so WRITEFLUSH handled same as WRITE */

	/* Parameters:
	 * lParam1 = huge pointer to write buffer
	 * lParam2 = number of bytes to write
	 * Returns: number of bytes written, -1 for error (error code in
	 *		wErrorRet)
	 */
	ret = _hwrite((HFILE)lpmmioinfo->adwInfo[0], (HPSTR)lParam1, (LONG)lParam2);
	if (ret != -1)
	    lpmmioinfo->lDiskOffset += ret;
	break;

    case MMIOM_SEEK:
	/* Parameters:
	 * lParam1 = new position
	 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
	 * Returns: new file position, -1 on error
	 */
	if (lParam2 == SEEK_END)
	    ret = _llseek((HFILE)lpmmioinfo->adwInfo[0], -(LONG)lParam1, (LONG)lParam2);
	else
	    ret = _llseek((HFILE)lpmmioinfo->adwInfo[0], (LONG)lParam1, (LONG)lParam2);
	if (ret != -1)
	    lpmmioinfo->lDiskOffset = ret;
	return ret;

    case MMIOM_RENAME:
	/* Parameters:
	 * lParam1 = old name
	 * lParam2 = new name
	 * Returns: zero on success, non-zero on failure
	 */
 	 if (!MoveFileA((const char*)lParam1, (const char*)lParam2))
	     ret = MMIOERR_FILENOTFOUND;
	 break;

    default:
	FIXME("unexpected message %u\n", uMessage);
	return 0;
    }

    return ret;
}

/**************************************************************************
 *               	mmioMemIOProc           		[internal]
 */
static LRESULT CALLBACK mmioMemIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage,
				      LPARAM lParam1, LPARAM lParam2)
{
    TRACE("(%p,0x%04x,0x%08lx,0x%08lx)\n", lpmmioinfo, uMessage, lParam1, lParam2);

    switch (uMessage) {

    case MMIOM_OPEN:
	/* Parameters:
	 * lParam1 = filename (must be NULL)
	 * lParam2 = reserved
	 * Returns: zero on success, error code on error
	 * NOTE: lDiskOffset automatically set to zero
	 */
	/* FIXME: io proc shouldn't change it */
	if (!(lpmmioinfo->dwFlags & MMIO_CREATE))
	    lpmmioinfo->pchEndRead = lpmmioinfo->pchEndWrite;
        lpmmioinfo->adwInfo[0] = HFILE_ERROR;
	return 0;

    case MMIOM_CLOSE:
	/* Parameters:
	 * lParam1 = wFlags parameter from mmioClose
	 * lParam2 = unused
	 * Returns: zero on success, error code on error
	 */
	return 0;

    case MMIOM_READ:
	/* Parameters:
	 * lParam1 = huge pointer to read buffer
	 * lParam2 = number of bytes to read
	 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
	 *	   in wErrorRet)
	 * NOTE: lDiskOffset should be updated
	 */
	FIXME("MMIOM_READ on memory files should not occur, buffer may be lost!\n");
	return 0;

    case MMIOM_WRITE:
    case MMIOM_WRITEFLUSH:
	/* no internal buffering, so WRITEFLUSH handled same as WRITE */

	/* Parameters:
	 * lParam1 = huge pointer to write buffer
	 * lParam2 = number of bytes to write
	 * Returns: number of bytes written, -1 for error (error code in
	 *		wErrorRet)
	 * NOTE: lDiskOffset should be updated
	 */
	FIXME("MMIOM_WRITE on memory files should not occur, buffer may be lost!\n");
	return 0;

    case MMIOM_SEEK:
	/* Parameters:
	 * lParam1 = new position
	 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
	 * Returns: new file position, -1 on error
	 * NOTE: lDiskOffset should be updated
	 */
	FIXME("MMIOM_SEEK on memory files should not occur, buffer may be lost!\n");
	return -1;

    default:
	FIXME("unexpected message %u\n", uMessage);
	return 0;
    }
}

/* This array will be the entire list for most apps 
 * Note that temporary ioProcs will be stored with a 0 fourCC code
 */

static struct IOProcList defaultProcs[] = {
    {&defaultProcs[1], FOURCC_DOS, (LPMMIOPROC)mmioDosIOProc, FALSE, 0},
    {NULL,             FOURCC_MEM, (LPMMIOPROC)mmioMemIOProc, FALSE, 0},
};

static struct IOProcList*	pIOProcListAnchor = &defaultProcs[0];

/****************************************************************
 *       	MMIO_FindProcNode 			[INTERNAL]
 *
 * Finds the ProcList node associated with a given FOURCC code.
 */
static struct IOProcList*	MMIO_FindProcNode(FOURCC fccIOProc)
{
    struct IOProcList*	pListNode;

    for (pListNode = pIOProcListAnchor; pListNode; pListNode = pListNode->pNext) {
	if (pListNode->fourCC == fccIOProc) {
	    return pListNode;
	}
    }
    return NULL;
}

/****************************************************************
 *       	MMIO_InstallIOProc 			[INTERNAL]
 */
static LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
                                     DWORD dwFlags, BOOL is_unicode)
{
    LPMMIOPROC	        lpProc = NULL;
    struct IOProcList*  pListNode;
    struct IOProcList** ppListNode;

    TRACE("(%08x, %p, %08X, %s)\n", fccIOProc, pIOProc, dwFlags, is_unicode ? "unicode" : "ansi");

    if (dwFlags & MMIO_GLOBALPROC)
	FIXME("Global procedures not implemented\n");

    /* just handle the known procedures for now */
    switch (dwFlags & (MMIO_INSTALLPROC|MMIO_REMOVEPROC|MMIO_FINDPROC)) {
    case MMIO_INSTALLPROC:
	/* Create new entry for the IOProc list */
	pListNode = HeapAlloc(GetProcessHeap(), 0, sizeof(*pListNode));
	if (pListNode) {
	    /* Fill in this node */
	    pListNode->fourCC = fccIOProc;
	    pListNode->pIOProc = pIOProc;
	    pListNode->is_unicode = is_unicode;
	    pListNode->count = 0;

	    /* Stick it on the end of the list */
	    pListNode->pNext = pIOProcListAnchor;
	    pIOProcListAnchor = pListNode;

	    /* Return this IOProc - that's how the caller knows we succeeded */
	    lpProc = pIOProc;
	}
	break;

    case MMIO_REMOVEPROC:
	/*
	 * Search for the node that we're trying to remove
         * We search for a matching fourCC code if it's non null, or the proc
         * address otherwise
         * note that this method won't find the first item on the list, but
	 * since the first two items on this list are ones we won't
	 * let the user delete anyway, that's okay
	 */
	ppListNode = &pIOProcListAnchor;
	while ((*ppListNode) && 
               ((fccIOProc != 0) ? 
                (*ppListNode)->fourCC != fccIOProc : 
                (*ppListNode)->pIOProc != pIOProc))
	    ppListNode = &((*ppListNode)->pNext);

	if (*ppListNode) { /* found it */
	    /* FIXME: what should be done if an open mmio object uses this proc ?
	     * shall we return an error, nuke the mmio object ?
	     */
	    if ((*ppListNode)->count) {
		ERR("Cannot remove a mmIOProc while in use\n");
		break;
	    }
	    /* remove it, but only if it isn't builtin */
	    if ((*ppListNode) >= defaultProcs &&
		(*ppListNode) < defaultProcs + sizeof(defaultProcs) / sizeof(defaultProcs[0])) {
		WARN("Tried to remove built-in mmio proc. Skipping\n");
	    } else {
		/* Okay, nuke it */
		struct IOProcList*  ptmpNode = *ppListNode;
		lpProc = (*ppListNode)->pIOProc;
		*ppListNode = (*ppListNode)->pNext;
		HeapFree(GetProcessHeap(), 0, ptmpNode);
	    }
	}
	break;

    case MMIO_FINDPROC:
	if ((pListNode = MMIO_FindProcNode(fccIOProc))) {
	    lpProc = pListNode->pIOProc;
	}
	break;
    }

    return lpProc;
}

/****************************************************************
 *       	send_message    			[INTERNAL]
 */
static LRESULT	send_message(struct IOProcList* ioProc, LPMMIOINFO mmioinfo,
                             DWORD wMsg, LPARAM lParam1,
                             LPARAM lParam2, BOOL is_unicode)
{
    LRESULT 		result = MMSYSERR_ERROR;
    LPARAM		lp1 = lParam1, lp2 = lParam2;

    if (!ioProc) {
	ERR("ioProc NULL\n");
	return MMSYSERR_INVALPARAM;
    }

    if (ioProc->is_unicode != is_unicode) {
        /* map (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
        FIXME("NIY 32 A<=>W mapping\n");
    }
    result = (ioProc->pIOProc)((LPSTR)mmioinfo, wMsg, lp1, lp2);

#if 0
    if (ioProc->is_unicode != is_unicode) {
	    /* unmap (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
	}
#endif

    return result;
}

/**************************************************************************
 *      			MMIO_ParseExtA 		        [internal]
 *
 * Parses a filename for the extension.
 *
 * RETURNS
 *  The FOURCC code for the extension if found, else 0.
 */
static FOURCC MMIO_ParseExtA(LPCSTR szFileName)
{
    /* Filenames are of the form file.ext{+ABC}
       For now, we take the last '+' if present */

    FOURCC ret = 0;

    /* Note that ext{Start,End} point to the . and + respectively */
    LPCSTR extEnd;
    LPCSTR extStart;

    CHAR ext[5];

    TRACE("(%s)\n", debugstr_a(szFileName));

    if (!szFileName)
	return ret;

    /* Find the last '+' */
    extEnd = strrchr(szFileName,'+');

    if (!extEnd) {
         /* No + so just an extension */
         return ret;
    } else {
        /* Find the first '.' before '+' */
        extStart = extEnd - 1;
        while (extStart >= szFileName && *extStart != '.') {
            extStart--;
        }
        if (extStart < szFileName) {
            ERR("No extension in szFileName: %s\n", debugstr_a(szFileName));
            return ret;
        }
    }

    if (extEnd - extStart - 1 > 4)
        WARN("Extension length > 4\n");
    lstrcpynA(ext, extStart + 1, min(extEnd-extStart,5));

    TRACE("Got extension: %s\n", debugstr_a(ext));

    /* FOURCC codes identifying file-extensions must be uppercase */
    ret = mmioStringToFOURCCA(ext, MMIO_TOUPPER);

    return ret;
}

/**************************************************************************
 *				MMIO_Get			[internal]
 *
 * Retrieves the mmio object from current process
 */
static LPWINE_MMIO      MMIO_Get(HMMIO h)
{
    LPWINE_MMIO		wm = NULL;

    EnterCriticalSection(&WINMM_cs);
    for (wm = MMIOList; wm; wm = wm->lpNext) {
	if (wm->info.hmmio == h)
	    break;
    }
    LeaveCriticalSection(&WINMM_cs);
    return wm;
}

/**************************************************************************
 *				MMIO_Create			[internal]
 *
 * Creates an internal representation for a mmio instance
 */
static	LPWINE_MMIO		MMIO_Create(void)
{
    static	WORD	MMIO_counter = 0;
    LPWINE_MMIO		wm;

    wm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MMIO));
    if (wm) {
	EnterCriticalSection(&WINMM_cs);
        /* lookup next unallocated WORD handle, with a non NULL value */
	while (++MMIO_counter == 0 || MMIO_Get((HMMIO)(ULONG_PTR)MMIO_counter));
	wm->info.hmmio = (HMMIO)(ULONG_PTR)MMIO_counter;
	wm->lpNext = MMIOList;
	MMIOList = wm;
	LeaveCriticalSection(&WINMM_cs);
    }
    return wm;
}

/**************************************************************************
 *				MMIO_Destroy			[internal]
 *-
 * Destroys an internal representation for a mmio instance
 */
static	BOOL		MMIO_Destroy(LPWINE_MMIO wm)
{
    LPWINE_MMIO*	m;

    EnterCriticalSection(&WINMM_cs);
    /* search for the matching one... */
    m = &MMIOList;
    while (*m && *m != wm) m = &(*m)->lpNext;
    /* ...and destroy */
    if (*m) {
	*m = (*m)->lpNext;
	HeapFree(GetProcessHeap(), 0, wm);
	wm = NULL;
    }
    LeaveCriticalSection(&WINMM_cs);
    return !wm;
}

/****************************************************************
 *       		MMIO_Flush 			[INTERNAL]
 */
static	MMRESULT MMIO_Flush(WINE_MMIO* wm, UINT uFlags)
{
    if (wm->info.cchBuffer && (wm->info.fccIOProc != FOURCC_MEM)) {
	/* not quite sure what to do here, but I'll guess */
	if (wm->info.dwFlags & MMIO_DIRTY) {
            /* FIXME: error handling */
	    send_message(wm->ioProc, &wm->info, MMIOM_SEEK, wm->info.lBufOffset, SEEK_SET, FALSE);
	    send_message(wm->ioProc, &wm->info, MMIOM_WRITE,
                         (LPARAM)wm->info.pchBuffer,
                         wm->info.pchNext - wm->info.pchBuffer, FALSE);
	}
	if (uFlags & MMIO_EMPTYBUF)
	    wm->info.pchNext = wm->info.pchEndRead = wm->info.pchBuffer;
    }
    wm->info.dwFlags &= ~MMIO_DIRTY;

    return MMSYSERR_NOERROR;
}

/***************************************************************************
 *       		MMIO_GrabNextBuffer			[INTERNAL]
 */
static LONG	MMIO_GrabNextBuffer(LPWINE_MMIO wm, int for_read)
{
    LONG	size = wm->info.cchBuffer;

    TRACE("bo=%x do=%x of=%lx\n",
	  wm->info.lBufOffset, wm->info.lDiskOffset,
	  send_message(wm->ioProc, &wm->info, MMIOM_SEEK, 0, SEEK_CUR, FALSE));

    wm->info.lBufOffset = wm->info.lDiskOffset;
    wm->info.pchNext = wm->info.pchBuffer;
    wm->info.pchEndRead = wm->info.pchBuffer;
    wm->info.pchEndWrite = wm->info.pchBuffer + wm->info.cchBuffer;

    wm->bBufferLoaded = TRUE;
    if (for_read) {
	size = send_message(wm->ioProc, &wm->info, MMIOM_READ,
                            (LPARAM)wm->info.pchBuffer, size, FALSE);
	if (size > 0)
	    wm->info.pchEndRead += size;
        else
            wm->bBufferLoaded = FALSE;
    }

    return size;
}

/***************************************************************************
 *       		MMIO_SetBuffer 				[INTERNAL]
 */
static MMRESULT MMIO_SetBuffer(WINE_MMIO* wm, void* pchBuffer, LONG cchBuffer,
			       UINT uFlags)
{
    TRACE("(%p %p %d %u)\n", wm, pchBuffer, cchBuffer, uFlags);

    if (cchBuffer > 0xFFFF)
	WARN("Untested handling of huge mmio buffers (%d >= 64k)\n", cchBuffer);

    if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
	return MMIOERR_CANNOTWRITE;

    /* free previous buffer if allocated */
    if (wm->info.dwFlags & MMIO_ALLOCBUF) {
        HeapFree(GetProcessHeap(), 0, wm->info.pchBuffer);
        wm->info.pchBuffer = NULL;
	wm->info.dwFlags &= ~MMIO_ALLOCBUF;
    }

    if (pchBuffer) {
        wm->info.pchBuffer = pchBuffer;
    } else if (cchBuffer) {
	if (!(wm->info.pchBuffer = HeapAlloc(GetProcessHeap(), 0, cchBuffer)))
	    return MMIOERR_OUTOFMEMORY;
	wm->info.dwFlags |= MMIO_ALLOCBUF;
    } else {
	wm->info.pchBuffer = NULL;
    }

    wm->info.cchBuffer = cchBuffer;
    wm->info.pchNext = wm->info.pchBuffer;
    wm->info.pchEndRead = wm->info.pchBuffer;
    wm->info.pchEndWrite = wm->info.pchBuffer + cchBuffer;
    wm->info.lBufOffset = wm->info.lDiskOffset;
    wm->bBufferLoaded = (wm->info.fccIOProc == FOURCC_MEM);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			MMIO_Open       			[internal]
 */
static HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags, BOOL is_unicode)
{
    LPWINE_MMIO		wm;
    MMIOINFO    	mmioinfo;
    DWORD               pos;

    TRACE("(%s, %p, %08X, %s);\n", debugstr_a(szFileName), refmminfo, dwOpenFlags, is_unicode ? "unicode" : "ansi");

    if (!refmminfo) {
        refmminfo = &mmioinfo;

	mmioinfo.fccIOProc = 0;
	mmioinfo.pIOProc = NULL;
	mmioinfo.pchBuffer = NULL;
	mmioinfo.cchBuffer = 0;
        is_unicode = FALSE;
    }

    if (dwOpenFlags & (MMIO_PARSE|MMIO_EXIST)) {
	char	buffer[MAX_PATH];

	if (!szFileName)
	    return (HMMIO)FALSE;
	if (GetFullPathNameA(szFileName, sizeof(buffer), buffer, NULL) >= sizeof(buffer))
	    return (HMMIO)FALSE;
	if ((dwOpenFlags & MMIO_EXIST) && (GetFileAttributesA(buffer) == INVALID_FILE_ATTRIBUTES))
	    return (HMMIO)FALSE;
	strcpy(szFileName, buffer);
	return (HMMIO)TRUE;
    }

    if ((wm = MMIO_Create()) == NULL)
	return 0;

    /* If both params are NULL, then parse the file name if available */
    if (refmminfo->fccIOProc == 0 && refmminfo->pIOProc == NULL) {
	wm->info.fccIOProc = MMIO_ParseExtA(szFileName);
	/* Handle any unhandled/error case. Assume DOS file */
	if (wm->info.fccIOProc == 0) {
	    wm->info.fccIOProc = FOURCC_DOS;
	    wm->ioProc = &defaultProcs[0];
	}
	else if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) {
	    /* If not found, assume DOS file */
	    wm->ioProc = &defaultProcs[0];
	}
	wm->bTmpIOProc = FALSE;
    }
    /* if just the four character code is present, look up IO proc */
    else if (refmminfo->pIOProc == NULL) {
	wm->info.fccIOProc = refmminfo->fccIOProc;
	if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) goto error2;
	wm->bTmpIOProc = FALSE;
    }
    /* if IO proc specified, use it and specified four character code */
    else {
	wm->info.fccIOProc = refmminfo->fccIOProc;
	MMIO_InstallIOProc(wm->info.fccIOProc, refmminfo->pIOProc,
                           MMIO_INSTALLPROC, is_unicode);
	if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) goto error2;
	assert(wm->ioProc->pIOProc == refmminfo->pIOProc);
	wm->bTmpIOProc = TRUE;
    }

    wm->ioProc->count++;
    wm->info.dwFlags = dwOpenFlags;

    if (dwOpenFlags & MMIO_ALLOCBUF) {
	refmminfo->wErrorRet = MMIO_SetBuffer(wm, refmminfo->pchBuffer,
	    refmminfo->cchBuffer ? refmminfo->cchBuffer : MMIO_DEFAULTBUFFER, 0);
	if (refmminfo->wErrorRet != MMSYSERR_NOERROR)
	    goto error1;
    } else {
        refmminfo->wErrorRet = MMIO_SetBuffer(wm, refmminfo->pchBuffer, refmminfo->cchBuffer, 0);
	if (refmminfo->wErrorRet != MMSYSERR_NOERROR)
	    goto error1;
    }

    /* see mmioDosIOProc for that one */
    memcpy( wm->info.adwInfo, refmminfo->adwInfo, sizeof(wm->info.adwInfo) );

    /* call IO proc to actually open file */
    refmminfo->wErrorRet = send_message(wm->ioProc, &wm->info, MMIOM_OPEN,
                                        (LPARAM)szFileName, 0, FALSE);

    /* update offsets and grab file size, when possible */
    if (wm->info.fccIOProc != FOURCC_MEM && (send_message(wm->ioProc, &wm->info, MMIOM_SEEK, 0, SEEK_CUR, FALSE)) != -1) {
       pos = wm->info.lBufOffset = wm->info.lDiskOffset;
       send_message(wm->ioProc, &wm->info, MMIOM_SEEK, 0, SEEK_END, FALSE);
       wm->dwFileSize = wm->info.lDiskOffset;
       send_message(wm->ioProc, &wm->info, MMIOM_SEEK, pos, SEEK_SET, FALSE);
    }
    else wm->dwFileSize = 0;

    if (refmminfo->wErrorRet == 0)
	return wm->info.hmmio;
 error1:
    if (wm->info.dwFlags & MMIO_ALLOCBUF)
        HeapFree(GetProcessHeap(), 0, wm->info.pchBuffer);
    if (wm->ioProc) wm->ioProc->count--;
 error2:
    MMIO_Destroy(wm);
    return 0;
}

/**************************************************************************
 * 				mmioOpenW       		[WINMM.@]
 */
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO* lpmmioinfo,
		       DWORD dwOpenFlags)
{
    HMMIO 	ret;
    LPSTR	szFn = NULL;

    if (szFileName)
    {
        INT     len = WideCharToMultiByte( CP_ACP, 0, szFileName, -1, NULL, 0, NULL, NULL );
        szFn = HeapAlloc( GetProcessHeap(), 0, len );
        if (!szFn) return NULL;
        WideCharToMultiByte( CP_ACP, 0, szFileName, -1, szFn, len, NULL, NULL );
    }

    ret = MMIO_Open(szFn, lpmmioinfo, dwOpenFlags, TRUE);

    HeapFree(GetProcessHeap(), 0, szFn);
    return ret;
}

/**************************************************************************
 * 				mmioOpenA       		[WINMM.@]
 */
HMMIO WINAPI mmioOpenA(LPSTR szFileName, MMIOINFO* lpmmioinfo,
		       DWORD dwOpenFlags)
{
    return  MMIO_Open(szFileName, lpmmioinfo, dwOpenFlags, FALSE);
}

/**************************************************************************
 * 				mmioClose      		[WINMM.@]
 */
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
{
    LPWINE_MMIO	wm;
    MMRESULT 	result;

    TRACE("(%p, %04X);\n", hmmio, uFlags);

    if ((wm = MMIO_Get(hmmio)) == NULL)
	return MMSYSERR_INVALHANDLE;

    if ((result = MMIO_Flush(wm, 0)) != MMSYSERR_NOERROR)
	return result;

    result = send_message(wm->ioProc, &wm->info, MMIOM_CLOSE, uFlags, 0, FALSE);

    MMIO_SetBuffer(wm, NULL, 0, 0);

    wm->ioProc->count--;

    if (wm->bTmpIOProc)
	MMIO_InstallIOProc(wm->info.fccIOProc, wm->ioProc->pIOProc,
                           MMIO_REMOVEPROC, wm->ioProc->is_unicode);

    MMIO_Destroy(wm);

    return result;
}

/**************************************************************************
 * 				mmioRead	       	[WINMM.@]
 */
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
{
    LPWINE_MMIO	wm;
    LONG 	count;

    TRACE("(%p, %p, %d);\n", hmmio, pch, cch);

    if ((wm = MMIO_Get(hmmio)) == NULL)
	return -1;

    /* unbuffered case first */
    if (!wm->info.pchBuffer)
	return send_message(wm->ioProc, &wm->info, MMIOM_READ, (LPARAM)pch, cch, FALSE);

    /* first try from current buffer */
    if (cch && wm->info.fccIOProc != FOURCC_MEM && wm->info.pchNext == wm->info.pchEndRead)
	MMIO_GrabNextBuffer(wm, TRUE);
    if (wm->info.pchNext != wm->info.pchEndRead) {
	count = wm->info.pchEndRead - wm->info.pchNext;
	if (count > cch || count < 0) count = cch;
	memcpy(pch, wm->info.pchNext, count);
	wm->info.pchNext += count;
	pch += count;
	cch -= count;
    } else
	count = 0;

    if (cch && (wm->info.fccIOProc != FOURCC_MEM)) {
	assert(wm->info.cchBuffer);

	while (cch) {
	    LONG size;

	    size = MMIO_GrabNextBuffer(wm, TRUE);
	    if (size <= 0) break;
	    if (size > cch) size = cch;
	    memcpy(pch, wm->info.pchBuffer, size);
	    wm->info.pchNext += size;
	    pch += size;
	    cch -= size;
	    count += size;
	}
	wm->bBufferLoaded = FALSE;
	mmioSeek(hmmio, 0, SEEK_CUR);
    }

    TRACE("count=%d\n", count);
    return count;
}

/**************************************************************************
 * 				mmioWrite      		[WINMM.@]
 */
LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
{
    LPWINE_MMIO	wm;
    LONG	count;

    TRACE("(%p, %p, %d);\n", hmmio, pch, cch);

    if ((wm = MMIO_Get(hmmio)) == NULL)
	return -1;

    if (wm->info.cchBuffer) {
	LONG	bytesW = 0;

        count = 0;
        while (cch) {
            if (wm->info.pchNext != wm->info.pchEndWrite) {
                count = wm->info.pchEndWrite - wm->info.pchNext;
                if (count > cch || count < 0) count = cch;
                memcpy(wm->info.pchNext, pch, count);
                wm->info.pchNext += count;
                pch += count;
                cch -= count;
                bytesW += count;
                wm->info.dwFlags |= MMIO_DIRTY;
	    } else {
                if (wm->info.fccIOProc == FOURCC_MEM) {
                    if (wm->info.adwInfo[0]) {
                        /* from where would we get the memory handle? */
                        FIXME("memory file expansion not implemented!\n");
                        break;
		    } else break;
                }
            }

            if (wm->info.pchNext == wm->info.pchEndWrite)
            {
                MMIO_Flush(wm, MMIO_EMPTYBUF);
                MMIO_GrabNextBuffer(wm, FALSE);
            }
            else break;
        }
	count = bytesW;
    } else {
	count = send_message(wm->ioProc, &wm->info, MMIOM_WRITE, (LPARAM)pch, cch, FALSE);
	wm->info.lBufOffset = wm->info.lDiskOffset;
    }

    TRACE("bytes written=%d\n", count);
    return count;
}

/**************************************************************************
 * 				mmioSeek		[WINMM.@]
 */
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
{
    LPWINE_MMIO	wm;
    LONG 	offset;

    TRACE("(%p, %08X, %d);\n", hmmio, lOffset, iOrigin);

    if ((wm = MMIO_Get(hmmio)) == NULL)
	return MMSYSERR_INVALHANDLE;

    /* not buffered, direct seek on file */
    if (!wm->info.pchBuffer && wm->info.fccIOProc != FOURCC_MEM) {
	LRESULT ret = send_message(wm->ioProc, &wm->info, MMIOM_SEEK, lOffset, iOrigin, FALSE);
	if (ret != -1)
	    wm->info.lBufOffset = wm->info.lDiskOffset;
	return ret;
    }

    switch (iOrigin) {
    case SEEK_SET:
	offset = lOffset;
	break;
    case SEEK_CUR:
	offset = wm->info.lBufOffset + (wm->info.pchNext - wm->info.pchBuffer) + lOffset;
	break;
    case SEEK_END:
	offset = ((wm->info.fccIOProc == FOURCC_MEM)? wm->info.cchBuffer : wm->dwFileSize) - lOffset;
	break;
    default:
	return -1;
    }

    /* stay in same buffer ? */
    /* some memory mapped buffers are defined with -1 as a size */
    if ((wm->info.cchBuffer > 0) &&
	((offset < wm->info.lBufOffset) ||
	 (offset > wm->info.lBufOffset + wm->info.cchBuffer) ||
	 (offset > wm->dwFileSize && wm->info.fccIOProc != FOURCC_MEM) ||
	 !wm->bBufferLoaded)) {

	/* condition to change buffer */
	if ((wm->info.fccIOProc == FOURCC_MEM) ||
	    MMIO_Flush(wm, 0) != MMSYSERR_NOERROR ||
	    /* this also sets the wm->info.lDiskOffset field */
	    send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
                         offset, SEEK_SET, FALSE) == -1)
	    return -1;
	wm->info.lBufOffset = offset;
	wm->bBufferLoaded = FALSE;
	wm->info.pchNext = wm->info.pchEndRead = wm->info.pchBuffer;
    }
    else
	wm->info.pchNext = wm->info.pchBuffer + (offset - wm->info.lBufOffset);

    TRACE("=> %d\n", offset);
    return offset;
}

/**************************************************************************
 * 				mmioGetInfo	       	[WINMM.@]
 */
MMRESULT WINAPI mmioGetInfo(HMMIO hmmio, MMIOINFO* lpmmioinfo, UINT uFlags)
{
    LPWINE_MMIO		wm;

    TRACE("(%p,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);

    if ((wm = MMIO_Get(hmmio)) == NULL)
	return MMSYSERR_INVALHANDLE;

    *lpmmioinfo = wm->info;

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mmioSetInfo    		[WINMM.@]
 */
MMRESULT WINAPI mmioSetInfo(HMMIO hmmio, const MMIOINFO* lpmmioinfo, UINT uFlags)
{
    LPWINE_MMIO		wm;

    TRACE("(%p,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);

    if ((wm = MMIO_Get(hmmio)) == NULL)
	return MMSYSERR_INVALHANDLE;

    /* check pointers coherence */
    if (lpmmioinfo->pchNext < wm->info.pchBuffer ||
	lpmmioinfo->pchNext > wm->info.pchBuffer + wm->info.cchBuffer ||
	lpmmioinfo->pchEndRead < wm->info.pchBuffer ||
	lpmmioinfo->pchEndRead > wm->info.pchBuffer + wm->info.cchBuffer ||
	lpmmioinfo->pchEndWrite < wm->info.pchBuffer ||
	lpmmioinfo->pchEndWrite > wm->info.pchBuffer + wm->info.cchBuffer)
	return MMSYSERR_INVALPARAM;

    wm->info.pchNext = lpmmioinfo->pchNext;
    wm->info.pchEndRead = lpmmioinfo->pchEndRead;

    return MMSYSERR_NOERROR;
}

/**************************************************************************
* 				mmioSetBuffer		[WINMM.@]
*/
MMRESULT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT uFlags)
{
    LPWINE_MMIO		wm;

    TRACE("(hmmio=%p, pchBuf=%p, cchBuf=%d, uFlags=%#08x)\n",
	  hmmio, pchBuffer, cchBuffer, uFlags);

    if ((wm = MMIO_Get(hmmio)) == NULL)
	return MMSYSERR_INVALHANDLE;

    return MMIO_SetBuffer(wm, pchBuffer, cchBuffer, uFlags);
}

/**************************************************************************
 * 				mmioFlush      		[WINMM.@]
 */
MMRESULT WINAPI mmioFlush(HMMIO hmmio, UINT uFlags)
{
    LPWINE_MMIO		wm;

    TRACE("(%p, %04X)\n", hmmio, uFlags);

    if ((wm = MMIO_Get(hmmio)) == NULL)
	return MMSYSERR_INVALHANDLE;

    return MMIO_Flush(wm, uFlags);
}

/**************************************************************************
 * 				mmioAdvance      	[WINMM.@]
 */
MMRESULT WINAPI mmioAdvance(HMMIO hmmio, MMIOINFO* lpmmioinfo, UINT uFlags)
{
    LPWINE_MMIO		wm;

    TRACE("hmmio=%p, lpmmioinfo=%p, uFlags=%04X\n", hmmio, lpmmioinfo, uFlags);

    /* NOTE: mmioAdvance16 heavily relies on parameters from lpmmioinfo we're using
     * here. be sure if you change something here to check mmioAdvance16 as well
     */
    if ((wm = MMIO_Get(hmmio)) == NULL)
	return MMSYSERR_INVALHANDLE;

    if (!wm->info.cchBuffer)
	return MMIOERR_UNBUFFERED;

    if (uFlags != MMIO_READ && uFlags != MMIO_WRITE)
	return MMSYSERR_INVALPARAM;

    if (uFlags == MMIO_WRITE && (lpmmioinfo->dwFlags & MMIO_DIRTY))
    {
        send_message(wm->ioProc, &wm->info, MMIOM_SEEK, lpmmioinfo->lBufOffset, SEEK_SET, FALSE);
        send_message(wm->ioProc, &wm->info, MMIOM_WRITE, (LPARAM)lpmmioinfo->pchBuffer,
                     lpmmioinfo->pchNext - lpmmioinfo->pchBuffer, FALSE);
        lpmmioinfo->dwFlags &= ~MMIO_DIRTY;
    }
    if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
	return MMIOERR_CANNOTWRITE;

    if (lpmmioinfo) {
	wm->dwFileSize = max(wm->dwFileSize, lpmmioinfo->lBufOffset + 
                             (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer));
    }
    MMIO_GrabNextBuffer(wm, uFlags == MMIO_READ);

    if (lpmmioinfo) {
	lpmmioinfo->pchNext = lpmmioinfo->pchBuffer;
	lpmmioinfo->pchEndRead  = lpmmioinfo->pchBuffer +
	    (wm->info.pchEndRead - wm->info.pchBuffer);
	lpmmioinfo->pchEndWrite = lpmmioinfo->pchBuffer +
	    (wm->info.pchEndWrite - wm->info.pchBuffer);
	lpmmioinfo->lDiskOffset = wm->info.lDiskOffset;
	lpmmioinfo->lBufOffset = wm->info.lBufOffset;
    }
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mmioStringToFOURCCA	[WINMM.@]
 */
FOURCC WINAPI mmioStringToFOURCCA(LPCSTR sz, UINT uFlags)
{
    CHAR cc[4];
    int i = 0;

    for (i = 0; i < 4 && sz[i]; i++) {
	if (uFlags & MMIO_TOUPPER) {
	    cc[i] = toupper(sz[i]);
	} else {
	    cc[i] = sz[i];
	}
    }

    /* Pad with spaces */
    while (i < 4) cc[i++] = ' ';

    TRACE("Got %s\n",debugstr_an(cc,4));
    return mmioFOURCC(cc[0],cc[1],cc[2],cc[3]);
}

/**************************************************************************
 * 				mmioStringToFOURCCW	[WINMM.@]
 */
FOURCC WINAPI mmioStringToFOURCCW(LPCWSTR sz, UINT uFlags)
{
    char	szA[4];

    WideCharToMultiByte( CP_ACP, 0, sz, 4, szA, sizeof(szA), NULL, NULL );
    return mmioStringToFOURCCA(szA,uFlags);
}

/**************************************************************************
 * 				mmioInstallIOProcA	   [WINMM.@]
 */
LPMMIOPROC WINAPI mmioInstallIOProcA(FOURCC fccIOProc,
				     LPMMIOPROC pIOProc, DWORD dwFlags)
{
    return MMIO_InstallIOProc(fccIOProc, pIOProc, dwFlags, FALSE);
}

/**************************************************************************
 * 				mmioInstallIOProcW	   [WINMM.@]
 */
LPMMIOPROC WINAPI mmioInstallIOProcW(FOURCC fccIOProc,
				     LPMMIOPROC pIOProc, DWORD dwFlags)
{
    return MMIO_InstallIOProc(fccIOProc, pIOProc, dwFlags, TRUE);
}

/******************************************************************
 *		MMIO_SendMessage
 *
 *
 */
static LRESULT  MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
                                 LPARAM lParam2, BOOL is_unicode)
{
    LPWINE_MMIO		wm;

    TRACE("(%p, %u, %ld, %ld, %s)\n", hmmio, uMessage, lParam1, lParam2, is_unicode ? "unicode" : "ansi");

    if (uMessage < MMIOM_USER)
	return MMSYSERR_INVALPARAM;

    if ((wm = MMIO_Get(hmmio)) == NULL)
	return MMSYSERR_INVALHANDLE;

    return send_message(wm->ioProc, &wm->info, uMessage, lParam1, lParam2, is_unicode);
}

/**************************************************************************
 * 				mmioSendMessage		[WINMM.@]
 */
LRESULT WINAPI mmioSendMessage(HMMIO hmmio, UINT uMessage,
			       LPARAM lParam1, LPARAM lParam2)
{
    return MMIO_SendMessage(hmmio, uMessage, lParam1, lParam2, FALSE);
}

/**************************************************************************
 * 				mmioDescend         	[WINMM.@]
 */
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck,
                            const MMCKINFO* lpckParent, UINT uFlags)
{
    DWORD		dwOldPos;
    FOURCC		srchCkId;
    FOURCC		srchType;

    TRACE("(%p, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags);

    if (lpck == NULL)
	return MMSYSERR_INVALPARAM;

    dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
    TRACE("dwOldPos=%d\n", dwOldPos);

    if (lpckParent != NULL) {
	TRACE("seek inside parent at %d !\n", lpckParent->dwDataOffset);
	/* EPP: was dwOldPos = mmioSeek(hmmio,lpckParent->dwDataOffset,SEEK_SET); */
	if (dwOldPos < lpckParent->dwDataOffset ||
	    dwOldPos >= lpckParent->dwDataOffset + lpckParent->cksize) {
	    WARN("outside parent chunk\n");
	    return MMIOERR_CHUNKNOTFOUND;
	}
    }

    /* The SDK docu says 'ckid' is used for all cases. Real World
     * examples disagree -Marcus,990216.
     */

    srchCkId = 0;
    srchType = 0;

    /* find_chunk looks for 'ckid' */
    if (uFlags & MMIO_FINDCHUNK)
	srchCkId = lpck->ckid;

    /* find_riff and find_list look for 'fccType' */
    if (uFlags & MMIO_FINDLIST)
    {
	srchCkId = FOURCC_LIST;
        srchType = lpck->fccType;
    }

    if (uFlags & MMIO_FINDRIFF)
    {
	srchCkId = FOURCC_RIFF;
        srchType = lpck->fccType;
    }

    TRACE("searching for %s.%s\n",
          debugstr_an((LPCSTR)&srchCkId, 4), srchType ? debugstr_an((LPCSTR)&srchType, 4) : "<any>");

    while (TRUE)
    {
        LONG ix;

        ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
        if (ix < 2*sizeof(DWORD))
        {
            mmioSeek(hmmio, dwOldPos, SEEK_SET);
            WARN("return ChunkNotFound\n");
            return MMIOERR_CHUNKNOTFOUND;
        }

        lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
        TRACE("ckid=%s fcc=%s cksize=%08X !\n",
              debugstr_an((LPCSTR)&lpck->ckid, 4),
              srchType ? debugstr_an((LPCSTR)&lpck->fccType, 4) : "<na>",
              lpck->cksize);
        if ( (!srchCkId || (srchCkId == lpck->ckid)) &&
             (!srchType || (srchType == lpck->fccType)) )
            break;

        dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1);
        mmioSeek(hmmio, dwOldPos, SEEK_SET);
    }

    lpck->dwFlags = 0;
    /* If we were looking for RIFF/LIST chunks, the final file position
     * is after the chunkid. If we were just looking for the chunk
     * it is after the cksize. So add 4 in RIFF/LIST case.
     */
    if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST)
	mmioSeek(hmmio, lpck->dwDataOffset + sizeof(DWORD), SEEK_SET);
    else
    {
	mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
	lpck->fccType = 0;
    }
    TRACE("lpck: ckid=%s, cksize=%d, dwDataOffset=%d fccType=%08X (%s)!\n",
	  debugstr_an((LPSTR)&lpck->ckid, 4), lpck->cksize, lpck->dwDataOffset,
	  lpck->fccType, srchType ? debugstr_an((LPSTR)&lpck->fccType, 4):"");
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mmioAscend     		[WINMM.@]
 */
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
{
    TRACE("(%p, %p, %04X);\n", hmmio, lpck, uFlags);

    if (lpck->dwFlags & MMIO_DIRTY) {
	DWORD	dwOldPos, dwNewSize;

	TRACE("Chunk is dirty, checking if chunk's size is correct\n");
	dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
	TRACE("dwOldPos=%d lpck->dwDataOffset = %d\n", dwOldPos, lpck->dwDataOffset);
	dwNewSize = dwOldPos - lpck->dwDataOffset;
	if (dwNewSize != lpck->cksize) {
	    TRACE("Nope: lpck->cksize=%d dwNewSize=%d\n", lpck->cksize, dwNewSize);
	    lpck->cksize = dwNewSize;

	    /* pad odd size with 0 */
	    if (dwNewSize & 1) {
		char ch = 0;
		mmioWrite(hmmio, &ch, 1);
	    }
	    mmioSeek(hmmio, lpck->dwDataOffset - sizeof(DWORD), SEEK_SET);
	    mmioWrite(hmmio, (LPSTR)&dwNewSize, sizeof(DWORD));
	}
	lpck->dwFlags = 0;
    }

    mmioSeek(hmmio, lpck->dwDataOffset + ((lpck->cksize + 1) & ~1), SEEK_SET);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			mmioCreateChunk				[WINMM.@]
 */
MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO* lpck, UINT uFlags)
{
    DWORD	dwOldPos;
    LONG 	size;
    LONG 	ix;

    TRACE("(%p, %p, %04X);\n", hmmio, lpck, uFlags);

    dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
    TRACE("dwOldPos=%d\n", dwOldPos);

    if (uFlags == MMIO_CREATELIST)
	lpck->ckid = FOURCC_LIST;
    else if (uFlags == MMIO_CREATERIFF)
	lpck->ckid = FOURCC_RIFF;

    TRACE("ckid=%s\n", debugstr_an((LPSTR)&lpck->ckid, 4));

    size = 2 * sizeof(DWORD);
    lpck->dwDataOffset = dwOldPos + size;

    if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST)
	size += sizeof(DWORD);
    lpck->dwFlags = MMIO_DIRTY;

    ix = mmioWrite(hmmio, (LPSTR)lpck, size);
    TRACE("after mmioWrite ix = %d req = %d, errno = %d\n", ix, size, errno);
    if (ix < size) {
	mmioSeek(hmmio, dwOldPos, SEEK_SET);
	WARN("return CannotWrite\n");
	return MMIOERR_CANNOTWRITE;
    }

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mmioRenameA    			[WINMM.@]
 */
MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
                            const MMIOINFO* lpmmioinfo, DWORD dwFlags)
{
    struct IOProcList*  ioProc = NULL;
    struct IOProcList   tmp;
    FOURCC              fcc;

    TRACE("(%s, %s, %p, %08X);\n",
	  debugstr_a(szFileName), debugstr_a(szNewFileName), lpmmioinfo, dwFlags);

    /* If both params are NULL, then parse the file name */
    if (lpmmioinfo && lpmmioinfo->fccIOProc == 0 && lpmmioinfo->pIOProc == NULL)
    {
	fcc = MMIO_ParseExtA(szFileName);
        if (fcc) ioProc = MMIO_FindProcNode(fcc);
    }

    /* Handle any unhandled/error case from above. Assume DOS file */
    if (!lpmmioinfo || (lpmmioinfo->fccIOProc == 0 && lpmmioinfo->pIOProc == NULL && ioProc == NULL))
	ioProc = &defaultProcs[0];
    /* if just the four character code is present, look up IO proc */
    else if (lpmmioinfo->pIOProc == NULL)
        ioProc = MMIO_FindProcNode(lpmmioinfo->fccIOProc);
    else /* use relevant ioProc */
    {
        ioProc = &tmp;
        tmp.fourCC = lpmmioinfo->fccIOProc;
        tmp.pIOProc = lpmmioinfo->pIOProc;
        tmp.is_unicode = FALSE;
        tmp.count = 1;
    }

    /* FIXME: should we actually pass lpmmioinfo down the drain ???
     * or make a copy of it because it's const ???
     */
    return send_message(ioProc, (MMIOINFO*)lpmmioinfo, MMIOM_RENAME,
                        (LPARAM)szFileName, (LPARAM)szNewFileName, FALSE);
}

/**************************************************************************
 * 				mmioRenameW    			[WINMM.@]
 */
MMRESULT WINAPI mmioRenameW(LPCWSTR szFileName, LPCWSTR szNewFileName,
                            const MMIOINFO* lpmmioinfo, DWORD dwFlags)
{
    LPSTR	szFn = NULL;
    LPSTR	sznFn = NULL;
    UINT	ret = MMSYSERR_NOMEM;
    INT         len;

    if (szFileName)
    {
        len = WideCharToMultiByte( CP_ACP, 0, szFileName, -1, NULL, 0, NULL, NULL );
        szFn = HeapAlloc( GetProcessHeap(), 0, len );
        if (!szFn) goto done;
        WideCharToMultiByte( CP_ACP, 0, szFileName, -1, szFn, len, NULL, NULL );
    }
    if (szNewFileName)
    {
        len = WideCharToMultiByte( CP_ACP, 0, szNewFileName, -1, NULL, 0, NULL, NULL );
        sznFn = HeapAlloc( GetProcessHeap(), 0, len );
        if (!sznFn) goto done;
        WideCharToMultiByte( CP_ACP, 0, szNewFileName, -1, sznFn, len, NULL, NULL );
    }

    ret = mmioRenameA(szFn, sznFn, lpmmioinfo, dwFlags);

done:
    HeapFree(GetProcessHeap(),0,szFn);
    HeapFree(GetProcessHeap(),0,sznFn);
    return ret;
}
