user: Fix DrawTextExA/W on empty strings.
[wine] / dlls / winmm / mmio.c
index 5491fc2..c47e7a7 100644 (file)
@@ -1,4 +1,3 @@
-/* -*- tab-width: 8; c-basic-offset: 4 -*- */
 /*
  * MMIO functions
  *
 
 
 #include <ctype.h>
+#include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
 
-#include "mmsystem.h"
 #include "windef.h"
-#include "heap.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "mmsystem.h"
 #include "winemm.h"
 
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mmio);
 
+LRESULT         (*pFnMmioCallback16)(DWORD,LPMMIOINFO,UINT,LPARAM,LPARAM) /* = NULL */;
+
 /**************************************************************************
  *                     mmioDosIOProc                           [internal]
  */
@@ -71,9 +74,7 @@ static LRESULT CALLBACK mmioDosIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage,
            }
 
            /* if filename NULL, assume open file handle in adwInfo[0] */
-           if (!szFileName) {
-                lpmmioinfo->adwInfo[0] = DosFileHandleToWin32Handle(lpmmioinfo->adwInfo[0]);
-           } else {
+           if (szFileName) {
                 OFSTRUCT    ofs;
                 lpmmioinfo->adwInfo[0] = (DWORD)OpenFile(szFileName, &ofs, lpmmioinfo->dwFlags & 0xFFFF);
             }
@@ -219,8 +220,6 @@ static LRESULT CALLBACK mmioMemIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage,
        FIXME("unexpected message %u\n", uMessage);
        return 0;
     }
-
-    return 0;
 }
 
 /* This array will be the entire list for most apps 
@@ -261,7 +260,7 @@ LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
     struct IOProcList*  pListNode;
     struct IOProcList** ppListNode;
 
-    TRACE("(%ld, %p, %08lX, %i)\n", fccIOProc, pIOProc, dwFlags, type);
+    TRACE("(%08lx, %p, %08lX, %i)\n", fccIOProc, pIOProc, dwFlags, type);
 
     if (dwFlags & MMIO_GLOBALPROC)
        FIXME("Global procedures not implemented\n");
@@ -352,9 +351,9 @@ static LRESULT      send_message(struct IOProcList* ioProc, LPMMIOINFO mmioinfo,
 
     switch (ioProc->type) {
     case MMIO_PROC_16:
-        if (WINMM_IData && WINMM_IData->pFnMmioCallback16)
-            result = WINMM_IData->pFnMmioCallback16((SEGPTR)ioProc->pIOProc,
-                                                    mmioinfo, wMsg, lp1, lp2);
+        if (pFnMmioCallback16)
+            result = pFnMmioCallback16((DWORD)ioProc->pIOProc,
+                                       mmioinfo, wMsg, lp1, lp2);
         break;
     case MMIO_PROC_32A:
     case MMIO_PROC_32W:
@@ -387,41 +386,47 @@ static LRESULT    send_message(struct IOProcList* ioProc, LPMMIOINFO mmioinfo,
  */
 static FOURCC MMIO_ParseExtA(LPCSTR szFileName)
 {
-    /* Filenames are of the form file.ext+ABC
-       FIXME: What if a '+' is part of the file name?
-       For now, we take the last '+' present */
+    /* 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 */
     LPSTR extEnd;
+    LPSTR extStart;
 
     TRACE("(%s)\n", debugstr_a(szFileName));
 
     if (!szFileName)
        return ret;
-    extEnd = strrchr(szFileName,'+');
-    if (extEnd) {
-       /* Need to parse to find the extension */
-       LPSTR extStart;
-
-       extStart = extEnd;
-       while (extStart >= szFileName && extStart[0] != '.') {
-           extStart--;
-       }
 
-       if (extStart < szFileName) {
-           ERR("+ but no . in szFileName: %s\n", debugstr_a(szFileName));
-       } else {
-           CHAR ext[5];
-
-           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);
-       }
+    /* Find the last '.' */
+    extStart = strrchr(szFileName,'.');
+
+    if (!extStart) {
+         ERR("No . in szFileName: %s\n", debugstr_a(szFileName));
+    } else {
+        CHAR ext[5];
+
+        /* Find the '+' afterwards */
+        extEnd = strchr(extStart,'+');
+        if (extEnd) {
+
+            if (extEnd - extStart - 1 > 4)
+                WARN("Extension length > 4\n");
+            lstrcpynA(ext, extStart + 1, min(extEnd-extStart,5));
+
+        } else {
+            /* No + so just an extension */
+            if (strlen(extStart) > 4) {
+                WARN("Extension length > 4\n");
+            }
+            lstrcpynA(ext, extStart + 1, 5);
+        }
+        TRACE("Got extension: %s\n", debugstr_a(ext));
+
+        /* FOURCC codes identifying file-extensions must be uppercase */
+        ret = mmioStringToFOURCCA(ext, MMIO_TOUPPER);
     }
     return ret;
 }
