/************************************************************************** * 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, MMIO_PROC_32A); wm->info.lBufOffset = wm->info.lDiskOffset; } TRACE("bytes written=%d\n", count); return count; }
/************************************************************************** * 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, MMIO_PROC_32A); send_message(wm->ioProc, &wm->info, MMIOM_WRITE, (LPARAM)lpmmioinfo->pchBuffer, lpmmioinfo->pchNext - lpmmioinfo->pchBuffer, MMIO_PROC_32A); 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; }
/************************************************************************** * 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; }