4 * Copyright 1998 Andrew Taylor
5 * Copyright 1998 Ove Kåven
14 #include "wine/winbase16.h"
21 /**************************************************************************
22 * mmioDosIOProc [internal]
24 static LRESULT
mmioDosIOProc(LPMMIOINFO16 lpmmioinfo
, UINT16 uMessage
, LPARAM lParam1
, LPARAM lParam2
) {
25 TRACE(mmio
, "(%p, %X, %ld, %ld);\n", lpmmioinfo
, uMessage
, lParam1
, lParam2
);
31 * lParam1 = szFileName parameter from mmioOpen
32 * lParam2 = reserved (we use it for 16-bitness)
33 * Returns: zero on success, error code on error
34 * NOTE: lDiskOffset automatically set to zero
38 LPSTR szFileName
= (LPSTR
) lParam1
;
40 if (lpmmioinfo
->dwFlags
& MMIO_GETTEMP
) {
41 FIXME(mmio
, "MMIO_GETTEMP not implemented\n");
42 return MMIOERR_CANNOTOPEN
;
45 /* if filename NULL, assume open file handle in adwInfo[0] */
47 if (lParam2
) lpmmioinfo
->adwInfo
[0] =
48 FILE_GetHandle(lpmmioinfo
->adwInfo
[0]);
52 lpmmioinfo
->adwInfo
[0] =
53 (DWORD
) OpenFile(szFileName
, &ofs
, lpmmioinfo
->dwFlags
);
54 if (lpmmioinfo
->adwInfo
[0] == -1)
55 return MMIOERR_CANNOTOPEN
;
62 * lParam1 = wFlags parameter from mmioClose
64 * Returns: zero on success, error code on error
67 UINT16 uFlags
= (UINT16
) lParam1
;
69 if (uFlags
& MMIO_FHOPEN
)
72 _lclose((HFILE
)lpmmioinfo
->adwInfo
[0]);
79 * lParam1 = huge pointer to read buffer
80 * lParam2 = number of bytes to read
81 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
83 * NOTE: lDiskOffset should be updated
86 HPSTR pch
= (HPSTR
) lParam1
;
87 LONG cch
= (LONG
) lParam2
;
90 count
= _lread((HFILE
)lpmmioinfo
->adwInfo
[0], pch
, cch
);
92 lpmmioinfo
->lDiskOffset
+= count
;
98 case MMIOM_WRITEFLUSH
: {
99 /* no internal buffering, so WRITEFLUSH handled same as WRITE */
102 * lParam1 = huge pointer to write buffer
103 * lParam2 = number of bytes to write
104 * Returns: number of bytes written, -1 for error (error code in
106 * NOTE: lDiskOffset should be updated
109 HPSTR pch
= (HPSTR
) lParam1
;
110 LONG cch
= (LONG
) lParam2
;
113 count
= _hwrite((HFILE
)lpmmioinfo
->adwInfo
[0], pch
, cch
);
115 lpmmioinfo
->lDiskOffset
+= count
;
122 * lParam1 = new position
123 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
124 * Returns: new file postion, -1 on error
125 * NOTE: lDiskOffset should be updated
128 LONG Offset
= (LONG
) lParam1
;
129 LONG Whence
= (LONG
) lParam2
;
132 pos
= _llseek((HFILE
)lpmmioinfo
->adwInfo
[0], Offset
, Whence
);
134 lpmmioinfo
->lDiskOffset
= pos
;
143 * Returns: zero on success, non-zero on failure
146 FIXME(mmio
, "MMIOM_RENAME unimplemented\n");
147 return MMIOERR_FILENOTFOUND
;
151 FIXME(mmio
, "unexpected message %u\n", uMessage
);
158 /**************************************************************************
159 * mmioMemIOProc [internal]
161 static LRESULT
mmioMemIOProc(LPMMIOINFO16 lpmmioinfo
, UINT16 uMessage
, LPARAM lParam1
, LPARAM lParam2
) {
162 TRACE(mmio
,"(%p,0x%04x,0x%08lx,0x%08lx)\n",lpmmioinfo
,uMessage
,lParam1
,lParam2
);
167 * lParam1 = filename (must be NULL)
168 * lParam2 = reserved (we use it for 16-bitness)
169 * Returns: zero on success, error code on error
170 * NOTE: lDiskOffset automatically set to zero
173 if (!(lpmmioinfo
->dwFlags
& MMIO_CREATE
))
174 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchEndWrite
;
181 * lParam1 = wFlags parameter from mmioClose
183 * Returns: zero on success, error code on error
192 * lParam1 = huge pointer to read buffer
193 * lParam2 = number of bytes to read
194 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
196 * NOTE: lDiskOffset should be updated
199 /* HPSTR pch = (HPSTR) lParam1; */
200 /* LONG cch = (LONG) lParam2; */
202 FIXME(mmio
,"MMIOM_READ on memory files should not occur, buffer may be lost!\n");
207 case MMIOM_WRITEFLUSH
: {
208 /* no internal buffering, so WRITEFLUSH handled same as WRITE */
211 * lParam1 = huge pointer to write buffer
212 * lParam2 = number of bytes to write
213 * Returns: number of bytes written, -1 for error (error code in
215 * NOTE: lDiskOffset should be updated
218 /* HPSTR pch = (HPSTR) lParam1; */
219 /* LONG cch = (LONG) lParam2; */
221 FIXME(mmio
,"MMIOM_WRITE on memory files should not occur, buffer may be lost!\n");
227 * lParam1 = new position
228 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
229 * Returns: new file postion, -1 on error
230 * NOTE: lDiskOffset should be updated
233 /* LONG Offset = (LONG) lParam1; */
234 /* LONG Whence = (LONG) lParam2; */
236 FIXME(mmio
,"MMIOM_SEEK on memory files should not occur, buffer may be lost!\n");
241 FIXME(mmio
, "unexpected message %u\n", uMessage
);
248 /**************************************************************************
249 * MMIO_Open [internal]
251 static HMMIO16
MMIO_Open(LPSTR szFileName
, MMIOINFO16
* lpmmioinfo
,
252 DWORD dwOpenFlags
, int use16
)
254 LPMMIOINFO16 lpmminfo
;
258 TRACE(mmio
, "('%s', %p, %08lX);\n", szFileName
, lpmmioinfo
, dwOpenFlags
);
260 hmmio
= GlobalAlloc16(GHND
, sizeof(MMIOINFO16
));
261 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
262 if (lpmminfo
== NULL
)
264 memset(lpmminfo
, 0, sizeof(MMIOINFO16
));
266 /* assume DOS file if not otherwise specified */
268 (lpmmioinfo
->fccIOProc
== 0 && lpmmioinfo
->pIOProc
== NULL
)) {
270 lpmminfo
->fccIOProc
= FOURCC_DOS
;
271 lpmminfo
->pIOProc
= (LPMMIOPROC16
) mmioDosIOProc
;
273 /* if just the four character code is present, look up IO proc */
274 else if (lpmmioinfo
->pIOProc
== NULL
) {
276 lpmminfo
->fccIOProc
= lpmmioinfo
->fccIOProc
;
277 lpmminfo
->pIOProc
= mmioInstallIOProc16(lpmmioinfo
->fccIOProc
, NULL
, MMIO_FINDPROC
);
280 /* if IO proc specified, use it and specified four character code */
283 lpmminfo
->fccIOProc
= lpmmioinfo
->fccIOProc
;
284 lpmminfo
->pIOProc
= lpmmioinfo
->pIOProc
;
287 if (dwOpenFlags
& MMIO_ALLOCBUF
) {
288 if ((result
= mmioSetBuffer16(hmmio
, NULL
, MMIO_DEFAULTBUFFER
, 0))) {
290 lpmmioinfo
->wErrorRet
= result
;
294 if (lpmminfo
->fccIOProc
== FOURCC_MEM
) {
295 if ((result
= mmioSetBuffer16(hmmio
, lpmmioinfo
->pchBuffer
, lpmmioinfo
->cchBuffer
, 0))) {
297 lpmmioinfo
->wErrorRet
= result
;
302 lpmminfo
->dwFlags
= dwOpenFlags
;
303 lpmminfo
->hmmio
= hmmio
;
305 /* call IO proc to actually open file */
306 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_OPEN
, (LPARAM
) szFileName
, (LPARAM
) use16
);
308 GlobalUnlock16(hmmio
);
318 /**************************************************************************
319 * mmioOpenW [WINMM.123]
321 HMMIO WINAPI
mmioOpenW(LPWSTR szFileName
, MMIOINFO
* lpmmioinfo
,
324 LPSTR szFn
= HEAP_strdupWtoA(GetProcessHeap(),0,szFileName
);
325 HMMIO ret
= MMIO_Open(szFn
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
,FALSE
);
327 HeapFree(GetProcessHeap(),0,szFn
);
331 /**************************************************************************
332 * mmioOpenA [WINMM.122]
334 HMMIO WINAPI
mmioOpenA(LPSTR szFileName
, MMIOINFO
* lpmmioinfo
,
337 return MMIO_Open(szFileName
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
,FALSE
);
340 /**************************************************************************
341 * mmioOpen [MMSYSTEM.1210]
343 HMMIO16 WINAPI
mmioOpen16(LPSTR szFileName
, MMIOINFO16
* lpmmioinfo
,
346 return MMIO_Open(szFileName
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
,TRUE
);
350 /**************************************************************************
351 * mmioClose [WINMM.114]
353 MMRESULT WINAPI
mmioClose(HMMIO hmmio
, UINT uFlags
)
355 LPMMIOINFO16 lpmminfo
;
358 TRACE(mmio
, "(%04X, %04X);\n", hmmio
, uFlags
);
360 lpmminfo
= (LPMMIOINFO16
) GlobalLock16(hmmio
);
361 if (lpmminfo
== NULL
)
364 /* flush the file - if error reported, ignore */
365 if (mmioFlush(hmmio
, MMIO_EMPTYBUF
) != 0)
366 lpmminfo
->dwFlags
&= ~MMIO_DIRTY
;
368 result
= mmioSendMessage(hmmio
,MMIOM_CLOSE
,(LPARAM
)uFlags
,(LPARAM
)0);
370 mmioSetBuffer16(hmmio
, NULL
, 0, 0);
372 GlobalUnlock16(hmmio
);
379 /**************************************************************************
380 * mmioClose [MMSYSTEM.1211]
382 MMRESULT16 WINAPI
mmioClose16(HMMIO16 hmmio
, UINT16 uFlags
)
384 return mmioClose(hmmio
,uFlags
);
389 /**************************************************************************
390 * mmioRead [WINMM.124]
392 LONG WINAPI
mmioRead(HMMIO hmmio
, HPSTR pch
, LONG cch
)
395 LPMMIOINFO16 lpmminfo
;
397 TRACE(mmio
, "(%04X, %p, %ld);\n", hmmio
, pch
, cch
);
399 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
400 if (lpmminfo
== NULL
)
403 if (lpmminfo
->pchNext
!= lpmminfo
->pchEndRead
) {
404 count
= lpmminfo
->pchEndRead
- lpmminfo
->pchNext
;
405 if (count
> cch
|| count
< 0) count
= cch
;
406 memcpy(pch
, lpmminfo
->pchNext
, count
);
407 lpmminfo
->pchNext
+= count
;
413 if (cch
&&(lpmminfo
->fccIOProc
!=FOURCC_MEM
)) {
414 if (lpmminfo
->cchBuffer
) {
415 mmioFlush(hmmio
, MMIO_EMPTYBUF
);
419 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
420 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
421 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
422 size
= mmioSendMessage(hmmio
, MMIOM_READ
,
423 (LPARAM
) lpmminfo
->pchBuffer
,
424 (LPARAM
) lpmminfo
->cchBuffer
);
426 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
+ size
;
427 if (size
> cch
) size
= cch
;
428 memcpy(pch
, lpmminfo
->pchNext
, size
);
429 lpmminfo
->pchNext
+= size
;
435 count
+= mmioSendMessage(hmmio
, MMIOM_READ
, (LPARAM
) pch
, (LPARAM
) cch
);
436 if (count
>0) lpmminfo
->lBufOffset
+= count
;
440 GlobalUnlock16(hmmio
);
441 TRACE(mmio
, "count=%ld\n", count
);
445 /**************************************************************************
446 * mmioRead [MMSYSTEM.1212]
448 LONG WINAPI
mmioRead16(HMMIO16 hmmio
, HPSTR pch
, LONG cch
)
450 return mmioRead(hmmio
,pch
,cch
);
453 /**************************************************************************
454 * mmioWrite [WINMM.133]
456 LONG WINAPI
mmioWrite(HMMIO hmmio
, HPCSTR pch
, LONG cch
)
459 LPMMIOINFO16 lpmminfo
;
461 TRACE(mmio
, "(%04X, %p, %ld);\n", hmmio
, pch
, cch
);
463 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
464 if (lpmminfo
== NULL
)
467 if (lpmminfo
->cchBuffer
) {
470 if (lpmminfo
->pchNext
!= lpmminfo
->pchEndWrite
) {
471 count
= lpmminfo
->pchEndWrite
- lpmminfo
->pchNext
;
472 if (count
> cch
|| count
< 0) count
= cch
;
473 memcpy(lpmminfo
->pchNext
, pch
, count
);
474 lpmminfo
->pchNext
+= count
;
477 lpmminfo
->dwFlags
|= MMIO_DIRTY
;
479 if (lpmminfo
->fccIOProc
==FOURCC_MEM
) {
480 if (lpmminfo
->adwInfo
[0]) {
481 /* from where would we get the memory handle? */
482 FIXME(mmio
, "memory file expansion not implemented!\n");
486 if (lpmminfo
->pchNext
== lpmminfo
->pchEndWrite
487 && mmioFlush(hmmio
, MMIO_EMPTYBUF
)) break;
490 count
= mmioSendMessage(hmmio
, MMIOM_WRITE
, (LPARAM
) pch
, (LPARAM
) cch
);
491 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
494 GlobalUnlock16(hmmio
);
495 TRACE(mmio
, "count=%ld\n", count
);
499 /**************************************************************************
500 * mmioWrite [MMSYSTEM.1213]
502 LONG WINAPI
mmioWrite16(HMMIO16 hmmio
, HPCSTR pch
, LONG cch
)
504 return mmioWrite(hmmio
,pch
,cch
);
507 /**************************************************************************
508 * mmioSeek [MMSYSTEM.1214]
510 LONG WINAPI
mmioSeek(HMMIO hmmio
, LONG lOffset
, INT iOrigin
)
513 LPMMIOINFO16 lpmminfo
;
515 TRACE(mmio
, "(%04X, %08lX, %d);\n", hmmio
, lOffset
, iOrigin
);
517 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
518 if (lpmminfo
== NULL
)
521 offset
= (iOrigin
==SEEK_SET
)?(lOffset
- lpmminfo
->lBufOffset
):
522 (iOrigin
==SEEK_CUR
)?(lOffset
+
523 (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
)):-1;
525 if ((lpmminfo
->cchBuffer
<0)||
526 ((offset
>=0)&&(offset
<=(lpmminfo
->pchEndRead
-lpmminfo
->pchBuffer
)))) {
527 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
+ offset
;
528 GlobalUnlock16(hmmio
);
529 return lpmminfo
->lBufOffset
+ offset
;
532 if ((lpmminfo
->fccIOProc
==FOURCC_MEM
)||mmioFlush(hmmio
, MMIO_EMPTYBUF
)) {
533 GlobalUnlock16(hmmio
);
537 offset
= mmioSendMessage(hmmio
, MMIOM_SEEK
, (LPARAM
) lOffset
, (LPARAM
) iOrigin
);
538 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
540 GlobalUnlock16(hmmio
);
544 /**************************************************************************
545 * mmioSeek [MMSYSTEM.1214]
547 LONG WINAPI
mmioSeek16(HMMIO16 hmmio
, LONG lOffset
, INT16 iOrigin
)
549 return mmioSeek(hmmio
,lOffset
,iOrigin
);
552 /**************************************************************************
553 * mmioGetInfo [MMSYSTEM.1215]
555 UINT16 WINAPI
mmioGetInfo16(HMMIO16 hmmio
, MMIOINFO16
* lpmmioinfo
, UINT16 uFlags
)
557 LPMMIOINFO16 lpmminfo
;
558 TRACE(mmio
, "mmioGetInfo\n");
559 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
560 if (lpmminfo
== NULL
) return 0;
561 memcpy(lpmmioinfo
, lpmminfo
, sizeof(MMIOINFO16
));
562 GlobalUnlock16(hmmio
);
566 /**************************************************************************
567 * mmioGetInfo [WINMM.118]
569 UINT WINAPI
mmioGetInfo(HMMIO hmmio
, MMIOINFO
*lpmmioinfo
, UINT uFlags
)
572 LPMMIOINFO16 lpmminfo
=&mmioinfo
;
575 TRACE(mmio
, "(0x%04x,%p,0x%08x)\n",hmmio
,lpmmioinfo
,uFlags
);
576 ret
= mmioGetInfo16(hmmio
,&mmioinfo
,uFlags
);
579 lpmmioinfo
->dwFlags
= lpmminfo
->dwFlags
;
580 lpmmioinfo
->fccIOProc
= lpmminfo
->fccIOProc
;
581 lpmmioinfo
->pIOProc
= (LPMMIOPROC
)lpmminfo
->pIOProc
;
582 lpmmioinfo
->wErrorRet
= lpmminfo
->wErrorRet
;
583 lpmmioinfo
->htask
= lpmminfo
->htask
;
584 lpmmioinfo
->cchBuffer
= lpmminfo
->cchBuffer
;
585 lpmmioinfo
->pchBuffer
= lpmminfo
->pchBuffer
;
586 lpmmioinfo
->pchNext
= lpmminfo
->pchNext
;
587 lpmmioinfo
->pchEndRead
= lpmminfo
->pchEndRead
;
588 lpmmioinfo
->pchEndWrite
= lpmminfo
->pchEndWrite
;
589 lpmmioinfo
->lBufOffset
= lpmminfo
->lBufOffset
;
590 lpmmioinfo
->lDiskOffset
= lpmminfo
->lDiskOffset
;
591 memcpy(lpmmioinfo
->adwInfo
,lpmminfo
->adwInfo
,sizeof(lpmminfo
->adwInfo
));
592 lpmmioinfo
->dwReserved1
= lpmminfo
->dwReserved1
;
593 lpmmioinfo
->dwReserved2
= lpmminfo
->dwReserved2
;
594 lpmmioinfo
->hmmio
= lpmminfo
->hmmio
;
598 /**************************************************************************
599 * mmioSetInfo [MMSYSTEM.1216]
601 UINT16 WINAPI
mmioSetInfo16(HMMIO16 hmmio
, const MMIOINFO16
* lpmmioinfo
, UINT16 uFlags
)
603 LPMMIOINFO16 lpmminfo
;
604 TRACE(mmio
, "mmioSetInfo\n");
605 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
606 if (lpmminfo
== NULL
) return 0;
607 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
608 lpmminfo
->pchEndRead
= lpmmioinfo
->pchEndRead
;
609 GlobalUnlock16(hmmio
);
613 /**************************************************************************
614 * mmioSetInfo [WINMM.130]
616 UINT WINAPI
mmioSetInfo(HMMIO hmmio
, const MMIOINFO
* lpmmioinfo
, UINT uFlags
)
618 LPMMIOINFO16 lpmminfo
;
619 TRACE(mmio
, "mmioSetInfo\n");
620 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
621 if (lpmminfo
== NULL
) return 0;
622 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
623 lpmminfo
->pchEndRead
= lpmmioinfo
->pchEndRead
;
624 GlobalUnlock16(hmmio
);
628 /**************************************************************************
629 * mmioSetBuffer [WINMM.129]
631 UINT WINAPI
mmioSetBuffer(HMMIO hmmio
, LPSTR pchBuffer
,
632 LONG cchBuffer
, UINT uFlags
)
634 LPMMIOINFO16 lpmminfo
;
636 if (mmioFlush(hmmio
, MMIO_EMPTYBUF
) != 0)
637 return MMIOERR_CANNOTWRITE
;
639 TRACE(mmio
, "(hmmio=%04x, pchBuf=%p, cchBuf=%ld, uFlags=%#08x)\n",
640 hmmio
, pchBuffer
, cchBuffer
, uFlags
);
642 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
643 if (lpmminfo
== NULL
) return 0;
644 if ((!cchBuffer
|| pchBuffer
) && lpmminfo
->dwFlags
&MMIO_ALLOCBUF
) {
645 GlobalUnlock16(lpmminfo
->dwReserved1
);
646 GlobalFree16(lpmminfo
->dwReserved1
);
647 lpmminfo
->dwFlags
&= ~MMIO_ALLOCBUF
;
650 lpmminfo
->pchBuffer
= pchBuffer
;
651 } else if (lpmminfo
->dwFlags
&MMIO_ALLOCBUF
) {
653 GlobalUnlock16(lpmminfo
->dwReserved1
);
654 hNewBuf
= GlobalReAlloc16(lpmminfo
->dwReserved1
, cchBuffer
, 0);
656 /* FIXME: this assumes the memory block didn't move */
657 GlobalLock16(lpmminfo
->dwReserved1
);
658 GlobalUnlock16(hmmio
);
659 return MMIOERR_OUTOFMEMORY
;
661 lpmminfo
->dwReserved1
= hNewBuf
;
662 lpmminfo
->pchBuffer
= GlobalLock16(hNewBuf
);
663 } else if (cchBuffer
) {
664 HGLOBAL16 hNewBuf
= GlobalAlloc16(GMEM_MOVEABLE
, cchBuffer
);
666 GlobalUnlock16(hmmio
);
667 return MMIOERR_OUTOFMEMORY
;
669 lpmminfo
->dwReserved1
= hNewBuf
;
670 lpmminfo
->pchBuffer
= GlobalLock16(hNewBuf
);
671 lpmminfo
->dwFlags
|= MMIO_ALLOCBUF
;
673 lpmminfo
->pchBuffer
= NULL
;
674 lpmminfo
->cchBuffer
= cchBuffer
;
675 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
676 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
677 lpmminfo
->pchEndWrite
= lpmminfo
->pchBuffer
+ cchBuffer
;
678 lpmminfo
->lBufOffset
= 0;
680 GlobalUnlock16(hmmio
);
684 /**************************************************************************
685 * mmioSetBuffer [MMSYSTEM.1217]
687 UINT16 WINAPI
mmioSetBuffer16(HMMIO16 hmmio
, LPSTR pchBuffer
,
688 LONG cchBuffer
, UINT16 uFlags
)
690 return mmioSetBuffer(hmmio
, pchBuffer
, cchBuffer
, uFlags
);
693 /**************************************************************************
694 * mmioFlush [WINMM.117]
696 UINT WINAPI
mmioFlush(HMMIO hmmio
, UINT uFlags
)
698 LPMMIOINFO16 lpmminfo
;
699 TRACE(mmio
, "(%04X, %04X)\n", hmmio
, uFlags
);
700 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
701 if (lpmminfo
== NULL
) return 0;
703 if ((!lpmminfo
->cchBuffer
)||(lpmminfo
->fccIOProc
==FOURCC_MEM
)) {
704 GlobalUnlock16(hmmio
);
707 /* not quite sure what to do here, but I'll guess */
708 if (lpmminfo
->dwFlags
& MMIO_DIRTY
) {
709 mmioSendMessage(hmmio
, MMIOM_SEEK
,
710 (LPARAM
) lpmminfo
->lBufOffset
,
712 mmioSendMessage(hmmio
, MMIOM_WRITE
,
713 (LPARAM
) lpmminfo
->pchBuffer
,
714 (LPARAM
) (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
) );
715 lpmminfo
->dwFlags
&= ~MMIO_DIRTY
;
717 if (uFlags
& MMIO_EMPTYBUF
) {
718 /* seems Windows doesn't do any seeking here, hopefully this
719 won't matter, otherwise a slight rewrite is necessary */
720 mmioSendMessage(hmmio
, MMIOM_SEEK
,
721 (LPARAM
) (lpmminfo
->lBufOffset
+
722 (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
)),
724 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
725 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
726 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
729 GlobalUnlock16(hmmio
);
733 /**************************************************************************
734 * mmioFlush [MMSYSTEM.1218]
736 UINT16 WINAPI
mmioFlush16(HMMIO16 hmmio
, UINT16 uFlags
)
738 return mmioFlush(hmmio
,uFlags
);
741 /**************************************************************************
742 * mmioAdvance [MMSYSTEM.1219]
744 UINT WINAPI
mmioAdvance(HMMIO hmmio
,MMIOINFO
*lpmmioinfo
,UINT uFlags
)
746 LPMMIOINFO16 lpmminfo
;
747 TRACE(mmio
, "mmioAdvance\n");
748 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
749 if (lpmminfo
== NULL
) return 0;
750 if (!lpmminfo
->cchBuffer
) {
751 GlobalUnlock16(hmmio
);
752 return MMIOERR_UNBUFFERED
;
754 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
755 if (mmioFlush(hmmio
, MMIO_EMPTYBUF
)) {
756 GlobalUnlock16(hmmio
);
757 return MMIOERR_CANNOTWRITE
;
759 if (uFlags
== MMIO_READ
)
760 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchBuffer
+
761 mmioSendMessage(hmmio
, MMIOM_READ
,
762 (LPARAM
) lpmmioinfo
->pchBuffer
,
763 (LPARAM
) lpmmioinfo
->cchBuffer
);
764 #if 0 /* mmioFlush32 already did the writing */
765 if (uFlags
== MMIO_WRITE
)
766 mmioSendMessage(hmmio
, MMIOM_WRITE
,
767 (LPARAM
) lpmmioinfo
->pchBuffer
,
768 (LPARAM
) lpmmioinfo
->cchBuffer
);
770 lpmmioinfo
->pchNext
= lpmmioinfo
->pchBuffer
;
771 GlobalUnlock16(hmmio
);
775 /**************************************************************************
776 * mmioAdvance [MMSYSTEM.1219]
778 UINT16 WINAPI
mmioAdvance16(HMMIO16 hmmio
,MMIOINFO16
*lpmmioinfo
,UINT16 uFlags
)
780 LPMMIOINFO16 lpmminfo
;
781 TRACE(mmio
, "mmioAdvance\n");
782 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
783 if (lpmminfo
== NULL
) return 0;
784 if (!lpmminfo
->cchBuffer
) {
785 GlobalUnlock16(hmmio
);
786 return MMIOERR_UNBUFFERED
;
788 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
789 if (mmioFlush(hmmio
, MMIO_EMPTYBUF
)) {
790 GlobalUnlock16(hmmio
);
791 return MMIOERR_CANNOTWRITE
;
793 if (uFlags
== MMIO_READ
)
794 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchBuffer
+
795 mmioSendMessage(hmmio
, MMIOM_READ
,
796 (LPARAM
) lpmmioinfo
->pchBuffer
,
797 (LPARAM
) lpmmioinfo
->cchBuffer
);
798 #if 0 /* mmioFlush32 already did the writing */
799 if (uFlags
== MMIO_WRITE
)
800 mmioSendMessage(hmmio
, MMIOM_WRITE
,
801 (LPARAM
) lpmmioinfo
->pchBuffer
,
802 (LPARAM
) lpmmioinfo
->cchBuffer
);
804 lpmmioinfo
->pchNext
= lpmmioinfo
->pchBuffer
;
805 GlobalUnlock16(hmmio
);
809 /**************************************************************************
810 * mmioStringToFOURCCA [WINMM.131]
812 FOURCC WINAPI
mmioStringToFOURCCA(LPCSTR sz
, UINT uFlags
)
814 return mmioStringToFOURCC16(sz
,uFlags
);
817 /**************************************************************************
818 * mmioStringToFOURCCW [WINMM.132]
820 FOURCC WINAPI
mmioStringToFOURCCW(LPCWSTR sz
, UINT uFlags
)
822 LPSTR szA
= HEAP_strdupWtoA(GetProcessHeap(),0,sz
);
823 FOURCC ret
= mmioStringToFOURCCA(szA
,uFlags
);
825 HeapFree(GetProcessHeap(),0,szA
);
829 /**************************************************************************
830 * mmioStringToFOURCC [MMSYSTEM.1220]
832 FOURCC WINAPI
mmioStringToFOURCC16(LPCSTR sz
, UINT16 uFlags
)
834 return mmioFOURCC(sz
[0],sz
[1],sz
[2],sz
[3]);
837 /**************************************************************************
838 * mmioInstallIOProc16 [MMSYSTEM.1221]
840 LPMMIOPROC16 WINAPI
mmioInstallIOProc16(FOURCC fccIOProc
,
841 LPMMIOPROC16 pIOProc
, DWORD dwFlags
)
843 TRACE(mmio
, "(%ld, %p, %08lX)\n",
844 fccIOProc
, pIOProc
, dwFlags
);
846 if (dwFlags
& MMIO_GLOBALPROC
) {
847 FIXME(mmio
, " global procedures not implemented\n");
850 /* just handle the known procedures for now */
851 switch(dwFlags
& (MMIO_INSTALLPROC
|MMIO_REMOVEPROC
|MMIO_FINDPROC
)) {
852 case MMIO_INSTALLPROC
:
854 case MMIO_REMOVEPROC
:
857 if (fccIOProc
== FOURCC_DOS
)
858 return (LPMMIOPROC16
) mmioDosIOProc
;
859 else if (fccIOProc
== FOURCC_MEM
)
860 return (LPMMIOPROC16
) mmioMemIOProc
;
868 /**************************************************************************
869 * mmioInstallIOProc32A [WINMM.120]
871 LPMMIOPROC WINAPI
mmioInstallIOProcA(FOURCC fccIOProc
,
872 LPMMIOPROC pIOProc
, DWORD dwFlags
)
874 FIXME(mmio
, "(%c%c%c%c,%p,0x%08lx) -- empty stub \n",
875 (char)((fccIOProc
&0xff000000)>>24),
876 (char)((fccIOProc
&0x00ff0000)>>16),
877 (char)((fccIOProc
&0x0000ff00)>> 8),
878 (char)(fccIOProc
&0x000000ff),
883 /**************************************************************************
884 * mmioSendMessage [MMSYSTEM.1222]
886 LRESULT WINAPI
mmioSendMessage(HMMIO16 hmmio
, UINT16 uMessage
,
887 LPARAM lParam1
, LPARAM lParam2
)
889 LPMMIOINFO16 lpmminfo
;
891 const char *msg
= NULL
;
895 #define msgname(x) case x: msg = #x; break;
897 msgname(MMIOM_CLOSE
);
899 msgname(MMIOM_WRITE
);
900 msgname(MMIOM_WRITEFLUSH
);
902 msgname(MMIOM_RENAME
);
908 TRACE(mmio
, "(%04X, %s, %ld, %ld)\n",
909 hmmio
, msg
, lParam1
, lParam2
);
911 TRACE(mmio
, "(%04X, %u, %ld, %ld)\n",
912 hmmio
, uMessage
, lParam1
, lParam2
);
914 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
916 if (lpmminfo
&& lpmminfo
->pIOProc
)
917 result
= (*lpmminfo
->pIOProc
)((LPSTR
)lpmminfo
, uMessage
, lParam1
, lParam2
);
919 result
= MMSYSERR_INVALPARAM
;
921 GlobalUnlock16(hmmio
);
926 /**************************************************************************
927 * mmioDescend [MMSYSTEM.1223]
929 UINT16 WINAPI
mmioDescend(HMMIO16 hmmio
, MMCKINFO
* lpck
,
930 const MMCKINFO
* lpckParent
, UINT16 uFlags
)
936 TRACE(mmio
,"(%04X, %p, %p, %04X);\n",hmmio
,lpck
,lpckParent
,uFlags
);
940 dwOldPos
= mmioSeek(hmmio
, 0, SEEK_CUR
);
941 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
943 if (lpckParent
!= NULL
) {
944 TRACE(mmio
, "seek inside parent at %ld !\n", lpckParent
->dwDataOffset
);
945 dwOldPos
= mmioSeek(hmmio
,lpckParent
->dwDataOffset
,SEEK_SET
);
948 /* The SDK docu says 'ckid' is used for all cases. Real World
949 * examples disagree -Marcus,990216.
952 searchcki
.fccType
= 0;
953 /* find_chunk looks for 'ckid' */
954 if (uFlags
& MMIO_FINDCHUNK
)
955 searchcki
.ckid
= lpck
->ckid
;
956 /* find_riff and find_list look for 'fccType' */
957 if (uFlags
& MMIO_FINDLIST
) {
958 searchcki
.ckid
= FOURCC_LIST
;
959 searchcki
.fccType
= lpck
->fccType
;
961 if (uFlags
& MMIO_FINDRIFF
) {
962 searchcki
.ckid
= FOURCC_RIFF
;
963 searchcki
.fccType
= lpck
->fccType
;
965 memcpy(&fcc
,&(searchcki
.fccType
),4);fcc
[4]=0;
966 memcpy(&ckid
,&(searchcki
.ckid
),4);ckid
[4]=0;
967 TRACE(mmio
,"searching for %s.%s\n",ckid
,searchcki
.fccType
?fcc
:"<any>");
969 if (uFlags
& (MMIO_FINDCHUNK
|MMIO_FINDLIST
|MMIO_FINDRIFF
)) {
973 ix
= mmioRead(hmmio
, (LPSTR
)lpck
, 3 * sizeof(DWORD
));
974 if (ix
< 2*sizeof(DWORD
)) {
975 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
976 WARN(mmio
, "return ChunkNotFound\n");
977 return MMIOERR_CHUNKNOTFOUND
;
979 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
980 if (ix
< lpck
->dwDataOffset
- dwOldPos
) {
981 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
982 WARN(mmio
, "return ChunkNotFound\n");
983 return MMIOERR_CHUNKNOTFOUND
;
985 memcpy(ckid
,&lpck
->ckid
,4);
986 memcpy(fcc
,&lpck
->fccType
,4);
987 TRACE(mmio
, "ckid=%s fcc=%s cksize=%08lX !\n",
988 ckid
, searchcki
.fccType
?fcc
:"<unused>",
991 if ((searchcki
.ckid
== lpck
->ckid
) &&
992 (!searchcki
.fccType
||
993 (searchcki
.fccType
== lpck
->fccType
)
998 dwOldPos
= lpck
->dwDataOffset
+ lpck
->cksize
;
999 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
1001 /* If we were looking for RIFF/LIST chunks, the final dataptr
1002 * is after the chunkid. If we were just looking for the chunk
1003 * it is after the cksize. So add 4 in RIFF/LIST case.
1005 if (uFlags
& (MMIO_FINDLIST
|MMIO_FINDRIFF
))
1006 lpck
->dwDataOffset
+=sizeof(DWORD
);
1008 /* FIXME: unverified, does it do this? */
1009 if (mmioRead(hmmio
, (LPSTR
)lpck
, sizeof(MMCKINFO
)) < sizeof(MMCKINFO
)) {
1010 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
1011 WARN(mmio
, "return ChunkNotFound 2nd\n");
1012 return MMIOERR_CHUNKNOTFOUND
;
1014 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
1015 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1016 lpck
->dwDataOffset
+= sizeof(DWORD
);
1018 mmioSeek(hmmio
, lpck
->dwDataOffset
, SEEK_SET
);
1019 memcpy(ckid
,&(lpck
->ckid
),4);
1020 TRACE(mmio
, "lpck->ckid=%s lpck->cksize=%ld !\n", ckid
, lpck
->cksize
);
1021 memcpy(fcc
,&(lpck
->fccType
),4);
1022 TRACE(mmio
, "lpck->fccType=%08lX (%s)!\n", lpck
->fccType
,searchcki
.fccType
?fcc
:"");
1026 /**************************************************************************
1027 * mmioAscend [WINMM.113]
1029 UINT WINAPI
mmioAscend(HMMIO hmmio
, MMCKINFO
* lpck
, UINT uFlags
)
1031 TRACE(mmio
, "(%04X, %p, %04X);\n",
1032 hmmio
, lpck
, uFlags
);
1033 if (lpck
->dwFlags
&MMIO_DIRTY
) {
1034 DWORD dwOldPos
, dwNewSize
, dwSizePos
;
1036 TRACE(mmio
, "chunk is marked MMIO_DIRTY, correcting chunk size\n");
1037 dwOldPos
= mmioSeek(hmmio
, 0, SEEK_CUR
);
1038 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
1039 dwNewSize
= dwOldPos
- lpck
->dwDataOffset
;
1040 if (dwNewSize
!= lpck
->cksize
) {
1041 TRACE(mmio
, "dwNewSize=%ld\n", dwNewSize
);
1042 lpck
->cksize
= dwNewSize
;
1044 dwSizePos
= lpck
->dwDataOffset
- sizeof(DWORD
);
1045 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1046 dwSizePos
-= sizeof(DWORD
);
1047 TRACE(mmio
, "dwSizePos=%ld\n", dwSizePos
);
1049 mmioSeek(hmmio
, dwSizePos
, SEEK_SET
);
1050 mmioWrite(hmmio
, (LPSTR
)&dwNewSize
, sizeof(DWORD
));
1053 mmioSeek(hmmio
,lpck
->dwDataOffset
+lpck
->cksize
,SEEK_SET
);
1058 /**************************************************************************
1059 * mmioAscend [MMSYSTEM.1224]
1061 UINT16 WINAPI
mmioAscend16(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
1063 return mmioAscend(hmmio
,lpck
,uFlags
);
1066 /**************************************************************************
1067 * mmioCreateChunk [MMSYSTEM.1225]
1069 UINT16 WINAPI
mmioCreateChunk16(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
1074 TRACE(mmio
, "(%04X, %p, %04X);\n",
1075 hmmio
, lpck
, uFlags
);
1077 dwOldPos
= mmioSeek(hmmio
, 0, SEEK_CUR
);
1078 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
1080 if (uFlags
== MMIO_CREATELIST
)
1081 lpck
->ckid
= FOURCC_LIST
;
1082 else if (uFlags
== MMIO_CREATERIFF
)
1083 lpck
->ckid
= FOURCC_RIFF
;
1085 TRACE(mmio
, "ckid=%08lX\n", lpck
->ckid
);
1087 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
1088 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1089 lpck
->dwDataOffset
+= sizeof(DWORD
);
1090 lpck
->dwFlags
= MMIO_DIRTY
;
1092 ix
= mmioWrite(hmmio
, (LPSTR
)lpck
, lpck
->dwDataOffset
- dwOldPos
);
1093 TRACE(mmio
, "after _lwrite32 ix = %ld req = %ld, errno = %d\n",ix
,lpck
->dwDataOffset
- dwOldPos
,errno
);
1094 if (ix
< lpck
->dwDataOffset
- dwOldPos
) {
1096 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
1097 WARN(mmio
, "return CannotWrite\n");
1098 return MMIOERR_CANNOTWRITE
;
1104 /**************************************************************************
1105 * mmioCreateChunk [WINMM.115]
1107 UINT WINAPI
mmioCreateChunk(HMMIO hmmio
, MMCKINFO
* lpck
, UINT uFlags
)
1109 return mmioCreateChunk16(hmmio
, lpck
, uFlags
);
1112 /**************************************************************************
1113 * mmioRename [MMSYSTEM.1226]
1115 UINT16 WINAPI
mmioRename16(LPCSTR szFileName
, LPCSTR szNewFileName
,
1116 MMIOINFO16
* lpmmioinfo
, DWORD dwRenameFlags
)
1119 LPMMIOINFO16 lpmminfo
;
1122 TRACE(mmio
, "('%s', '%s', %p, %08lX);\n",
1123 szFileName
, szNewFileName
, lpmmioinfo
, dwRenameFlags
);
1125 hmmio
= GlobalAlloc16(GHND
, sizeof(MMIOINFO16
));
1126 lpmminfo
= (LPMMIOINFO16
) GlobalLock16(hmmio
);
1129 memcpy(lpmminfo
, lpmmioinfo
, sizeof(MMIOINFO16
));
1131 /* assume DOS file if not otherwise specified */
1132 if (lpmminfo
->fccIOProc
== 0 && lpmminfo
->pIOProc
== NULL
) {
1134 lpmminfo
->fccIOProc
= mmioFOURCC('D', 'O', 'S', ' ');
1135 lpmminfo
->pIOProc
= (LPMMIOPROC16
) mmioDosIOProc
;
1138 /* if just the four character code is present, look up IO proc */
1139 else if (lpmminfo
->pIOProc
== NULL
) {
1141 lpmminfo
->pIOProc
= mmioInstallIOProc16(lpmminfo
->fccIOProc
, NULL
, MMIO_FINDPROC
);
1144 /* (if IO proc specified, use it and specified four character code) */
1146 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_RENAME
, (LPARAM
) szFileName
, (LPARAM
) szNewFileName
);
1148 GlobalUnlock16(hmmio
);
1149 GlobalFree16(hmmio
);
1154 /**************************************************************************
1155 * mmioRenameA [WINMM.125]
1157 UINT WINAPI
mmioRenameA(LPCSTR szFileName
, LPCSTR szNewFileName
,
1158 MMIOINFO
* lpmmioinfo
, DWORD dwRenameFlags
)
1160 FIXME(mmio
, "This may fail\n");
1161 return mmioRename16(szFileName
, szNewFileName
, (MMIOINFO16
*)lpmmioinfo
, dwRenameFlags
);
1164 /**************************************************************************
1165 * mmioRenameW [WINMM.126]
1167 UINT WINAPI
mmioRenameW(LPCWSTR szFileName
, LPCWSTR szNewFileName
,
1168 MMIOINFO
* lpmmioinfo
, DWORD dwRenameFlags
)
1170 LPSTR szFn
= HEAP_strdupWtoA(GetProcessHeap(), 0, szFileName
);
1171 LPSTR sznFn
= HEAP_strdupWtoA(GetProcessHeap(), 0, szNewFileName
);
1172 UINT ret
= mmioRenameA(szFn
, sznFn
, lpmmioinfo
, dwRenameFlags
);
1174 HeapFree(GetProcessHeap(),0,szFn
);
1175 HeapFree(GetProcessHeap(),0,sznFn
);