@@ -435,12 +440,12 @@ LPWINE_MMIO       MMIO_Get(HMMIO h)
 {
     LPWINE_MMIO                wm = NULL;
 
-    EnterCriticalSection(&WINMM_IData->cs);
-    for (wm = WINMM_IData->lpMMIO; wm; wm = wm->lpNext) {
+    EnterCriticalSection(&WINMM_IData.cs);
+    for (wm = WINMM_IData.lpMMIO; wm; wm = wm->lpNext) {
        if (wm->info.hmmio == h)
            break;
     }
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
     return wm;
 }
 
@@ -456,13 +461,13 @@ static    LPWINE_MMIO             MMIO_Create(void)
 
     wm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MMIO));
     if (wm) {
-       EnterCriticalSection(&WINMM_IData->cs);
+       EnterCriticalSection(&WINMM_IData.cs);
         /* lookup next unallocated WORD handle, with a non NULL value */
-       while (++MMIO_counter == 0 || MMIO_Get(HMMIO_32(MMIO_counter)));
-       wm->info.hmmio = HMMIO_32(MMIO_counter);
-       wm->lpNext = WINMM_IData->lpMMIO;
-       WINMM_IData->lpMMIO = wm;
-       LeaveCriticalSection(&WINMM_IData->cs);
+       while (++MMIO_counter == 0 || MMIO_Get((HMMIO)(ULONG_PTR)MMIO_counter));
+       wm->info.hmmio = (HMMIO)(ULONG_PTR)MMIO_counter;
+       wm->lpNext = WINMM_IData.lpMMIO;
+       WINMM_IData.lpMMIO = wm;
+       LeaveCriticalSection(&WINMM_IData.cs);
     }
     return wm;
 }
@@ -476,9 +481,9 @@ static      BOOL            MMIO_Destroy(LPWINE_MMIO wm)
 {
     LPWINE_MMIO*       m;
 
-    EnterCriticalSection(&WINMM_IData->cs);
+    EnterCriticalSection(&WINMM_IData.cs);
     /* search for the matching one... */
-    m = &(WINMM_IData->lpMMIO);
+    m = &(WINMM_IData.lpMMIO);
     while (*m && *m != wm) m = &(*m)->lpNext;
     /* ...and destroy */
     if (*m) {
@@ -486,7 +491,7 @@ static      BOOL            MMIO_Destroy(LPWINE_MMIO wm)
        HeapFree(GetProcessHeap(), 0, wm);
        wm = NULL;
     }
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
     return wm ? FALSE : TRUE;
 }
 
@@ -529,14 +534,16 @@ static LONG       MMIO_GrabNextBuffer(LPWINE_MMIO wm, int for_read)
     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, MMIO_PROC_32A);
        if (size > 0)
            wm->info.pchEndRead += size;
+        else
+            wm->bBufferLoaded = FALSE;
     }
 
-    wm->bBufferLoaded = TRUE;
     return size;
 }
 
@@ -562,13 +569,6 @@ static MMRESULT MMIO_SetBuffer(WINE_MMIO* wm, void* pchBuffer, LONG cchBuffer,
        wm->info.dwFlags &= ~MMIO_ALLOCBUF;
     }
 
