-/* -*- 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]
*/
}
/* 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);
}
FIXME("unexpected message %u\n", uMessage);
return 0;
}
-
- return 0;
}
/* This array will be the entire list for most apps
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");
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:
*/
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;
}
{
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;
}
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;
}
{
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) {
HeapFree(GetProcessHeap(), 0, wm);
wm = NULL;
}
- LeaveCriticalSection(&WINMM_IData->cs);
+ LeaveCriticalSection(&WINMM_IData.cs);
return wm ? FALSE : TRUE;
}
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;
}
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) {
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;
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;
/* 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 */
(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;
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);
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;
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;
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;
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;
{
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;
{
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;
{
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)
{
LPWINE_MMIO wm;
- TRACE("(%04X, %04X)\n", hmmio, uFlags);
+ TRACE("(%p, %04X)\n", hmmio, uFlags);
if ((wm = MMIO_Get(hmmio)) == NULL)
return MMSYSERR_INVALHANDLE;
{
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
*/
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);
}
/**************************************************************************
{
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;
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;
* 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
*/
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;
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);
* 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)
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);
}
* 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;