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
= mmioSetBuffer(hmmio
, NULL
, MMIO_DEFAULTBUFFER
, 0))) {
291 lpmmioinfo
->wErrorRet
= result
;
295 if (lpmminfo
->fccIOProc
== FOURCC_MEM
) {
296 if ((result
= mmioSetBuffer(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 mmioSetBuffer(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 [WINM.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 [MMSYSTEM.1217]
632 UINT16 WINAPI
mmioSetBuffer(HMMIO16 hmmio
, LPSTR pchBuffer
,
633 LONG cchBuffer
, UINT16 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
;
653 if (lpmminfo
->dwFlags
&MMIO_ALLOCBUF
) {
655 GlobalUnlock16(lpmminfo
->dwReserved1
);
656 hNewBuf
= GlobalReAlloc16(lpmminfo
->dwReserved1
, cchBuffer
, 0);
658 /* FIXME: this assumes the memory block didn't move */
659 GlobalLock16(lpmminfo
->dwReserved1
);
660 GlobalUnlock16(hmmio
);
661 return MMIOERR_OUTOFMEMORY
;
663 lpmminfo
->dwReserved1
= hNewBuf
;
664 lpmminfo
->pchBuffer
= GlobalLock16(hNewBuf
);
667 HGLOBAL16 hNewBuf
= GlobalAlloc16(GMEM_MOVEABLE
, cchBuffer
);
669 GlobalUnlock16(hmmio
);
670 return MMIOERR_OUTOFMEMORY
;
672 lpmminfo
->dwReserved1
= hNewBuf
;
673 lpmminfo
->pchBuffer
= GlobalLock16(hNewBuf
);
674 lpmminfo
->dwFlags
|= MMIO_ALLOCBUF
;
676 lpmminfo
->pchBuffer
= NULL
;
677 lpmminfo
->cchBuffer
= cchBuffer
;
678 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
679 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
680 lpmminfo
->pchEndWrite
= lpmminfo
->pchBuffer
+ cchBuffer
;
681 lpmminfo
->lBufOffset
= 0;
683 GlobalUnlock16(hmmio
);
687 /**************************************************************************
688 * mmioFlush [WINMM.117]
690 UINT32 WINAPI
mmioFlush32(HMMIO32 hmmio
, UINT32 uFlags
)
692 LPMMIOINFO16 lpmminfo
;
693 TRACE(mmio
, "(%04X, %04X)\n", hmmio
, uFlags
);
694 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
695 if (lpmminfo
== NULL
) return 0;
697 if ((!lpmminfo
->cchBuffer
)||(lpmminfo
->fccIOProc
==FOURCC_MEM
)) {
698 GlobalUnlock16(hmmio
);
701 /* not quite sure what to do here, but I'll guess */
702 if (lpmminfo
->dwFlags
& MMIO_DIRTY
) {
703 mmioSendMessage(hmmio
, MMIOM_SEEK
,
704 (LPARAM
) lpmminfo
->lBufOffset
,
706 mmioSendMessage(hmmio
, MMIOM_WRITE
,
707 (LPARAM
) lpmminfo
->pchBuffer
,
708 (LPARAM
) (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
) );
709 lpmminfo
->dwFlags
&= ~MMIO_DIRTY
;
711 if (uFlags
& MMIO_EMPTYBUF
) {
712 /* seems Windows doesn't do any seeking here, hopefully this
713 won't matter, otherwise a slight rewrite is necessary */
714 mmioSendMessage(hmmio
, MMIOM_SEEK
,
715 (LPARAM
) (lpmminfo
->lBufOffset
+
716 (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
)),
718 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
719 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
720 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
723 GlobalUnlock16(hmmio
);
727 /**************************************************************************
728 * mmioFlush [MMSYSTEM.1218]
730 UINT16 WINAPI
mmioFlush16(HMMIO16 hmmio
, UINT16 uFlags
)
732 return mmioFlush32(hmmio
,uFlags
);
735 /**************************************************************************
736 * mmioAdvance [MMSYSTEM.1219]
738 UINT32 WINAPI
mmioAdvance32(HMMIO32 hmmio
,MMIOINFO32
*lpmmioinfo
,UINT32 uFlags
)
740 LPMMIOINFO16 lpmminfo
;
741 TRACE(mmio
, "mmioAdvance\n");
742 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
743 if (lpmminfo
== NULL
) return 0;
744 if (!lpmminfo
->cchBuffer
) {
745 GlobalUnlock16(hmmio
);
746 return MMIOERR_UNBUFFERED
;
748 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
749 if (mmioFlush32(hmmio
, MMIO_EMPTYBUF
)) {
750 GlobalUnlock16(hmmio
);
751 return MMIOERR_CANNOTWRITE
;
753 if (uFlags
== MMIO_READ
)
754 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchBuffer
+
755 mmioSendMessage(hmmio
, MMIOM_READ
,
756 (LPARAM
) lpmmioinfo
->pchBuffer
,
757 (LPARAM
) lpmmioinfo
->cchBuffer
);
758 #if 0 /* mmioFlush32 already did the writing */
759 if (uFlags
== MMIO_WRITE
)
760 mmioSendMessage(hmmio
, MMIOM_WRITE
,
761 (LPARAM
) lpmmioinfo
->pchBuffer
,
762 (LPARAM
) lpmmioinfo
->cchBuffer
);
764 lpmmioinfo
->pchNext
= lpmmioinfo
->pchBuffer
;
765 GlobalUnlock16(hmmio
);
769 /**************************************************************************
770 * mmioAdvance [MMSYSTEM.1219]
772 UINT16 WINAPI
mmioAdvance16(HMMIO16 hmmio
,MMIOINFO16
*lpmmioinfo
,UINT16 uFlags
)
774 LPMMIOINFO16 lpmminfo
;
775 TRACE(mmio
, "mmioAdvance\n");
776 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
777 if (lpmminfo
== NULL
) return 0;
778 if (!lpmminfo
->cchBuffer
) {
779 GlobalUnlock16(hmmio
);
780 return MMIOERR_UNBUFFERED
;
782 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
783 if (mmioFlush32(hmmio
, MMIO_EMPTYBUF
)) {
784 GlobalUnlock16(hmmio
);
785 return MMIOERR_CANNOTWRITE
;
787 if (uFlags
== MMIO_READ
)
788 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchBuffer
+
789 mmioSendMessage(hmmio
, MMIOM_READ
,
790 (LPARAM
) lpmmioinfo
->pchBuffer
,
791 (LPARAM
) lpmmioinfo
->cchBuffer
);
792 #if 0 /* mmioFlush32 already did the writing */
793 if (uFlags
== MMIO_WRITE
)
794 mmioSendMessage(hmmio
, MMIOM_WRITE
,
795 (LPARAM
) lpmmioinfo
->pchBuffer
,
796 (LPARAM
) lpmmioinfo
->cchBuffer
);
798 lpmmioinfo
->pchNext
= lpmmioinfo
->pchBuffer
;
799 GlobalUnlock16(hmmio
);
803 /**************************************************************************
804 * mmioStringToFOURCCA [WINMM.131]
806 FOURCC WINAPI
mmioStringToFOURCC32A(LPCSTR sz
, UINT32 uFlags
)
808 return mmioStringToFOURCC16(sz
,uFlags
);
811 /**************************************************************************
812 * mmioStringToFOURCCW [WINMM.132]
814 FOURCC WINAPI
mmioStringToFOURCC32W(LPCWSTR sz
, UINT32 uFlags
)
816 LPSTR szA
= HEAP_strdupWtoA(GetProcessHeap(),0,sz
);
817 FOURCC ret
= mmioStringToFOURCC32A(szA
,uFlags
);
819 HeapFree(GetProcessHeap(),0,szA
);
823 /**************************************************************************
824 * mmioStringToFOURCC [MMSYSTEM.1220]
826 FOURCC WINAPI
mmioStringToFOURCC16(LPCSTR sz
, UINT16 uFlags
)
828 return mmioFOURCC(sz
[0],sz
[1],sz
[2],sz
[3]);
831 /**************************************************************************
832 * mmioInstallIOProc16 [MMSYSTEM.1221]
834 LPMMIOPROC16 WINAPI
mmioInstallIOProc16(FOURCC fccIOProc
,
835 LPMMIOPROC16 pIOProc
, DWORD dwFlags
)
837 TRACE(mmio
, "(%ld, %p, %08lX)\n",
838 fccIOProc
, pIOProc
, dwFlags
);
840 if (dwFlags
& MMIO_GLOBALPROC
) {
841 FIXME(mmio
, " global procedures not implemented\n");
844 /* just handle the known procedures for now */
845 switch(dwFlags
& (MMIO_INSTALLPROC
|MMIO_REMOVEPROC
|MMIO_FINDPROC
)) {
846 case MMIO_INSTALLPROC
:
848 case MMIO_REMOVEPROC
:
851 if (fccIOProc
== FOURCC_DOS
)
852 return (LPMMIOPROC16
) mmioDosIOProc
;
853 else if (fccIOProc
== FOURCC_MEM
)
854 return (LPMMIOPROC16
) mmioMemIOProc
;
862 /**************************************************************************
863 * mmioInstallIOProc32A [WINMM.120]
865 LPMMIOPROC32 WINAPI
mmioInstallIOProc32A(FOURCC fccIOProc
,
866 LPMMIOPROC32 pIOProc
, DWORD dwFlags
)
868 FIXME(mmio
, "(%c%c%c%c,%p,0x%08lx) -- empty stub \n",
869 (char)((fccIOProc
&0xff000000)>>24),
870 (char)((fccIOProc
&0x00ff0000)>>16),
871 (char)((fccIOProc
&0x0000ff00)>> 8),
872 (char)(fccIOProc
&0x000000ff),
877 /**************************************************************************
878 * mmioSendMessage [MMSYSTEM.1222]
880 LRESULT WINAPI
mmioSendMessage(HMMIO16 hmmio
, UINT16 uMessage
,
881 LPARAM lParam1
, LPARAM lParam2
)
883 LPMMIOINFO16 lpmminfo
;
885 const char *msg
= NULL
;
889 #define msgname(x) case x: msg = #x; break;
891 msgname(MMIOM_CLOSE
);
893 msgname(MMIOM_WRITE
);
894 msgname(MMIOM_WRITEFLUSH
);
896 msgname(MMIOM_RENAME
);
902 TRACE(mmio
, "(%04X, %s, %ld, %ld)\n",
903 hmmio
, msg
, lParam1
, lParam2
);
905 TRACE(mmio
, "(%04X, %u, %ld, %ld)\n",
906 hmmio
, uMessage
, lParam1
, lParam2
);
908 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
910 if (lpmminfo
&& lpmminfo
->pIOProc
)
911 result
= (*lpmminfo
->pIOProc
)((LPSTR
)lpmminfo
, uMessage
, lParam1
, lParam2
);
913 result
= MMSYSERR_INVALPARAM
;
915 GlobalUnlock16(hmmio
);
920 /**************************************************************************
921 * mmioDescend [MMSYSTEM.1223]
923 UINT16 WINAPI
mmioDescend(HMMIO16 hmmio
, MMCKINFO
* lpck
,
924 const MMCKINFO
* lpckParent
, UINT16 uFlags
)
926 DWORD dwfcc
, dwOldPos
;
928 TRACE(mmio
, "(%04X, %p, %p, %04X);\n",
929 hmmio
, lpck
, lpckParent
, uFlags
);
935 TRACE(mmio
, "dwfcc=%08lX\n", dwfcc
);
937 dwOldPos
= mmioSeek32(hmmio
, 0, SEEK_CUR
);
938 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
940 if (lpckParent
!= NULL
) {
941 TRACE(mmio
, "seek inside parent at %ld !\n", lpckParent
->dwDataOffset
);
942 dwOldPos
= mmioSeek32(hmmio
,lpckParent
->dwDataOffset
,SEEK_SET
);
946 It seems to be that FINDRIFF should not be treated the same as the
947 other FINDxxx so I treat it as a MMIO_FINDxxx
949 if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDRIFF) ||
950 (uFlags & MMIO_FINDLIST)) {
952 if ((uFlags
& MMIO_FINDCHUNK
) || (uFlags
& MMIO_FINDLIST
)) {
953 TRACE(mmio
, "MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc
);
957 ix
= mmioRead32(hmmio
, (LPSTR
)lpck
, 3 * sizeof(DWORD
));
958 TRACE(mmio
, "after _lread32 ix = %ld req = %d, errno = %d\n",ix
,3 * sizeof(DWORD
),errno
);
959 if (ix
< sizeof(DWORD
)) {
960 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
961 WARN(mmio
, "return ChunkNotFound\n");
962 return MMIOERR_CHUNKNOTFOUND
;
964 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
965 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
966 lpck
->dwDataOffset
+= sizeof(DWORD
);
967 if (ix
< lpck
->dwDataOffset
- dwOldPos
) {
968 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
969 WARN(mmio
, "return ChunkNotFound\n");
970 return MMIOERR_CHUNKNOTFOUND
;
972 TRACE(mmio
, "dwfcc=%08lX ckid=%08lX cksize=%08lX !\n",
973 dwfcc
, lpck
->ckid
, lpck
->cksize
);
974 if (dwfcc
== lpck
->ckid
)
977 dwOldPos
= lpck
->dwDataOffset
+ lpck
->cksize
;
978 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
982 if (mmioRead32(hmmio
, (LPSTR
)lpck
, sizeof(MMCKINFO
)) < sizeof(MMCKINFO
)) {
983 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
984 WARN(mmio
, "return ChunkNotFound 2nd\n");
985 return MMIOERR_CHUNKNOTFOUND
;
987 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
988 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
989 lpck
->dwDataOffset
+= sizeof(DWORD
);
991 mmioSeek32(hmmio
, lpck
->dwDataOffset
, SEEK_SET
);
993 TRACE(mmio
, "lpck->ckid=%08lX lpck->cksize=%ld !\n",
994 lpck
->ckid
, lpck
->cksize
);
995 TRACE(mmio
, "lpck->fccType=%08lX !\n", lpck
->fccType
);
1000 /**************************************************************************
1001 * mmioAscend [WINMM.113]
1003 UINT32 WINAPI
mmioAscend32(HMMIO32 hmmio
, MMCKINFO
* lpck
, UINT32 uFlags
)
1005 TRACE(mmio
, "(%04X, %p, %04X);\n",
1006 hmmio
, lpck
, uFlags
);
1007 if (lpck
->dwFlags
&MMIO_DIRTY
) {
1008 DWORD dwOldPos
, dwNewSize
, dwSizePos
;
1010 TRACE(mmio
, "chunk is marked MMIO_DIRTY, correcting chunk size\n");
1011 dwOldPos
= mmioSeek32(hmmio
, 0, SEEK_CUR
);
1012 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
1013 dwNewSize
= dwOldPos
- lpck
->dwDataOffset
;
1014 if (dwNewSize
!= lpck
->cksize
) {
1015 TRACE(mmio
, "dwNewSize=%ld\n", dwNewSize
);
1016 lpck
->cksize
= dwNewSize
;
1018 dwSizePos
= lpck
->dwDataOffset
- sizeof(DWORD
);
1019 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1020 dwSizePos
-= sizeof(DWORD
);
1021 TRACE(mmio
, "dwSizePos=%ld\n", dwSizePos
);
1023 mmioSeek32(hmmio
, dwSizePos
, SEEK_SET
);
1024 mmioWrite32(hmmio
, (LPSTR
)&dwNewSize
, sizeof(DWORD
));
1027 mmioSeek32(hmmio
,lpck
->dwDataOffset
+lpck
->cksize
,SEEK_SET
);
1032 /**************************************************************************
1033 * mmioAscend [MMSYSTEM.1224]
1035 UINT16 WINAPI
mmioAscend16(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
1037 return mmioAscend32(hmmio
,lpck
,uFlags
);
1040 /**************************************************************************
1041 * mmioCreateChunk [MMSYSTEM.1225]
1043 UINT16 WINAPI
mmioCreateChunk(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
1048 TRACE(mmio
, "(%04X, %p, %04X);\n",
1049 hmmio
, lpck
, uFlags
);
1051 dwOldPos
= mmioSeek32(hmmio
, 0, SEEK_CUR
);
1052 TRACE(mmio
, "dwOldPos=%ld\n", dwOldPos
);
1054 if (uFlags
== MMIO_CREATELIST
)
1055 lpck
->ckid
= FOURCC_LIST
;
1056 else if (uFlags
== MMIO_CREATERIFF
)
1057 lpck
->ckid
= FOURCC_RIFF
;
1059 TRACE(mmio
, "ckid=%08lX\n", lpck
->ckid
);
1061 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
1062 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1063 lpck
->dwDataOffset
+= sizeof(DWORD
);
1064 lpck
->dwFlags
= MMIO_DIRTY
;
1066 ix
= mmioWrite32(hmmio
, (LPSTR
)lpck
, lpck
->dwDataOffset
- dwOldPos
);
1067 TRACE(mmio
, "after _lwrite32 ix = %ld req = %ld, errno = %d\n",ix
,lpck
->dwDataOffset
- dwOldPos
,errno
);
1068 if (ix
< lpck
->dwDataOffset
- dwOldPos
) {
1070 mmioSeek32(hmmio
, dwOldPos
, SEEK_SET
);
1071 WARN(mmio
, "return CannotWrite\n");
1072 return MMIOERR_CANNOTWRITE
;
1079 /**************************************************************************
1080 * mmioRename [MMSYSTEM.1226]
1082 UINT16 WINAPI
mmioRename(LPCSTR szFileName
, LPCSTR szNewFileName
,
1083 MMIOINFO16
* lpmmioinfo
, DWORD dwRenameFlags
)
1086 LPMMIOINFO16 lpmminfo
;
1089 TRACE(mmio
, "('%s', '%s', %p, %08lX);\n",
1090 szFileName
, szNewFileName
, lpmmioinfo
, dwRenameFlags
);
1092 hmmio
= GlobalAlloc16(GHND
, sizeof(MMIOINFO16
));
1093 lpmminfo
= (LPMMIOINFO16
) GlobalLock16(hmmio
);
1096 memcpy(lpmminfo
, lpmmioinfo
, sizeof(MMIOINFO16
));
1098 /* assume DOS file if not otherwise specified */
1099 if (lpmminfo
->fccIOProc
== 0 && lpmminfo
->pIOProc
== NULL
) {
1101 lpmminfo
->fccIOProc
= mmioFOURCC('D', 'O', 'S', ' ');
1102 lpmminfo
->pIOProc
= (LPMMIOPROC16
) mmioDosIOProc
;
1105 /* if just the four character code is present, look up IO proc */
1106 else if (lpmminfo
->pIOProc
== NULL
) {
1108 lpmminfo
->pIOProc
= mmioInstallIOProc16(lpmminfo
->fccIOProc
, NULL
, MMIO_FINDPROC
);
1111 /* (if IO proc specified, use it and specified four character code) */
1113 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_RENAME
, (LPARAM
) szFileName
, (LPARAM
) szNewFileName
);
1115 GlobalUnlock16(hmmio
);
1116 GlobalFree16(hmmio
);