-    /* free segmented ptr mapping, if any */
-    if (wm->info.dwReserved1 != 0L)
-    {
-        UnMapLS(wm->info.dwReserved1);
-        wm->info.dwReserved1 = 0L;
-    }
-
     if (pchBuffer) {
         wm->info.pchBuffer = pchBuffer;
     } else if (cchBuffer) {
@@ -579,9 +579,6 @@ static MMRESULT MMIO_SetBuffer(WINE_MMIO* wm, void* pchBuffer, LONG cchBuffer,
        wm->info.pchBuffer = NULL;
     }
 
-    if (wm->ioProc->type == MMIO_PROC_16)
-        wm->info.dwReserved1 = MapLS(wm->info.pchBuffer);
-
     wm->info.cchBuffer = cchBuffer;
     wm->info.pchNext = wm->info.pchBuffer;
     wm->info.pchEndRead = wm->info.pchBuffer;
@@ -617,8 +614,8 @@ HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags,
        char    buffer[MAX_PATH];
 
        if (GetFullPathNameA(szFileName, sizeof(buffer), buffer, NULL) >= sizeof(buffer))
-           return (HMMIO16)FALSE;
-       if ((dwOpenFlags & MMIO_EXIST) && (GetFileAttributesA(buffer) == -1))
+           return (HMMIO)FALSE;
+       if ((dwOpenFlags & MMIO_EXIST) && (GetFileAttributesA(buffer) == INVALID_FILE_ATTRIBUTES))
            return (HMMIO)FALSE;
        strcpy(szFileName, buffer);
        return (HMMIO)TRUE;
@@ -633,7 +630,12 @@ HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags,
        /* Handle any unhandled/error case. Assume DOS file */
        if (wm->info.fccIOProc == 0)
            wm->info.fccIOProc = FOURCC_DOS;
-       if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) goto error2;
+       if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) {
+           /* If not found, retry with FOURCC_DOS */
+           wm->info.fccIOProc = FOURCC_DOS;
+           if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc)))
+               goto error2;
+       }
        wm->bTmpIOProc = FALSE;
     }
     /* if just the four character code is present, look up IO proc */
@@ -674,7 +676,7 @@ HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags,
                                         (LPARAM)szFileName, 0, MMIO_PROC_32A);
 
     /* grab file size, when possible */
-    wm->dwFileSize = GetFileSize(wm->info.adwInfo[0], NULL);
+    wm->dwFileSize = GetFileSize((HANDLE)wm->info.adwInfo[0], NULL);
 
     if (refmminfo->wErrorRet == 0)
        return wm->info.hmmio;
@@ -692,7 +694,15 @@ HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO* lpmmioinfo,
                       DWORD dwOpenFlags)
 {
     HMMIO      ret;
-    LPSTR      szFn = HEAP_strdupWtoA(GetProcessHeap(), 0, szFileName);
+    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, MMIO_PROC_32W);
 
@@ -717,7 +727,7 @@ MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
     LPWINE_MMIO        wm;
     MMRESULT   result;
 
-    TRACE("(%04X, %04X);\n", hmmio, uFlags);
+    TRACE("(%p, %04X);\n", hmmio, uFlags);
 
     if ((wm = MMIO_Get(hmmio)) == NULL)
        return MMSYSERR_INVALHANDLE;
@@ -749,7 +759,7 @@ LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
     LPWINE_MMIO        wm;
     LONG       count;
 
-    TRACE("(%04X, %p, %ld);\n", hmmio, pch, cch);
+    TRACE("(%p, %p, %ld);\n", hmmio, pch, cch);
 
     if ((wm = MMIO_Get(hmmio)) == NULL)
        return -1;
@@ -799,7 +809,7 @@ LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
     LPWINE_MMIO        wm;
     LONG       count;
 
-    TRACE("(%04X, %p, %ld);\n", hmmio, pch, cch);
+    TRACE("(%p, %p, %ld);\n", hmmio, pch, cch);
 
     if ((wm = MMIO_Get(hmmio)) == NULL)
        return -1;
@@ -854,7 +864,7 @@ LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
     LPWINE_MMIO        wm;
     LONG       offset;
 
