4 * Copyright 1998 Andrew Taylor
6 * NOTES: I/O is still unbuffered; mmioSetBuffer must be implemented
7 * and mmio{Read,Write,Seek,others?} need buffer support.
8 * Buffering should almost give us memory files for free.
25 /**************************************************************************
26 * mmioDosIOProc [internal]
28 static LRESULT
mmioDosIOProc(LPMMIOINFO16 lpmmioinfo
, UINT16 uMessage
, LPARAM lParam1
, LPARAM lParam2
) {
29 TRACE(mmio
, "(%p, %X, %ld, %ld);\n", lpmmioinfo
, uMessage
, lParam1
, lParam2
);
35 * lParam1 = szFileName parameter from mmioOpen
37 * Returns: zero on success, error code on error
38 * NOTE: lDiskOffset automatically set to zero
42 LPSTR szFileName
= (LPSTR
) lParam1
;
44 if (lpmmioinfo
->dwFlags
& MMIO_GETTEMP
) {
45 FIXME(mmio
, "MMIO_GETTEMP not implemented\n");
46 return MMIOERR_CANNOTOPEN
;
49 /* if filename NULL, assume open file handle in adwInfo[0] */
53 lpmmioinfo
->adwInfo
[0] =
54 (DWORD
) OpenFile32(szFileName
, &ofs
, lpmmioinfo
->dwFlags
);
55 if (lpmmioinfo
->adwInfo
[0] == -1)
56 return MMIOERR_CANNOTOPEN
;
63 * lParam1 = wFlags parameter from mmioClose
65 * Returns: zero on success, error code on error
68 UINT16 uFlags
= (UINT16
) lParam1
;
70 if (uFlags
& MMIO_FHOPEN
)
73 _lclose32((HFILE32
)lpmmioinfo
->adwInfo
[0]);
80 * lParam1 = huge pointer to read buffer
81 * lParam2 = number of bytes to read
82 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
84 * NOTE: lDiskOffset should be updated
87 HPSTR pch
= (HPSTR
) lParam1
;
88 LONG cch
= (LONG
) lParam2
;
91 count
= _lread32((HFILE32
)lpmmioinfo
->adwInfo
[0], pch
, cch
);
93 lpmmioinfo
->lDiskOffset
+= count
;
99 case MMIOM_WRITEFLUSH
: {
100 /* no internal buffering, so WRITEFLUSH handled same as WRITE */
103 * lParam1 = huge pointer to write buffer
104 * lParam2 = number of bytes to write
105 * Returns: number of bytes written, -1 for error (error code in
107 * NOTE: lDiskOffset should be updated
110 HPSTR pch
= (HPSTR
) lParam1
;
111 LONG cch
= (LONG
) lParam2
;
114 count
= _hwrite16((HFILE32
)lpmmioinfo
->adwInfo
[0], pch
, cch
);
116 lpmmioinfo
->lDiskOffset
+= count
;
123 * lParam1 = new position
124 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
125 * Returns: new file postion, -1 on error
126 * NOTE: lDiskOffset should be updated
129 LONG Offset
= (LONG
) lParam1
;
130 LONG Whence
= (LONG
) lParam2
;
133 pos
= _llseek32((HFILE32
)lpmmioinfo
->adwInfo
[0], Offset
, Whence
);
135 lpmmioinfo
->lDiskOffset
= pos
;
144 * Returns: zero on success, non-zero on failure
147 FIXME(mmio
, "MMIOM_RENAME unimplemented\n");
148 return MMIOERR_FILENOTFOUND
;
152 WARN(mmio
, "unexpected message %u\n", uMessage
);
159 /**************************************************************************
160 * mmioDosIOProc [internal]
162 static LRESULT
mmioMemIOProc(LPMMIOINFO16 lpmmioinfo
, UINT16 uMessage
, LPARAM lParam1
, LPARAM lParam2
) {
166 /**************************************************************************
167 * mmioOpenW [WINMM.123]
169 HMMIO32 WINAPI
mmioOpen32W(LPWSTR szFileName
, MMIOINFO32
* lpmmioinfo
,
172 LPSTR szFn
= HEAP_strdupWtoA(GetProcessHeap(),0,szFileName
);
173 HMMIO32 ret
= mmioOpen16(szFn
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
);
175 HeapFree(GetProcessHeap(),0,szFn
);
179 /**************************************************************************
180 * mmioOpenA [WINMM.122]
182 HMMIO32 WINAPI
mmioOpen32A(LPSTR szFileName
, MMIOINFO32
* lpmmioinfo
,
185 return mmioOpen16(szFileName
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
);
188 /**************************************************************************
189 * mmioOpen [MMSYSTEM.1210]
191 HMMIO16 WINAPI
mmioOpen16(LPSTR szFileName
, MMIOINFO16
* lpmmioinfo
,
194 LPMMIOINFO16 lpmminfo
;
198 TRACE(mmio
, "('%s', %p, %08lX);\n", szFileName
, lpmmioinfo
, dwOpenFlags
);
200 hmmio
= GlobalAlloc16(GHND
, sizeof(MMIOINFO16
));
201 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
202 if (lpmminfo
== NULL
)
204 memset(lpmminfo
, 0, sizeof(MMIOINFO16
));
206 /* assume DOS file if not otherwise specified */
208 (lpmmioinfo
->fccIOProc
== 0 && lpmmioinfo
->pIOProc
== NULL
)) {
210 lpmminfo
->fccIOProc
= mmioFOURCC('D', 'O', 'S', ' ');
211 lpmminfo
->pIOProc
= (LPMMIOPROC16
) mmioDosIOProc
;
213 /* if just the four character code is present, look up IO proc */
214 else if (lpmmioinfo
->pIOProc
== NULL
) {
216 lpmminfo
->fccIOProc
= lpmmioinfo
->fccIOProc
;
217 lpmminfo
->pIOProc
= mmioInstallIOProc16(lpmmioinfo
->fccIOProc
, NULL
, MMIO_FINDPROC
);
220 /* if IO proc specified, use it and specified four character code */
223 lpmminfo
->fccIOProc
= lpmmioinfo
->fccIOProc
;
224 lpmminfo
->pIOProc
= lpmmioinfo
->pIOProc
;
227 if (dwOpenFlags
& MMIO_ALLOCBUF
) {
228 if ((result
= mmioSetBuffer(hmmio
, NULL
, MMIO_DEFAULTBUFFER
, 0))) {
230 lpmmioinfo
->wErrorRet
= result
;
235 lpmminfo
->hmmio
= hmmio
;
237 /* call IO proc to actually open file */
238 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_OPEN
, (LPARAM
) szFileName
, (LPARAM
) 0);
240 GlobalUnlock16(hmmio
);
251 /**************************************************************************
252 * mmioClose [MMSYSTEM.1211]
254 UINT16 WINAPI
mmioClose(HMMIO16 hmmio
, UINT16 uFlags
)
256 LPMMIOINFO16 lpmminfo
;
259 TRACE(mmio
, "(%04X, %04X);\n", hmmio
, uFlags
);
261 lpmminfo
= (LPMMIOINFO16
) GlobalLock16(hmmio
);
262 if (lpmminfo
== NULL
)
265 /* flush the file - if error reported, ignore */
266 if (mmioFlush(hmmio
, MMIO_EMPTYBUF
) != 0)
267 lpmminfo
->dwFlags
&= ~MMIO_DIRTY
;
269 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_CLOSE
, (LPARAM
) uFlags
, (LPARAM
) 0);
271 mmioSetBuffer(hmmio
, NULL
, 0, 0);
273 GlobalUnlock16(hmmio
);
281 /**************************************************************************
282 * mmioRead [MMSYSTEM.1212]
284 LONG WINAPI
mmioRead(HMMIO16 hmmio
, HPSTR pch
, LONG cch
)
287 LPMMIOINFO16 lpmminfo
;
289 TRACE(mmio
, "(%04X, %p, %ld);\n", hmmio
, pch
, cch
);
291 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
292 if (lpmminfo
== NULL
)
295 count
= mmioSendMessage(hmmio
, MMIOM_READ
, (LPARAM
) pch
, (LPARAM
) cch
);
297 GlobalUnlock16(hmmio
);
298 TRACE(mmio
, "count=%ld\n", count
);
304 /**************************************************************************
305 * mmioWrite [MMSYSTEM.1213]
307 LONG WINAPI
mmioWrite(HMMIO16 hmmio
, HPCSTR pch
, LONG cch
)
310 LPMMIOINFO16 lpmminfo
;
312 TRACE(mmio
, "(%04X, %p, %ld);\n", hmmio
, pch
, cch
);
314 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
315 if (lpmminfo
== NULL
)
318 count
= mmioSendMessage(hmmio
, MMIOM_WRITE
, (LPARAM
) pch
, (LPARAM
) cch
);
320 GlobalUnlock16(hmmio
);
321 TRACE(mmio
, "count=%ld\n", count
);
325 /**************************************************************************
326 * mmioSeek [MMSYSTEM.1214]
328 LONG WINAPI
mmioSeek(HMMIO16 hmmio
, LONG lOffset
, int iOrigin
)
331 LPMMIOINFO16 lpmminfo
;
333 TRACE(mmio
, "(%04X, %08lX, %d);\n", hmmio
, lOffset
, iOrigin
);
335 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
336 if (lpmminfo
== NULL
)
339 offset
= mmioSendMessage(hmmio
, MMIOM_SEEK
, (LPARAM
) lOffset
, (LPARAM
) iOrigin
);
341 GlobalUnlock16(hmmio
);
345 /**************************************************************************
346 * mmioGetInfo [MMSYSTEM.1215]
348 UINT16 WINAPI
mmioGetInfo(HMMIO16 hmmio
, MMIOINFO16
* lpmmioinfo
, UINT16 uFlags
)
350 LPMMIOINFO16 lpmminfo
;
351 TRACE(mmio
, "mmioGetInfo\n");
352 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
353 if (lpmminfo
== NULL
) return 0;
354 memcpy(lpmmioinfo
, lpmminfo
, sizeof(MMIOINFO16
));
355 GlobalUnlock16(hmmio
);
359 /**************************************************************************
360 * mmioSetInfo [MMSYSTEM.1216]
362 UINT16 WINAPI
mmioSetInfo(HMMIO16 hmmio
, const MMIOINFO16
* lpmmioinfo
, UINT16 uFlags
)
364 LPMMIOINFO16 lpmminfo
;
365 TRACE(mmio
, "mmioSetInfo\n");
366 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
367 if (lpmminfo
== NULL
) return 0;
368 GlobalUnlock16(hmmio
);
372 /**************************************************************************
373 * mmioSetBuffer [MMSYSTEM.1217]
375 UINT16 WINAPI
mmioSetBuffer(HMMIO16 hmmio
, LPSTR pchBuffer
,
376 LONG cchBuffer
, UINT16 uFlags
)
378 FIXME(mmio
, "empty stub \n");
382 /**************************************************************************
383 * mmioFlush [MMSYSTEM.1218]
385 UINT16 WINAPI
mmioFlush(HMMIO16 hmmio
, UINT16 uFlags
)
387 LPMMIOINFO16 lpmminfo
;
388 TRACE(mmio
, "(%04X, %04X)\n", hmmio
, uFlags
);
389 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
390 if (lpmminfo
== NULL
) return 0;
391 GlobalUnlock16(hmmio
);
395 /**************************************************************************
396 * mmioAdvance [MMSYSTEM.1219]
398 UINT16 WINAPI
mmioAdvance(HMMIO16 hmmio
, MMIOINFO16
* lpmmioinfo
, UINT16 uFlags
)
401 LPMMIOINFO16 lpmminfo
;
402 TRACE(mmio
, "mmioAdvance\n");
403 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
404 if (lpmminfo
== NULL
) return 0;
405 if (uFlags
== MMIO_READ
) {
406 count
= _lread32(LOWORD(lpmminfo
->adwInfo
[0]),
407 lpmmioinfo
->pchBuffer
, lpmmioinfo
->cchBuffer
);
409 if (uFlags
== MMIO_WRITE
) {
410 count
= _lwrite32(LOWORD(lpmminfo
->adwInfo
[0]),
411 lpmmioinfo
->pchBuffer
, lpmmioinfo
->cchBuffer
);
413 lpmmioinfo
->pchNext
+= count
;
414 GlobalUnlock16(hmmio
);
415 lpmminfo
->lDiskOffset
= _llseek32((HFILE32
)lpmminfo
->adwInfo
[0], 0, SEEK_CUR
);
419 /**************************************************************************
420 * mmioStringToFOURCCA [WINMM.131]
422 FOURCC WINAPI
mmioStringToFOURCC32A(LPCSTR sz
, UINT32 uFlags
)
424 return mmioStringToFOURCC16(sz
,uFlags
);
427 /**************************************************************************
428 * mmioStringToFOURCCW [WINMM.132]
430 FOURCC WINAPI
mmioStringToFOURCC32W(LPCWSTR sz
, UINT32 uFlags
)
432 LPSTR szA
= HEAP_strdupWtoA(GetProcessHeap(),0,sz
);
433 FOURCC ret
= mmioStringToFOURCC32A(szA
,uFlags
);
435 HeapFree(GetProcessHeap(),0,szA
);
439 /**************************************************************************
440 * mmioStringToFOURCC [MMSYSTEM.1220]
442 FOURCC WINAPI
mmioStringToFOURCC16(LPCSTR sz
, UINT16 uFlags
)
444 FIXME(mmio
, "empty stub \n");
448 /**************************************************************************
449 * mmioInstallIOProc16 [MMSYSTEM.1221]
451 LPMMIOPROC16 WINAPI
mmioInstallIOProc16(FOURCC fccIOProc
,
452 LPMMIOPROC16 pIOProc
, DWORD dwFlags
)
454 TRACE(mmio
, "(%ld, %p, %08lX)\n",
455 fccIOProc
, pIOProc
, dwFlags
);
457 if (dwFlags
& MMIO_GLOBALPROC
) {
458 FIXME(mmio
, " global procedures not implemented\n");
461 /* just handle the known procedures for now */
462 switch(dwFlags
& (MMIO_INSTALLPROC
|MMIO_REMOVEPROC
|MMIO_FINDPROC
)) {
463 case MMIO_INSTALLPROC
:
465 case MMIO_REMOVEPROC
:
468 if (fccIOProc
== FOURCC_DOS
)
469 return (LPMMIOPROC16
) mmioDosIOProc
;
470 else if (fccIOProc
== FOURCC_MEM
)
471 return (LPMMIOPROC16
) mmioMemIOProc
;
479 /**************************************************************************
480 * mmioInstallIOProc32A [WINMM.120]
482 LPMMIOPROC32 WINAPI
mmioInstallIOProc32A(FOURCC fccIOProc
,
483 LPMMIOPROC32 pIOProc
, DWORD dwFlags
)
485 FIXME(mmio
, "(%c%c%c%c,%p,0x%08lx) -- empty stub \n",
486 (char)((fccIOProc
&0xff000000)>>24),
487 (char)((fccIOProc
&0x00ff0000)>>16),
488 (char)((fccIOProc
&0x0000ff00)>> 8),
489 (char)(fccIOProc
&0x000000ff),
494 /**************************************************************************
495 * mmioSendMessage [MMSYSTEM.1222]
497 LRESULT WINAPI
mmioSendMessage(HMMIO16 hmmio
, UINT16 uMessage
,
498 LPARAM lParam1
, LPARAM lParam2
)
500 LPMMIOINFO16 lpmminfo
;
502 const char *msg
= NULL
;
506 #define msgname(x) case x: msg = #x; break;
508 msgname(MMIOM_CLOSE
);
510 msgname(MMIOM_WRITE
);
511 msgname(MMIOM_WRITEFLUSH
);
513 msgname(MMIOM_RENAME
);
519 TRACE(mmio
, "(%04X, %s, %ld, %ld)\n",
520 hmmio
, msg
, lParam1
, lParam2
);
522 TRACE(mmio
, "(%04X, %u, %ld, %ld)\n",
523 hmmio
, uMessage
, lParam1
, lParam2
);
525 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
527 if (lpmminfo
&& lpmminfo
->pIOProc
)
528 result
= (*lpmminfo
->pIOProc
)((LPSTR
)lpmminfo
, uMessage
, lParam1
, lParam2
);
530 result
= MMSYSERR_INVALPARAM
;
532 GlobalUnlock16(hmmio
);
537 /**************************************************************************
538 * mmioDescend [MMSYSTEM.1223]
540 UINT16 WINAPI
mmioDescend(HMMIO16 hmmio
, MMCKINFO
* lpck
,
541 const MMCKINFO
* lpckParent
, UINT16 uFlags
)
543 DWORD dwfcc
, dwOldPos
;
545 TRACE(mmio
, "(%04X, %p, %p, %04X);\n",
546 hmmio
, lpck
, lpckParent
, uFlags
);
552 TRACE(mmio
, "dwfcc=%08lX\n", dwfcc
);
554 dwOldPos
= mmioSeek(hmmio
, 0, SEEK_CUR
);
555 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
557 if (lpckParent
!= NULL
) {
558 TRACE(mmio
, "seek inside parent at %ld !\n", lpckParent
->dwDataOffset
);
559 dwOldPos
= mmioSeek(hmmio
, lpckParent
->dwDataOffset
, SEEK_SET
);
563 It seems to be that FINDRIFF should not be treated the same as the
564 other FINDxxx so I treat it as a MMIO_FINDxxx
566 if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDRIFF) ||
567 (uFlags & MMIO_FINDLIST)) {
569 if ((uFlags
& MMIO_FINDCHUNK
) || (uFlags
& MMIO_FINDLIST
)) {
570 TRACE(mmio
, "MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc
);
574 ix
= mmioRead(hmmio
, (LPSTR
)lpck
, sizeof(MMCKINFO
));
575 TRACE(mmio
, "after _lread32 ix = %ld req = %d, errno = %d\n",ix
,sizeof(MMCKINFO
),errno
);
576 if (ix
< sizeof(MMCKINFO
)) {
578 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
579 WARN(mmio
, "return ChunkNotFound\n");
580 return MMIOERR_CHUNKNOTFOUND
;
582 TRACE(mmio
, "dwfcc=%08lX ckid=%08lX cksize=%08lX !\n",
583 dwfcc
, lpck
->ckid
, lpck
->cksize
);
584 if (dwfcc
== lpck
->ckid
)
587 dwOldPos
+= lpck
->cksize
+ 2 * sizeof(DWORD
);
588 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
589 dwOldPos
+= sizeof(DWORD
);
590 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
594 if (mmioRead(hmmio
, (LPSTR
)lpck
, sizeof(MMCKINFO
)) < sizeof(MMCKINFO
)) {
595 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
596 WARN(mmio
, "return ChunkNotFound 2nd\n");
597 return MMIOERR_CHUNKNOTFOUND
;
600 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
601 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
602 lpck
->dwDataOffset
+= sizeof(DWORD
);
603 mmioSeek(hmmio
, lpck
->dwDataOffset
, SEEK_SET
);
605 TRACE(mmio
, "lpck->ckid=%08lX lpck->cksize=%ld !\n",
606 lpck
->ckid
, lpck
->cksize
);
607 TRACE(mmio
, "lpck->fccType=%08lX !\n", lpck
->fccType
);
612 /**************************************************************************
613 * mmioAscend [MMSYSTEM.1224]
615 UINT16 WINAPI
mmioAscend(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
617 FIXME(mmio
, "empty stub !\n");
621 /**************************************************************************
622 * mmioCreateChunk [MMSYSTEM.1225]
624 UINT16 WINAPI
mmioCreateChunk(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
626 FIXME(mmio
, "empty stub \n");
631 /**************************************************************************
632 * mmioRename [MMSYSTEM.1226]
634 UINT16 WINAPI
mmioRename(LPCSTR szFileName
, LPCSTR szNewFileName
,
635 MMIOINFO16
* lpmmioinfo
, DWORD dwRenameFlags
)
638 LPMMIOINFO16 lpmminfo
;
641 TRACE(mmio
, "('%s', '%s', %p, %08lX);\n",
642 szFileName
, szNewFileName
, lpmmioinfo
, dwRenameFlags
);
644 hmmio
= GlobalAlloc16(GHND
, sizeof(MMIOINFO16
));
645 lpmminfo
= (LPMMIOINFO16
) GlobalLock16(hmmio
);
648 memcpy(lpmminfo
, lpmmioinfo
, sizeof(MMIOINFO16
));
650 /* assume DOS file if not otherwise specified */
651 if (lpmminfo
->fccIOProc
== 0 && lpmminfo
->pIOProc
== NULL
) {
653 lpmminfo
->fccIOProc
= mmioFOURCC('D', 'O', 'S', ' ');
654 lpmminfo
->pIOProc
= (LPMMIOPROC16
) mmioDosIOProc
;
657 /* if just the four character code is present, look up IO proc */
658 else if (lpmminfo
->pIOProc
== NULL
) {
660 lpmminfo
->pIOProc
= mmioInstallIOProc16(lpmminfo
->fccIOProc
, NULL
, MMIO_FINDPROC
);
663 /* (if IO proc specified, use it and specified four character code) */
665 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_RENAME
, (LPARAM
) szFileName
, (LPARAM
) szNewFileName
);
667 GlobalUnlock16(hmmio
);