4 * Copyright 1998 Andrew Taylor
5 * Copyright 1998 Ove Kåven
22 /**************************************************************************
23 * mmioDosIOProc [internal]
25 static LRESULT
mmioDosIOProc(LPMMIOINFO16 lpmmioinfo
, UINT16 uMessage
, LPARAM lParam1
, LPARAM lParam2
) {
26 TRACE(mmio
, "(%p, %X, %ld, %ld);\n", lpmmioinfo
, uMessage
, lParam1
, lParam2
);
32 * lParam1 = szFileName parameter from mmioOpen
33 * lParam2 = reserved (we use it for 16-bitness)
34 * Returns: zero on success, error code on error
35 * NOTE: lDiskOffset automatically set to zero
39 LPSTR szFileName
= (LPSTR
) lParam1
;
41 if (lpmmioinfo
->dwFlags
& MMIO_GETTEMP
) {
42 FIXME(mmio
, "MMIO_GETTEMP not implemented\n");
43 return MMIOERR_CANNOTOPEN
;
46 /* if filename NULL, assume open file handle in adwInfo[0] */
48 if (lParam2
) lpmmioinfo
->adwInfo
[0] =
49 HFILE16_TO_HFILE32(lpmmioinfo
->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
= _hwrite32((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 FIXME(mmio
, "unexpected message %u\n", uMessage
);
159 /**************************************************************************
160 * mmioMemIOProc [internal]
162 static LRESULT
mmioMemIOProc(LPMMIOINFO16 lpmmioinfo
, UINT16 uMessage
, LPARAM lParam1
, LPARAM lParam2
) {
163 TRACE(mmio
,"(%p,0x%04x,0x%08lx,0x%08lx)\n",lpmmioinfo
,uMessage
,lParam1
,lParam2
);
168 * lParam1 = filename (must be NULL)
169 * lParam2 = reserved (we use it for 16-bitness)
170 * Returns: zero on success, error code on error
171 * NOTE: lDiskOffset automatically set to zero
174 if (!(lpmmioinfo
->dwFlags
& MMIO_CREATE
))
175 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchEndWrite
;
182 * lParam1 = wFlags parameter from mmioClose
184 * Returns: zero on success, error code on error
193 * lParam1 = huge pointer to read buffer
194 * lParam2 = number of bytes to read
195 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
197 * NOTE: lDiskOffset should be updated
200 HPSTR pch
= (HPSTR
) lParam1
;
201 LONG cch
= (LONG
) lParam2
;
203 FIXME(mmio
,"MMIOM_READ on memory files should not occur, buffer may be lost!\n");
208 case MMIOM_WRITEFLUSH
: {
209 /* no internal buffering, so WRITEFLUSH handled same as WRITE */
212 * lParam1 = huge pointer to write buffer
213 * lParam2 = number of bytes to write
214 * Returns: number of bytes written, -1 for error (error code in
216 * NOTE: lDiskOffset should be updated
219 HPSTR pch
= (HPSTR
) lParam1
;
220 LONG cch
= (LONG
) lParam2
;
222 FIXME(mmio
,"MMIOM_WRITE on memory files should not occur, buffer may be lost!\n");
228 * lParam1 = new position
229 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
230 * Returns: new file postion, -1 on error
231 * NOTE: lDiskOffset should be updated
234 LONG Offset
= (LONG
) lParam1
;
235 LONG Whence
= (LONG
) lParam2
;
237 FIXME(mmio
,"MMIOM_SEEK on memory files should not occur, buffer may be lost!\n");
242 FIXME(mmio
, "unexpected message %u\n", uMessage
);
249 /**************************************************************************
250 * MMIO_Open [internal]
252 static HMMIO16
MMIO_Open(LPSTR szFileName
, MMIOINFO16
* lpmmioinfo
,
253 DWORD dwOpenFlags
, int use16
)
255 LPMMIOINFO16 lpmminfo
;
259 TRACE(mmio
, "('%s', %p, %08lX);\n", szFileName
, lpmmioinfo
, dwOpenFlags
);
261 hmmio
= GlobalAlloc16(GHND
, sizeof(MMIOINFO16
));
262 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
263 if (lpmminfo
== NULL
)
265 memset(lpmminfo
, 0, sizeof(MMIOINFO16
));
267 /* assume DOS file if not otherwise specified */
269 (lpmmioinfo
->fccIOProc
== 0 && lpmmioinfo
->pIOProc
== NULL
)) {
271 lpmminfo
->fccIOProc
= FOURCC_DOS
;
272 lpmminfo
->pIOProc
= (LPMMIOPROC16
) mmioDosIOProc
;
274 /* if just the four character code is present, look up IO proc */
275 else if (lpmmioinfo
->pIOProc
== NULL
) {
277 lpmminfo
->fccIOProc
= lpmmioinfo
->fccIOProc
;
278 lpmminfo
->pIOProc
= mmioInstallIOProc16(lpmmioinfo
->fccIOProc
, NULL
, MMIO_FINDPROC
);
281 /* if IO proc specified, use it and specified four character code */
284 lpmminfo
->fccIOProc
= lpmmioinfo
->fccIOProc
;
285 lpmminfo
->pIOProc
= lpmmioinfo
->pIOProc
;
288 if (dwOpenFlags
& MMIO_ALLOCBUF
) {
289 if ((result
= mmioSetBuffer16(hmmio
, NULL
, MMIO_DEFAULTBUFFER
, 0))) {
291 lpmmioinfo
->wErrorRet
= result
;
295 if (lpmminfo
->fccIOProc
== FOURCC_MEM
) {
296 if ((result
= mmioSetBuffer16(hmmio
, lpmmioinfo
->pchBuffer
, lpmmioinfo
->cchBuffer
, 0))) {
298 lpmmioinfo
->wErrorRet
= result
;
303 lpmminfo
->dwFlags
= dwOpenFlags
;
304 lpmminfo
->hmmio
= hmmio
;
306 /* call IO proc to actually open file */
307 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_OPEN
, (LPARAM
) szFileName
, (LPARAM
) use16
);
309 GlobalUnlock16(hmmio
);
319 /**************************************************************************
320 * mmioOpenW [WINMM.123]
322 HMMIO32 WINAPI
mmioOpen32W(LPWSTR szFileName
, MMIOINFO32
* lpmmioinfo
,
325 LPSTR szFn
= HEAP_strdupWtoA(GetProcessHeap(),0,szFileName
);
326 HMMIO32 ret
= MMIO_Open(szFn
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
,FALSE
);
328 HeapFree(GetProcessHeap(),0,szFn
);
332 /**************************************************************************
333 * mmioOpenA [WINMM.122]
335 HMMIO32 WINAPI
mmioOpen32A(LPSTR szFileName
, MMIOINFO32
* lpmmioinfo
,
338 return MMIO_Open(szFileName
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
,FALSE
);
341 /**************************************************************************
342 * mmioOpen [MMSYSTEM.1210]
344 HMMIO16 WINAPI
mmioOpen16(LPSTR szFileName
, MMIOINFO16
* lpmmioinfo
,
347 return MMIO_Open(szFileName
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
,TRUE
);
351 /**************************************************************************
352 * mmioClose [WINMM.114]
354 MMRESULT32 WINAPI
mmioClose32(HMMIO32 hmmio
, UINT32 uFlags
)
356 LPMMIOINFO16 lpmminfo
;
359 TRACE(mmio
, "(%04X, %04X);\n", hmmio
, uFlags
);
361 lpmminfo
= (LPMMIOINFO16
) GlobalLock16(hmmio
);
362 if (lpmminfo
== NULL
)
365 /* flush the file - if error reported, ignore */
366 if (mmioFlush32(hmmio
, MMIO_EMPTYBUF
) != 0)
367 lpmminfo
->dwFlags
&= ~MMIO_DIRTY
;
369 result
= mmioSendMessage(hmmio
,MMIOM_CLOSE
,(LPARAM
)uFlags
,(LPARAM
)0);
371 mmioSetBuffer16(hmmio
, NULL
, 0, 0);
373 GlobalUnlock16(hmmio
);
380 /**************************************************************************
381 * mmioClose [MMSYSTEM.1211]
383 MMRESULT16 WINAPI
mmioClose16(HMMIO16 hmmio
, UINT16 uFlags
)
385 return mmioClose32(hmmio
,uFlags
);
390 /**************************************************************************
391 * mmioRead [WINMM.124]
393 LONG WINAPI
mmioRead32(HMMIO32 hmmio
, HPSTR pch
, LONG cch
)
396 LPMMIOINFO16 lpmminfo
;
398 TRACE(mmio
, "(%04X, %p, %ld);\n", hmmio
, pch
, cch
);
400 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
401 if (lpmminfo
== NULL
)
404 if (lpmminfo
->pchNext
!= lpmminfo
->pchEndRead
) {
405 count
= lpmminfo
->pchEndRead
- lpmminfo
->pchNext
;
406 if (count
> cch
|| count
< 0) count
= cch
;
407 memcpy(pch
, lpmminfo
->pchNext
, count
);
408 lpmminfo
->pchNext
+= count
;
414 if (cch
&&(lpmminfo
->fccIOProc
!=FOURCC_MEM
)) {
415 if (lpmminfo
->cchBuffer
) {
416 mmioFlush32(hmmio
, MMIO_EMPTYBUF
);
420 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
421 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
422 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
423 size
= mmioSendMessage(hmmio
, MMIOM_READ
,
424 (LPARAM
) lpmminfo
->pchBuffer
,
425 (LPARAM
) lpmminfo
->cchBuffer
);
427 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
+ size
;
428 if (size
> cch
) size
= cch
;
429 memcpy(pch
, lpmminfo
->pchNext
, size
);
430 lpmminfo
->pchNext
+= size
;
436 count
+= mmioSendMessage(hmmio
, MMIOM_READ
, (LPARAM
) pch
, (LPARAM
) cch
);
437 if (count
>0) lpmminfo
->lBufOffset
+= count
;
441 GlobalUnlock16(hmmio
);
442 TRACE(mmio
, "count=%ld\n", count
);
446 /**************************************************************************
447 * mmioRead [MMSYSTEM.1212]
449 LONG WINAPI
mmioRead16(HMMIO16 hmmio
, HPSTR pch
, LONG cch
)
451 return mmioRead32(hmmio
,pch
,cch
);
454 /**************************************************************************
455 * mmioWrite [WINMM.133]
457 LONG WINAPI
mmioWrite32(HMMIO32 hmmio
, HPCSTR pch
, LONG cch
)
460 LPMMIOINFO16 lpmminfo
;
462 TRACE(mmio
, "(%04X, %p, %ld);\n", hmmio
, pch
, cch
);
464 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
465 if (lpmminfo
== NULL
)
468 if (lpmminfo
->cchBuffer
) {
471 if (lpmminfo
->pchNext
!= lpmminfo
->pchEndWrite
) {
472 count
= lpmminfo
->pchEndWrite
- lpmminfo
->pchNext
;
473 if (count
> cch
|| count
< 0) count
= cch
;
474 memcpy(lpmminfo
->pchNext
, pch
, count
);
475 lpmminfo
->pchNext
+= count
;
478 lpmminfo
->dwFlags
|= MMIO_DIRTY
;
480 if (lpmminfo
->fccIOProc
==FOURCC_MEM
) {
481 if (lpmminfo
->adwInfo
[0]) {
482 /* from where would we get the memory handle? */
483 FIXME(mmio
, "memory file expansion not implemented!\n");
487 if (lpmminfo
->pchNext
== lpmminfo
->pchEndWrite
488 && mmioFlush32(hmmio
, MMIO_EMPTYBUF
)) break;
491 count
= mmioSendMessage(hmmio
, MMIOM_WRITE
, (LPARAM
) pch
, (LPARAM
) cch
);
492 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
495 GlobalUnlock16(hmmio
);
496 TRACE(mmio
, "count=%ld\n", count
);
500 /**************************************************************************
501 * mmioWrite [MMSYSTEM.1213]
503 LONG WINAPI
mmioWrite16(HMMIO16 hmmio
, HPCSTR pch
, LONG cch
)
505 return mmioWrite32(hmmio
,pch
,cch
);
508 /**************************************************************************
509 * mmioSeek [MMSYSTEM.1214]
511 LONG WINAPI
mmioSeek32(HMMIO32 hmmio
, LONG lOffset
, INT32 iOrigin
)
514 LPMMIOINFO16 lpmminfo
;
516 TRACE(mmio
, "(%04X, %08lX, %d);\n", hmmio
, lOffset
, iOrigin
);
518 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
519 if (lpmminfo
== NULL
)
522 offset
= (iOrigin
==SEEK_SET
)?(lOffset
- lpmminfo
->lBufOffset
):
523 (iOrigin
==SEEK_CUR
)?(lOffset
+
524 (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
)):-1;
526 if ((lpmminfo
->cchBuffer
<0)||
527 ((offset
>=0)&&(offset
<=(lpmminfo
->pchEndRead
-lpmminfo
->pchBuffer
)))) {
528 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
+ offset
;
529 GlobalUnlock16(hmmio
);
530 return lpmminfo
->lBufOffset
+ offset
;
533 if ((lpmminfo
->fccIOProc
==FOURCC_MEM
)||mmioFlush32(hmmio
, MMIO_EMPTYBUF
)) {
534 GlobalUnlock16(hmmio
);
538 offset
= mmioSendMessage(hmmio
, MMIOM_SEEK
, (LPARAM
) lOffset
, (LPARAM
) iOrigin
);
539 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
541 GlobalUnlock16(hmmio
);
545 /**************************************************************************
546 * mmioSeek [MMSYSTEM.1214]
548 LONG WINAPI
mmioSeek16(HMMIO16 hmmio
, LONG lOffset
, INT16 iOrigin
)
550 return mmioSeek32(hmmio
,lOffset
,iOrigin
);
553 /**************************************************************************
554 * mmioGetInfo [MMSYSTEM.1215]
556 UINT16 WINAPI
mmioGetInfo16(HMMIO16 hmmio
, MMIOINFO16
* lpmmioinfo
, UINT16 uFlags
)
558 LPMMIOINFO16 lpmminfo
;
559 TRACE(mmio
, "mmioGetInfo\n");
560 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
561 if (lpmminfo
== NULL
) return 0;
562 memcpy(lpmmioinfo
, lpmminfo
, sizeof(MMIOINFO16
));
563 GlobalUnlock16(hmmio
);
567 /**************************************************************************
568 * mmioGetInfo [WINMM.118]
570 UINT32 WINAPI
mmioGetInfo32(HMMIO32 hmmio
, MMIOINFO32
*lpmmioinfo
, UINT32 uFlags
)
573 LPMMIOINFO16 lpmminfo
=&mmioinfo
;
576 TRACE(mmio
, "(0x%04x,%p,0x%08x)\n",hmmio
,lpmmioinfo
,uFlags
);
577 ret
= mmioGetInfo16(hmmio
,&mmioinfo
,uFlags
);
580 lpmmioinfo
->dwFlags
= lpmminfo
->dwFlags
;
581 lpmmioinfo
->fccIOProc
= lpmminfo
->fccIOProc
;
582 lpmmioinfo
->pIOProc
= (LPMMIOPROC32
)lpmminfo
->pIOProc
;
583 lpmmioinfo
->wErrorRet
= lpmminfo
->wErrorRet
;
584 lpmmioinfo
->htask
= lpmminfo
->htask
;
585 lpmmioinfo
->cchBuffer
= lpmminfo
->cchBuffer
;
586 lpmmioinfo
->pchBuffer
= lpmminfo
->pchBuffer
;
587 lpmmioinfo
->pchNext
= lpmminfo
->pchNext
;
588 lpmmioinfo
->pchEndRead
= lpmminfo
->pchEndRead
;
589 lpmmioinfo
->pchEndWrite
= lpmminfo
->pchEndWrite
;
590 lpmmioinfo
->lBufOffset
= lpmminfo
->lBufOffset
;
591 lpmmioinfo
->lDiskOffset
= lpmminfo
->lDiskOffset
;
592 memcpy(lpmmioinfo
->adwInfo
,lpmminfo
->adwInfo
,sizeof(lpmminfo
->adwInfo
));
593 lpmmioinfo
->dwReserved1
= lpmminfo
->dwReserved1
;
594 lpmmioinfo
->dwReserved2
= lpmminfo
->dwReserved2
;
595 lpmmioinfo
->hmmio
= lpmminfo
->hmmio
;
599 /**************************************************************************
600 * mmioSetInfo [MMSYSTEM.1216]
602 UINT16 WINAPI
mmioSetInfo16(HMMIO16 hmmio
, const MMIOINFO16
* lpmmioinfo
, UINT16 uFlags
)
604 LPMMIOINFO16 lpmminfo
;
605 TRACE(mmio
, "mmioSetInfo\n");
606 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
607 if (lpmminfo
== NULL
) return 0;
608 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
609 lpmminfo
->pchEndRead
= lpmmioinfo
->pchEndRead
;
610 GlobalUnlock16(hmmio
);
614 /**************************************************************************
615 * mmioSetInfo [WINMM.130]
617 UINT32 WINAPI
mmioSetInfo32(HMMIO32 hmmio
, const MMIOINFO32
* lpmmioinfo
, UINT32 uFlags
)
619 LPMMIOINFO16 lpmminfo
;
620 TRACE(mmio
, "mmioSetInfo\n");
621 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
622 if (lpmminfo
== NULL
) return 0;
623 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
624 lpmminfo
->pchEndRead
= lpmmioinfo
->pchEndRead
;
625 GlobalUnlock16(hmmio
);
629 /**************************************************************************
630 * mmioSetBuffer [WINMM.129]
632 UINT32 WINAPI
mmioSetBuffer32(HMMIO32 hmmio
, LPSTR pchBuffer
,
633 LONG cchBuffer
, UINT32 uFlags
)
635 LPMMIOINFO16 lpmminfo
;
637 if (mmioFlush32(hmmio
, MMIO_EMPTYBUF
) != 0)
638 return MMIOERR_CANNOTWRITE
;
640 TRACE(mmio
, "(hmmio=%04x, pchBuf=%p, cchBuf=%ld, uFlags=%#08x)\n",
641 hmmio
, pchBuffer
, cchBuffer
, uFlags
);
643 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
644 if (lpmminfo
== NULL
) return 0;
645 if ((!cchBuffer
|| pchBuffer
) && lpmminfo
->dwFlags
&MMIO_ALLOCBUF
) {
646 GlobalUnlock16(lpmminfo
->dwReserved1
);
647 GlobalFree16(lpmminfo
->dwReserved1
);
648 lpmminfo
->dwFlags
&= ~MMIO_ALLOCBUF
;
651 lpmminfo
->pchBuffer
= pchBuffer
;
652 } else if (lpmminfo
->dwFlags
&MMIO_ALLOCBUF
) {
654 GlobalUnlock16(lpmminfo
->dwReserved1
);
655 hNewBuf
= GlobalReAlloc16(lpmminfo
->dwReserved1
, cchBuffer
, 0);
657 /* FIXME: this assumes the memory block didn't move */
658 GlobalLock16(lpmminfo
->dwReserved1
);
659 GlobalUnlock16(hmmio
);
660 return MMIOERR_OUTOFMEMORY
;
662 lpmminfo
->dwReserved1
= hNewBuf
;
663 lpmminfo
->pchBuffer
= GlobalLock16(hNewBuf
);
664 } else if (cchBuffer
) {
665 HGLOBAL16 hNewBuf
= GlobalAlloc16(GMEM_MOVEABLE
, cchBuffer
);
667 GlobalUnlock16(hmmio
);
668 return MMIOERR_OUTOFMEMORY
;
670 lpmminfo
->dwReserved1
= hNewBuf
;
671 lpmminfo
->pchBuffer
= GlobalLock16(hNewBuf
);
672 lpmminfo
->dwFlags
|= MMIO_ALLOCBUF
;
674 lpmminfo
->pchBuffer
= NULL
;
675 lpmminfo
->cchBuffer
= cchBuffer
;
676 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
677 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
678 lpmminfo
->pchEndWrite
= lpmminfo
->pchBuffer
+ cchBuffer
;
679 lpmminfo
->lBufOffset
= 0;
681 GlobalUnlock16(hmmio
);
685 /**************************************************************************
686 * mmioSetBuffer [MMSYSTEM.1217]
688 UINT16 WINAPI
mmioSetBuffer16(HMMIO16 hmmio
, LPSTR pchBuffer
,
689 LONG cchBuffer
, UINT16 uFlags
)
691 return mmioSetBuffer32(hmmio
, pchBuffer
, cchBuffer
, uFlags
);
694 /**************************************************************************
695 * mmioFlush [WINMM.117]
697 UINT32 WINAPI
mmioFlush32(HMMIO32 hmmio
, UINT32 uFlags
)
699 LPMMIOINFO16 lpmminfo
;
700 TRACE(mmio
, "(%04X, %04X)\n", hmmio
, uFlags
);
701 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
702 if (lpmminfo
== NULL
) return 0;
704 if ((!lpmminfo
->cchBuffer
)||(lpmminfo
->fccIOProc
==FOURCC_MEM
)) {
705 GlobalUnlock16(hmmio
);
708 /* not quite sure what to do here, but I'll guess */
709 if (lpmminfo
->dwFlags
& MMIO_DIRTY
) {
710 mmioSendMessage(hmmio
, MMIOM_SEEK
,
711 (LPARAM
) lpmminfo
->lBufOffset
,
713 mmioSendMessage(hmmio
, MMIOM_WRITE
,
714 (LPARAM
) lpmminfo
->pchBuffer
,
715 (LPARAM
) (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
) );
716 lpmminfo
->dwFlags
&= ~MMIO_DIRTY
;
718 if (uFlags
& MMIO_EMPTYBUF
) {
719 /* seems Windows doesn't do any seeking here, hopefully this
720 won't matter, otherwise a slight rewrite is necessary */
721 mmioSendMessage(hmmio
, MMIOM_SEEK
,
722 (LPARAM
) (lpmminfo
->lBufOffset
+
723 (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
)),
725 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
726 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
727 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
730 GlobalUnlock16(hmmio
);
734 /**************************************************************************
735 * mmioFlush [MMSYSTEM.1218]
737 UINT16 WINAPI
mmioFlush16(HMMIO16 hmmio
, UINT16 uFlags
)
739 return mmioFlush32(hmmio
,uFlags
);
742 /**************************************************************************
743 * mmioAdvance [MMSYSTEM.1219]
745 UINT32 WINAPI
mmioAdvance32(HMMIO32 hmmio
,MMIOINFO32
*lpmmioinfo
,UINT32 uFlags
)
747 LPMMIOINFO16 lpmminfo
;
748 TRACE(mmio
, "mmioAdvance\n");
749 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
750 if (lpmminfo
== NULL
) return 0;
751 if (!lpmminfo
->cchBuffer
) {
752 GlobalUnlock16(hmmio
);
753 return MMIOERR_UNBUFFERED
;
755 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
756 if (mmioFlush32(hmmio
, MMIO_EMPTYBUF
)) {
757 GlobalUnlock16(hmmio
);
758 return MMIOERR_CANNOTWRITE
;
760 if (uFlags
== MMIO_READ
)
761 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchBuffer
+
762 mmioSendMessage(hmmio
, MMIOM_READ
,
763 (LPARAM
) lpmmioinfo
->pchBuffer
,
764 (LPARAM
) lpmmioinfo
->cchBuffer
);
765 #if 0 /* mmioFlush32 already did the writing */
766 if (uFlags
== MMIO_WRITE
)
767 mmioSendMessage(hmmio
, MMIOM_WRITE
,
768 (LPARAM
) lpmmioinfo
->pchBuffer
,
769 (LPARAM
) lpmmioinfo
->cchBuffer
);
771 lpmmioinfo
->pchNext
= lpmmioinfo
->pchBuffer
;
772 GlobalUnlock16(hmmio
);
776 /**************************************************************************
777 * mmioAdvance [MMSYSTEM.1219]
779 UINT16 WINAPI
mmioAdvance16(HMMIO16 hmmio
,MMIOINFO16
*lpmmioinfo
,UINT16 uFlags
)
781 LPMMIOINFO16 lpmminfo
;
782 TRACE(mmio
, "mmioAdvance\n");
783 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
784 if (lpmminfo
== NULL
) return 0;
785 if (!lpmminfo
->cchBuffer
) {
786 GlobalUnlock16(hmmio
);
787 return MMIOERR_UNBUFFERED
;
789 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
790 if (mmioFlush32(hmmio
, MMIO_EMPTYBUF
)) {
791 GlobalUnlock16(hmmio
);
792 return MMIOERR_CANNOTWRITE
;
794 if (uFlags
== MMIO_READ
)
795 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchBuffer
+
796 mmioSendMessage(hmmio
, MMIOM_READ
,
797 (LPARAM
) lpmmioinfo
->pchBuffer
,
798 (LPARAM
) lpmmioinfo
->cchBuffer
);
799 #if 0 /* mmioFlush32 already did the writing */
800 if (uFlags
== MMIO_WRITE
)
801 mmioSendMessage(hmmio
, MMIOM_WRITE
,
802 (LPARAM
) lpmmioinfo
->pchBuffer
,
803 (LPARAM
) lpmmioinfo
->cchBuffer
);
805 lpmmioinfo
->pchNext
= lpmmioinfo
->pchBuffer
;
806 GlobalUnlock16(hmmio
);
810 /**************************************************************************
811 * mmioStringToFOURCCA [WINMM.131]
813 FOURCC WINAPI
mmioStringToFOURCC32A(LPCSTR sz
, UINT32 uFlags
)
815 return mmioStringToFOURCC16(sz
,uFlags
);
818 /**************************************************************************
819 * mmioStringToFOURCCW [WINMM.132]
821 FOURCC WINAPI
mmioStringToFOURCC32W(LPCWSTR sz
, UINT32 uFlags
)
823 LPSTR szA
= HEAP_strdupWtoA(GetProcessHeap(),0,sz
);
824 FOURCC ret
= mmioStringToFOURCC32A(szA
,uFlags
);
826 HeapFree(GetProcessHeap(),0,szA
);
830 /**************************************************************************
831 * mmioStringToFOURCC [MMSYSTEM.1220]
833 FOURCC WINAPI
mmioStringToFOURCC16(LPCSTR sz
, UINT16 uFlags
)
835 return mmioFOURCC(sz
[0],sz
[1],sz
[2],sz
[3]);
838 /**************************************************************************
839 * mmioInstallIOProc16 [MMSYSTEM.1221]
841 LPMMIOPROC16 WINAPI
mmioInstallIOProc16(FOURCC fccIOProc
,
842 LPMMIOPROC16 pIOProc
, DWORD dwFlags
)
844 TRACE(mmio
, "(%ld, %p, %08lX)\n",
845 fccIOProc
, pIOProc
, dwFlags
);
847 if (dwFlags
& MMIO_GLOBALPROC
) {
848 FIXME(mmio
, " global procedures not implemented\n");
851 /* just handle the known procedures for now */
852 switch(dwFlags
& (MMIO_INSTALLPROC
|MMIO_REMOVEPROC
|MMIO_FINDPROC
)) {
853 case MMIO_INSTALLPROC
:
855 case MMIO_REMOVEPROC
:
858 if (fccIOProc
== FOURCC_DOS
)
859 return (LPMMIOPROC16
) mmioDosIOProc
;
860 else if (fccIOProc
== FOURCC_MEM
)
861 return (LPMMIOPROC16
) mmioMemIOProc
;
869 /**************************************************************************
870 * mmioInstallIOProc32A [WINMM.120]
872 LPMMIOPROC32 WINAPI
mmioInstallIOProc32A(FOURCC fccIOProc
,
873 LPMMIOPROC32 pIOProc
, DWORD dwFlags
)
875 FIXME(mmio
, "(%c%c%c%c,%p,0x%08lx) -- empty stub \n",
876 (char)((fccIOProc
&0xff000000)>>24),
877 (char)((fccIOProc
&0x00ff0000)>>16),
878 (char)((fccIOProc
&0x0000ff00)>> 8),
879 (char)(fccIOProc
&0x000000ff),
884 /**************************************************************************
885 * mmioSendMessage [MMSYSTEM.1222]
887 LRESULT WINAPI
mmioSendMessage(HMMIO16 hmmio
, UINT16 uMessage
,
888 LPARAM lParam1
, LPARAM lParam2
)
890 LPMMIOINFO16 lpmminfo
;
892 const char *msg
= NULL
;
896 #define msgname(x) case x: msg = #x; break;
898 msgname(MMIOM_CLOSE
);
900 msgname(MMIOM_WRITE
);
901 msgname(MMIOM_WRITEFLUSH
);
903 msgname(MMIOM_RENAME
);
909 TRACE(mmio
, "(%04X, %s, %ld, %ld)\n",
910 hmmio
, msg
, lParam1
, lParam2
);
912 TRACE(mmio
, "(%04X, %u, %ld, %ld)\n",
913 hmmio
, uMessage
, lParam1
, lParam2
);
915 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
917 if (lpmminfo
&& lpmminfo
->pIOProc
)
918 result
= (*lpmminfo
->pIOProc
)((LPSTR
)lpmminfo
, uMessage
, lParam1
, lParam2
);
920 result
= MMSYSERR_INVALPARAM
;
922 GlobalUnlock16(hmmio
);
927 /**************************************************************************
928 * mmioDescend [MMSYSTEM.1223]
930 UINT16 WINAPI
mmioDescend(HMMIO16 hmmio
, MMCKINFO
* lpck
,
931 const MMCKINFO
* lpckParent
, UINT16 uFlags
)
933 DWORD dwfcc
, dwOldPos
;
935 TRACE(mmio
, "(%04X, %p, %p, %04X);\n",
936 hmmio
, lpck
, lpckParent
, uFlags
);
942 TRACE(mmio
, "dwfcc=%08lX\n", dwfcc
);
944 dwOldPos
= mmioSeek32(hmmio
, 0, SEEK_CUR
);
945 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
947 if (lpckParent
!= NULL
) {
948 TRACE(mmio
, "seek inside parent at %ld !\n", lpckParent
->dwDataOffset
);
949 dwOldPos
= mmioSeek32(hmmio
,lpckParent
->dwDataOffset
,SEEK_SET
);
953 It seems to be that FINDRIFF should not be treated the same as the
954 other FINDxxx so I treat it as a MMIO_FINDxxx
956 if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDRIFF) ||
957 (uFlags & MMIO_FINDLIST)) {
959 if ((uFlags
& MMIO_FINDCHUNK
) || (uFlags
& MMIO_FINDLIST
)) {
960 TRACE(mmio
, "MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc
);
964 ix
= mmioRead32(hmmio
, (LPSTR
)lpck
, 3 * sizeof(DWORD
));
965 TRACE(mmio
, "after _lread32 ix = %ld req = %d, errno = %d\n",ix
,3 * sizeof(DWORD
),errno
);
966 if (ix
< sizeof(DWORD
)) {
967 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
968 WARN(mmio
, "return ChunkNotFound\n");
969 return MMIOERR_CHUNKNOTFOUND
;
971 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
972 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
973 lpck
->dwDataOffset
+= sizeof(DWORD
);
974 if (ix
< lpck
->dwDataOffset
- dwOldPos
) {
975 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
976 WARN(mmio
, "return ChunkNotFound\n");
977 return MMIOERR_CHUNKNOTFOUND
;
979 TRACE(mmio
, "dwfcc=%08lX ckid=%08lX cksize=%08lX !\n",
980 dwfcc
, lpck
->ckid
, lpck
->cksize
);
981 if (dwfcc
== lpck
->ckid
)
984 dwOldPos
= lpck
->dwDataOffset
+ lpck
->cksize
;
985 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
989 if (mmioRead32(hmmio
, (LPSTR
)lpck
, sizeof(MMCKINFO
)) < sizeof(MMCKINFO
)) {
990 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
991 WARN(mmio
, "return ChunkNotFound 2nd\n");
992 return MMIOERR_CHUNKNOTFOUND
;
994 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
995 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
996 lpck
->dwDataOffset
+= sizeof(DWORD
);
998 mmioSeek32(hmmio
, lpck
->dwDataOffset
, SEEK_SET
);
1000 TRACE(mmio
, "lpck->ckid=%08lX lpck->cksize=%ld !\n",
1001 lpck
->ckid
, lpck
->cksize
);
1002 TRACE(mmio
, "lpck->fccType=%08lX !\n", lpck
->fccType
);
1007 /**************************************************************************
1008 * mmioAscend [WINMM.113]
1010 UINT32 WINAPI
mmioAscend32(HMMIO32 hmmio
, MMCKINFO
* lpck
, UINT32 uFlags
)
1012 TRACE(mmio
, "(%04X, %p, %04X);\n",
1013 hmmio
, lpck
, uFlags
);
1014 if (lpck
->dwFlags
&MMIO_DIRTY
) {
1015 DWORD dwOldPos
, dwNewSize
, dwSizePos
;
1017 TRACE(mmio
, "chunk is marked MMIO_DIRTY, correcting chunk size\n");
1018 dwOldPos
= mmioSeek32(hmmio
, 0, SEEK_CUR
);
1019 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
1020 dwNewSize
= dwOldPos
- lpck
->dwDataOffset
;
1021 if (dwNewSize
!= lpck
->cksize
) {
1022 TRACE(mmio
, "dwNewSize=%ld\n", dwNewSize
);
1023 lpck
->cksize
= dwNewSize
;
1025 dwSizePos
= lpck
->dwDataOffset
- sizeof(DWORD
);
1026 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1027 dwSizePos
-= sizeof(DWORD
);
1028 TRACE(mmio
, "dwSizePos=%ld\n", dwSizePos
);
1030 mmioSeek32(hmmio
, dwSizePos
, SEEK_SET
);
1031 mmioWrite32(hmmio
, (LPSTR
)&dwNewSize
, sizeof(DWORD
));
1034 mmioSeek32(hmmio
,lpck
->dwDataOffset
+lpck
->cksize
,SEEK_SET
);
1039 /**************************************************************************
1040 * mmioAscend [MMSYSTEM.1224]
1042 UINT16 WINAPI
mmioAscend16(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
1044 return mmioAscend32(hmmio
,lpck
,uFlags
);
1047 /**************************************************************************
1048 * mmioCreateChunk [MMSYSTEM.1225]
1050 UINT16 WINAPI
mmioCreateChunk16(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
1055 TRACE(mmio
, "(%04X, %p, %04X);\n",
1056 hmmio
, lpck
, uFlags
);
1058 dwOldPos
= mmioSeek32(hmmio
, 0, SEEK_CUR
);
1059 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
1061 if (uFlags
== MMIO_CREATELIST
)
1062 lpck
->ckid
= FOURCC_LIST
;
1063 else if (uFlags
== MMIO_CREATERIFF
)
1064 lpck
->ckid
= FOURCC_RIFF
;
1066 TRACE(mmio
, "ckid=%08lX\n", lpck
->ckid
);
1068 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
1069 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1070 lpck
->dwDataOffset
+= sizeof(DWORD
);
1071 lpck
->dwFlags
= MMIO_DIRTY
;
1073 ix
= mmioWrite32(hmmio
, (LPSTR
)lpck
, lpck
->dwDataOffset
- dwOldPos
);
1074 TRACE(mmio
, "after _lwrite32 ix = %ld req = %ld, errno = %d\n",ix
,lpck
->dwDataOffset
- dwOldPos
,errno
);
1075 if (ix
< lpck
->dwDataOffset
- dwOldPos
) {
1077 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
1078 WARN(mmio
, "return CannotWrite\n");
1079 return MMIOERR_CANNOTWRITE
;
1085 /**************************************************************************
1086 * mmioCreateChunk [WINMM.115]
1088 UINT32 WINAPI
mmioCreateChunk32(HMMIO32 hmmio
, MMCKINFO
* lpck
, UINT32 uFlags
)
1090 return mmioCreateChunk16(hmmio
, lpck
, uFlags
);
1093 /**************************************************************************
1094 * mmioRename [MMSYSTEM.1226]
1096 UINT16 WINAPI
mmioRename16(LPCSTR szFileName
, LPCSTR szNewFileName
,
1097 MMIOINFO16
* lpmmioinfo
, DWORD dwRenameFlags
)
1100 LPMMIOINFO16 lpmminfo
;
1103 TRACE(mmio
, "('%s', '%s', %p, %08lX);\n",
1104 szFileName
, szNewFileName
, lpmmioinfo
, dwRenameFlags
);
1106 hmmio
= GlobalAlloc16(GHND
, sizeof(MMIOINFO16
));
1107 lpmminfo
= (LPMMIOINFO16
) GlobalLock16(hmmio
);
1110 memcpy(lpmminfo
, lpmmioinfo
, sizeof(MMIOINFO16
));
1112 /* assume DOS file if not otherwise specified */
1113 if (lpmminfo
->fccIOProc
== 0 && lpmminfo
->pIOProc
== NULL
) {
1115 lpmminfo
->fccIOProc
= mmioFOURCC('D', 'O', 'S', ' ');
1116 lpmminfo
->pIOProc
= (LPMMIOPROC16
) mmioDosIOProc
;
1119 /* if just the four character code is present, look up IO proc */
1120 else if (lpmminfo
->pIOProc
== NULL
) {
1122 lpmminfo
->pIOProc
= mmioInstallIOProc16(lpmminfo
->fccIOProc
, NULL
, MMIO_FINDPROC
);
1125 /* (if IO proc specified, use it and specified four character code) */
1127 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_RENAME
, (LPARAM
) szFileName
, (LPARAM
) szNewFileName
);
1129 GlobalUnlock16(hmmio
);
1130 GlobalFree16(hmmio
);
1135 /**************************************************************************
1136 * mmioRenameA [WINMM.125]
1138 UINT32 WINAPI
mmioRename32A(LPCSTR szFileName
, LPCSTR szNewFileName
,
1139 MMIOINFO32
* lpmmioinfo
, DWORD dwRenameFlags
)
1141 FIXME(mmio
, "This may fail\n");
1142 return mmioRename16(szFileName
, szNewFileName
, (MMIOINFO16
*)lpmmioinfo
, dwRenameFlags
);
1145 /**************************************************************************
1146 * mmioRenameW [WINMM.126]
1148 UINT32 WINAPI
mmioRename32W(LPCWSTR szFileName
, LPCWSTR szNewFileName
,
1149 MMIOINFO32
* lpmmioinfo
, DWORD dwRenameFlags
)
1151 LPSTR szFn
= HEAP_strdupWtoA(GetProcessHeap(), 0, szFileName
);
1152 LPSTR sznFn
= HEAP_strdupWtoA(GetProcessHeap(), 0, szNewFileName
);
1153 UINT32 ret
= mmioRename32A(szFn
, sznFn
, lpmmioinfo
, dwRenameFlags
);
1155 HeapFree(GetProcessHeap(),0,szFn
);
1156 HeapFree(GetProcessHeap(),0,sznFn
);