/*
 * 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 postion, -1 on error
	 */
	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 postion, -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 ? FALSE : TRUE;
}

/****************************************************************
 *       		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 = FALSE;

    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;
    }

    if (wm->info.fccIOProc == FOURCC_MEM && !(wm->info.dwFlags & MMIO_ALLOCBUF))
        wm->bBufferLoaded = TRUE;

    /* see mmioDosIOProc for that one */
    wm->info.adwInfo[0] = refmminfo->adwInfo[0];

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

    /* 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.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 (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;
	}
    }

    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)
	return send_message(wm->ioProc, &wm->info, MMIOM_SEEK, lOffset, iOrigin, FALSE);

    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;
    }

    if (offset && offset >= wm->dwFileSize && wm->info.fccIOProc != FOURCC_MEM) {
        /* should check that write mode exists */
        if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
            return -1;
        wm->info.lBufOffset = offset;
        wm->info.pchEndRead = wm->info.pchBuffer;
        wm->info.pchEndWrite = wm->info.pchBuffer + wm->info.cchBuffer;
        if ((wm->info.dwFlags & MMIO_RWMODE) == MMIO_READ) {
            wm->info.lDiskOffset = wm->dwFileSize;
        }
    } else if ((wm->info.cchBuffer > 0) &&
	((offset < wm->info.lBufOffset) ||
	 (offset >= wm->info.lBufOffset + wm->info.cchBuffer) ||
	 !wm->bBufferLoaded)) {
        /* stay in same buffer ? */
        /* some memory mapped buffers are defined with -1 as a size */

	/* 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 / wm->info.cchBuffer) * wm->info.cchBuffer,
                         SEEK_SET, FALSE) == -1)
	    return -1;
	MMIO_GrabNextBuffer(wm, TRUE);
    }

    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;
}