-    TRACE("(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
+    TRACE("(%p, %08lX, %d);\n", hmmio, lOffset, iOrigin);
 
     if ((wm = MMIO_Get(hmmio)) == NULL)
        return MMSYSERR_INVALHANDLE;
@@ -919,7 +929,7 @@ MMRESULT WINAPI mmioGetInfo(HMMIO hmmio, MMIOINFO* lpmmioinfo, UINT uFlags)
 {
     LPWINE_MMIO                wm;
 
-    TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
+    TRACE("(%p,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
 
     if ((wm = MMIO_Get(hmmio)) == NULL)
        return MMSYSERR_INVALHANDLE;
@@ -939,7 +949,7 @@ MMRESULT WINAPI mmioSetInfo(HMMIO hmmio, const MMIOINFO* lpmmioinfo, UINT uFlags
 {
     LPWINE_MMIO                wm;
 
-    TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
+    TRACE("(%p,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
 
     if ((wm = MMIO_Get(hmmio)) == NULL)
        return MMSYSERR_INVALHANDLE;
@@ -966,7 +976,7 @@ MMRESULT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT
 {
     LPWINE_MMIO                wm;
 
-    TRACE("(hmmio=%04x, pchBuf=%p, cchBuf=%ld, uFlags=%#08x)\n",
+    TRACE("(hmmio=%p, pchBuf=%p, cchBuf=%ld, uFlags=%#08x)\n",
          hmmio, pchBuffer, cchBuffer, uFlags);
 
     if ((wm = MMIO_Get(hmmio)) == NULL)
@@ -982,7 +992,7 @@ MMRESULT WINAPI mmioFlush(HMMIO hmmio, UINT uFlags)
 {
     LPWINE_MMIO                wm;
 
-    TRACE("(%04X, %04X)\n", hmmio, uFlags);
+    TRACE("(%p, %04X)\n", hmmio, uFlags);
 
     if ((wm = MMIO_Get(hmmio)) == NULL)
        return MMSYSERR_INVALHANDLE;
@@ -997,7 +1007,7 @@ MMRESULT WINAPI mmioAdvance(HMMIO hmmio, MMIOINFO* lpmmioinfo, UINT uFlags)
 {
     LPWINE_MMIO                wm;
 
-    TRACE("hmmio=%04X, lpmmioinfo=%p, uFlags=%04X\n", hmmio, lpmmioinfo, uFlags);
+    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
@@ -1069,11 +1079,10 @@ FOURCC WINAPI mmioStringToFOURCCA(LPCSTR sz, UINT uFlags)
  */
 FOURCC WINAPI mmioStringToFOURCCW(LPCWSTR sz, UINT uFlags)
 {
-    LPSTR      szA = HEAP_strdupWtoA(GetProcessHeap(),0,sz);
-    FOURCC     ret = mmioStringToFOURCCA(szA,uFlags);
+    char       szA[4];
 
-    HeapFree(GetProcessHeap(), 0, szA);
-    return ret;
+    WideCharToMultiByte( CP_ACP, 0, sz, 4, szA, sizeof(szA), NULL, NULL );
+    return mmioStringToFOURCCA(szA,uFlags);
 }
 
 /**************************************************************************
@@ -1104,7 +1113,7 @@ LRESULT         MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
 {
     LPWINE_MMIO                wm;
 
-    TRACE("(%04X, %u, %ld, %ld, %d)\n", hmmio, uMessage, lParam1, lParam2, type);
+    TRACE("(%p, %u, %ld, %ld, %d)\n", hmmio, uMessage, lParam1, lParam2, type);
 
     if (uMessage < MMIOM_USER)
        return MMSYSERR_INVALPARAM;
@@ -1134,8 +1143,7 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck,
     FOURCC             srchCkId;
     FOURCC             srchType;
 
-
-    TRACE("(%04X, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags);
+    TRACE("(%p, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags);
 
     if (lpck == NULL)
        return MMSYSERR_INVALPARAM;
@@ -1157,62 +1165,54 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck,
      * 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) {
+    if (uFlags & MMIO_FINDLIST)
+    {
        srchCkId = FOURCC_LIST;
-       srchType = lpck->fccType;
+        srchType = lpck->fccType;
     }
-    if (uFlags & MMIO_FINDRIFF) {
+
+    if (uFlags & MMIO_FINDRIFF)
+    {
        srchCkId = FOURCC_RIFF;
-       srchType = lpck->fccType;
+        srchType = lpck->fccType;
     }
 
-    if (uFlags & (MMIO_FINDCHUNK|MMIO_FINDLIST|MMIO_FINDRIFF)) {
-       TRACE("searching for %.4s.%.4s\n",
-             (LPSTR)&srchCkId,
-             srchType?(LPSTR)&srchType:"any ");
-
-       while (TRUE) {
-           LONG ix;
+    TRACE("searching for %4.4s.%4.4s\n",
+          (LPCSTR)&srchCkId, srchType ? (LPCSTR)&srchType : "any");
 
-           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);
-           if (ix < lpck->dwDataOffset - dwOldPos) {
-               mmioSeek(hmmio, dwOldPos, SEEK_SET);
-               WARN("return ChunkNotFound\n");
-               return MMIOERR_CHUNKNOTFOUND;
-           }
-           TRACE("ckid=%.4s fcc=%.4s cksize=%08lX !\n",
-                 (LPSTR)&lpck->ckid,
-                 srchType?(LPSTR)&lpck->fccType:"<na>",
-                 lpck->cksize);
-           if ((srchCkId == lpck->ckid) &&
-               (!srchType || (srchType == lpck->fccType))
-               )
-               break;
+    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;
+        }
 
-           dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1);
-           mmioSeek(hmmio, dwOldPos, SEEK_SET);
-       }
-    } else {
-       /* FIXME: unverified, does it do this? */
-       /* NB: This part is used by WAVE_mciOpen, among others */
-       if (mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD)) < 3 * sizeof(DWORD)) {
-           mmioSeek(hmmio, dwOldPos, SEEK_SET);
-           WARN("return ChunkNotFound 2nd\n");
-           return MMIOERR_CHUNKNOTFOUND;
-       }
-       lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
+        lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
+        TRACE("ckid=%4.4s fcc=%4.4s cksize=%08lX !\n",
+              (LPCSTR)&lpck->ckid,
+              srchType ? (LPCSTR)&lpck->fccType:"<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
@@ -1233,7 +1233,7 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck,
  */
 MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
 {
-    TRACE("(%04X, %p, %04X);\n", hmmio, lpck, uFlags);
+    TRACE("(%p, %p, %04X);\n", hmmio, lpck, uFlags);
 
     if (lpck->dwFlags & MMIO_DIRTY) {
        DWORD   dwOldPos, dwNewSize;
@@ -1271,7 +1271,7 @@ MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO* lpck, UINT uFlags)
     LONG       size;
     LONG       ix;
 
-    TRACE("(%04X, %p, %04X);\n", hmmio, lpck, uFlags);
+    TRACE("(%p, %p, %04X);\n", hmmio, lpck, uFlags);
 
     dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
     TRACE("dwOldPos=%ld\n", dwOldPos);
@@ -1305,20 +1305,24 @@ MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO* lpck, UINT uFlags)
  *                             mmioRenameA                     [WINMM.@]
  */
 MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
-                            MMIOINFO* lpmmioinfo, DWORD dwFlags)
+                            const MMIOINFO* lpmmioinfo, DWORD dwFlags)
 {
     struct IOProcList*  ioProc = NULL;
     struct IOProcList   tmp;
+    FOURCC              fcc;
 
     TRACE("('%s', '%s', %p, %08lX);\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)
-       lpmmioinfo->fccIOProc = MMIO_ParseExtA(szFileName);
+    {
+       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))
+    if (!lpmmioinfo || (lpmmioinfo->fccIOProc == 0 && lpmmioinfo->pIOProc == NULL && ioProc == NULL))
        ioProc = MMIO_FindProcNode(FOURCC_DOS);
     /* if just the four character code is present, look up IO proc */
     else if (lpmmioinfo->pIOProc == NULL)
@@ -1332,7 +1336,10 @@ MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
         tmp.count = 1;
     }
 
-    return send_message(ioProc, lpmmioinfo, MMIOM_RENAME,
+    /* 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, MMIO_PROC_32A);
 }
 
@@ -1340,12 +1347,31 @@ MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
  *                             mmioRenameW                     [WINMM.@]
  */
 MMRESULT WINAPI mmioRenameW(LPCWSTR szFileName, LPCWSTR szNewFileName,
-                            MMIOINFO* lpmmioinfo, DWORD dwFlags)
+                            const MMIOINFO* lpmmioinfo, DWORD dwFlags)
 {
-    LPSTR      szFn = HEAP_strdupWtoA(GetProcessHeap(), 0, szFileName);
-    LPSTR      sznFn = HEAP_strdupWtoA(GetProcessHeap(), 0, szNewFileName);
-    UINT       ret = mmioRenameA(szFn, sznFn, lpmmioinfo, 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;