4 * Copyright 1998 Andrew Taylor
5 * Copyright 1998 Ove Kåven
14 #include "wine/winbase16.h"
16 #include "selectors.h"
19 #include "debugtools.h"
21 DEFAULT_DEBUG_CHANNEL(mmio
)
23 /**************************************************************************
24 * mmioDosIOProc [internal]
26 static LRESULT
mmioDosIOProc(LPMMIOINFO16 lpmmioinfo
, UINT16 uMessage
, LPARAM lParam1
, LPARAM lParam2
) {
27 TRACE("(%p, %X, %ld, %ld);\n", lpmmioinfo
, uMessage
, lParam1
, lParam2
);
33 * lParam1 = szFileName parameter from mmioOpen
34 * lParam2 = reserved (we use it for 16-bitness)
35 * Returns: zero on success, error code on error
36 * NOTE: lDiskOffset automatically set to zero
40 LPSTR szFileName
= (LPSTR
) lParam1
;
42 if (lpmmioinfo
->dwFlags
& MMIO_GETTEMP
) {
43 FIXME("MMIO_GETTEMP not implemented\n");
44 return MMIOERR_CANNOTOPEN
;
47 /* if filename NULL, assume open file handle in adwInfo[0] */
49 if (lParam2
) lpmmioinfo
->adwInfo
[0] =
50 FILE_GetHandle(lpmmioinfo
->adwInfo
[0]);
54 lpmmioinfo
->adwInfo
[0] =
55 (DWORD
) OpenFile(szFileName
, &ofs
, lpmmioinfo
->dwFlags
);
56 if (lpmmioinfo
->adwInfo
[0] == -1)
57 return MMIOERR_CANNOTOPEN
;
64 * lParam1 = wFlags parameter from mmioClose
66 * Returns: zero on success, error code on error
69 UINT16 uFlags
= (UINT16
) lParam1
;
71 if (uFlags
& MMIO_FHOPEN
)
74 _lclose((HFILE
)lpmmioinfo
->adwInfo
[0]);
81 * lParam1 = huge pointer to read buffer
82 * lParam2 = number of bytes to read
83 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
85 * NOTE: lDiskOffset should be updated
88 HPSTR pch
= (HPSTR
) lParam1
;
89 LONG cch
= (LONG
) lParam2
;
92 count
= _lread((HFILE
)lpmmioinfo
->adwInfo
[0], pch
, cch
);
94 lpmmioinfo
->lDiskOffset
+= count
;
100 case MMIOM_WRITEFLUSH
: {
101 /* no internal buffering, so WRITEFLUSH handled same as WRITE */
104 * lParam1 = huge pointer to write buffer
105 * lParam2 = number of bytes to write
106 * Returns: number of bytes written, -1 for error (error code in
108 * NOTE: lDiskOffset should be updated
111 HPSTR pch
= (HPSTR
) lParam1
;
112 LONG cch
= (LONG
) lParam2
;
115 count
= _hwrite((HFILE
)lpmmioinfo
->adwInfo
[0], pch
, cch
);
117 lpmmioinfo
->lDiskOffset
+= count
;
124 * lParam1 = new position
125 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
126 * Returns: new file postion, -1 on error
127 * NOTE: lDiskOffset should be updated
130 LONG Offset
= (LONG
) lParam1
;
131 LONG Whence
= (LONG
) lParam2
;
134 pos
= _llseek((HFILE
)lpmmioinfo
->adwInfo
[0], Offset
, Whence
);
136 lpmmioinfo
->lDiskOffset
= pos
;
145 * Returns: zero on success, non-zero on failure
148 FIXME("MMIOM_RENAME unimplemented\n");
149 return MMIOERR_FILENOTFOUND
;
153 FIXME("unexpected message %u\n", uMessage
);
160 /**************************************************************************
161 * mmioMemIOProc [internal]
163 static LRESULT
mmioMemIOProc(LPMMIOINFO16 lpmmioinfo
, UINT16 uMessage
, LPARAM lParam1
, LPARAM lParam2
) {
164 TRACE("(%p,0x%04x,0x%08lx,0x%08lx)\n",lpmmioinfo
,uMessage
,lParam1
,lParam2
);
169 * lParam1 = filename (must be NULL)
170 * lParam2 = reserved (we use it for 16-bitness)
171 * Returns: zero on success, error code on error
172 * NOTE: lDiskOffset automatically set to zero
175 if (!(lpmmioinfo
->dwFlags
& MMIO_CREATE
))
176 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchEndWrite
;
183 * lParam1 = wFlags parameter from mmioClose
185 * Returns: zero on success, error code on error
194 * lParam1 = huge pointer to read buffer
195 * lParam2 = number of bytes to read
196 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
198 * NOTE: lDiskOffset should be updated
201 /* HPSTR pch = (HPSTR) lParam1; */
202 /* LONG cch = (LONG) lParam2; */
204 FIXME("MMIOM_READ on memory files should not occur, buffer may be lost!\n");
209 case MMIOM_WRITEFLUSH
: {
210 /* no internal buffering, so WRITEFLUSH handled same as WRITE */
213 * lParam1 = huge pointer to write buffer
214 * lParam2 = number of bytes to write
215 * Returns: number of bytes written, -1 for error (error code in
217 * NOTE: lDiskOffset should be updated
220 /* HPSTR pch = (HPSTR) lParam1; */
221 /* LONG cch = (LONG) lParam2; */
223 FIXME("MMIOM_WRITE on memory files should not occur, buffer may be lost!\n");
229 * lParam1 = new position
230 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
231 * Returns: new file postion, -1 on error
232 * NOTE: lDiskOffset should be updated
235 /* LONG Offset = (LONG) lParam1; */
236 /* LONG Whence = (LONG) lParam2; */
238 FIXME("MMIOM_SEEK on memory files should not occur, buffer may be lost!\n");
243 FIXME("unexpected message %u\n", uMessage
);
250 /**************************************************************************
251 * MMIO_Open [internal]
253 static HMMIO16
MMIO_Open(LPSTR szFileName
, MMIOINFO16
* lpmmioinfo
,
254 DWORD dwOpenFlags
, int use16
)
256 LPMMIOINFO16 lpmminfo
;
260 TRACE("('%s', %p, %08lX);\n", szFileName
, lpmmioinfo
, dwOpenFlags
);
262 if (dwOpenFlags
& MMIO_PARSE
) {
263 char buffer
[MAX_PATH
];
265 if (GetFullPathNameA(szFileName
, sizeof(buffer
), buffer
, NULL
) >= sizeof(buffer
))
266 return (HMMIO16
)FALSE
;
267 strcpy(szFileName
, buffer
);
268 return (HMMIO16
)TRUE
;
271 hmmio
= GlobalAlloc16(GHND
, sizeof(MMIOINFO16
));
272 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
273 if (lpmminfo
== NULL
)
275 memset(lpmminfo
, 0, sizeof(MMIOINFO16
));
277 /* assume DOS file if not otherwise specified */
279 (lpmmioinfo
->fccIOProc
== 0 && lpmmioinfo
->pIOProc
== NULL
)) {
281 lpmminfo
->fccIOProc
= FOURCC_DOS
;
282 lpmminfo
->pIOProc
= (LPMMIOPROC16
) mmioDosIOProc
;
284 /* if just the four character code is present, look up IO proc */
285 else if (lpmmioinfo
->pIOProc
== NULL
) {
287 lpmminfo
->fccIOProc
= lpmmioinfo
->fccIOProc
;
288 lpmminfo
->pIOProc
= mmioInstallIOProc16(lpmmioinfo
->fccIOProc
, NULL
, MMIO_FINDPROC
);
291 /* if IO proc specified, use it and specified four character code */
294 lpmminfo
->fccIOProc
= lpmmioinfo
->fccIOProc
;
295 lpmminfo
->pIOProc
= lpmmioinfo
->pIOProc
;
298 if (dwOpenFlags
& MMIO_ALLOCBUF
) {
299 if ((result
= mmioSetBuffer16(hmmio
, NULL
, MMIO_DEFAULTBUFFER
, 0))) {
301 lpmmioinfo
->wErrorRet
= result
;
305 if (lpmminfo
->fccIOProc
== FOURCC_MEM
) {
306 if ((result
= mmioSetBuffer16(hmmio
,
308 PTR_SEG_TO_LIN(lpmmioinfo
->pchBuffer
) :
309 lpmmioinfo
->pchBuffer
,
310 lpmmioinfo
->cchBuffer
, 0))) {
312 lpmmioinfo
->wErrorRet
= result
;
317 lpmminfo
->dwFlags
= dwOpenFlags
;
318 lpmminfo
->hmmio
= hmmio
;
320 /* call IO proc to actually open file */
321 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_OPEN
, (LPARAM
) szFileName
, (LPARAM
) use16
);
323 GlobalUnlock16(hmmio
);
333 /**************************************************************************
334 * mmioOpenW [WINMM.123]
336 HMMIO WINAPI
mmioOpenW(LPWSTR szFileName
, MMIOINFO
* lpmmioinfo
,
339 LPSTR szFn
= HEAP_strdupWtoA(GetProcessHeap(),0,szFileName
);
340 HMMIO ret
= MMIO_Open(szFn
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
,FALSE
);
342 HeapFree(GetProcessHeap(),0,szFn
);
346 /**************************************************************************
347 * mmioOpenA [WINMM.122]
349 HMMIO WINAPI
mmioOpenA(LPSTR szFileName
, MMIOINFO
* lpmmioinfo
,
352 return MMIO_Open(szFileName
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
,FALSE
);
355 /**************************************************************************
356 * mmioOpen [MMSYSTEM.1210]
358 HMMIO16 WINAPI
mmioOpen16(LPSTR szFileName
, MMIOINFO16
* lpmmioinfo
,
361 return MMIO_Open(szFileName
,(LPMMIOINFO16
)lpmmioinfo
,dwOpenFlags
,TRUE
);
365 /**************************************************************************
366 * mmioClose [WINMM.114]
368 MMRESULT WINAPI
mmioClose(HMMIO hmmio
, UINT uFlags
)
370 LPMMIOINFO16 lpmminfo
;
373 TRACE("(%04X, %04X);\n", hmmio
, uFlags
);
375 lpmminfo
= (LPMMIOINFO16
) GlobalLock16(hmmio
);
376 if (lpmminfo
== NULL
)
379 /* flush the file - if error reported, ignore */
380 if (mmioFlush(hmmio
, MMIO_EMPTYBUF
) != 0)
381 lpmminfo
->dwFlags
&= ~MMIO_DIRTY
;
383 result
= mmioSendMessage(hmmio
,MMIOM_CLOSE
,(LPARAM
)uFlags
,(LPARAM
)0);
385 mmioSetBuffer16(hmmio
, NULL
, 0, 0);
387 GlobalUnlock16(hmmio
);
394 /**************************************************************************
395 * mmioClose [MMSYSTEM.1211]
397 MMRESULT16 WINAPI
mmioClose16(HMMIO16 hmmio
, UINT16 uFlags
)
399 return mmioClose(hmmio
,uFlags
);
404 /**************************************************************************
405 * mmioRead [WINMM.124]
407 LONG WINAPI
mmioRead(HMMIO hmmio
, HPSTR pch
, LONG cch
)
410 LPMMIOINFO16 lpmminfo
;
412 TRACE("(%04X, %p, %ld);\n", hmmio
, pch
, cch
);
414 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
415 if (lpmminfo
== NULL
)
418 if (lpmminfo
->pchNext
!= lpmminfo
->pchEndRead
) {
419 count
= lpmminfo
->pchEndRead
- lpmminfo
->pchNext
;
420 if (count
> cch
|| count
< 0) count
= cch
;
421 memcpy(pch
, lpmminfo
->pchNext
, count
);
422 lpmminfo
->pchNext
+= count
;
428 if (cch
&&(lpmminfo
->fccIOProc
!=FOURCC_MEM
)) {
429 if (lpmminfo
->cchBuffer
) {
430 mmioFlush(hmmio
, MMIO_EMPTYBUF
);
434 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
435 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
436 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
437 size
= mmioSendMessage(hmmio
, MMIOM_READ
,
438 (LPARAM
) lpmminfo
->pchBuffer
,
439 (LPARAM
) lpmminfo
->cchBuffer
);
441 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
+ size
;
442 if (size
> cch
) size
= cch
;
443 memcpy(pch
, lpmminfo
->pchNext
, size
);
444 lpmminfo
->pchNext
+= size
;
450 count
+= mmioSendMessage(hmmio
, MMIOM_READ
, (LPARAM
) pch
, (LPARAM
) cch
);
451 if (count
>0) lpmminfo
->lBufOffset
+= count
;
455 GlobalUnlock16(hmmio
);
456 TRACE("count=%ld\n", count
);
460 /**************************************************************************
461 * mmioRead [MMSYSTEM.1212]
463 LONG WINAPI
mmioRead16(HMMIO16 hmmio
, HPSTR pch
, LONG cch
)
465 return mmioRead(hmmio
,pch
,cch
);
468 /**************************************************************************
469 * mmioWrite [WINMM.133]
471 LONG WINAPI
mmioWrite(HMMIO hmmio
, HPCSTR pch
, LONG cch
)
474 LPMMIOINFO16 lpmminfo
;
476 TRACE("(%04X, %p, %ld);\n", hmmio
, pch
, cch
);
478 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
479 if (lpmminfo
== NULL
)
482 if (lpmminfo
->cchBuffer
) {
485 if (lpmminfo
->pchNext
!= lpmminfo
->pchEndWrite
) {
486 count
= lpmminfo
->pchEndWrite
- lpmminfo
->pchNext
;
487 if (count
> cch
|| count
< 0) count
= cch
;
488 memcpy(lpmminfo
->pchNext
, pch
, count
);
489 lpmminfo
->pchNext
+= count
;
492 lpmminfo
->dwFlags
|= MMIO_DIRTY
;
494 if (lpmminfo
->fccIOProc
==FOURCC_MEM
) {
495 if (lpmminfo
->adwInfo
[0]) {
496 /* from where would we get the memory handle? */
497 FIXME("memory file expansion not implemented!\n");
501 if (lpmminfo
->pchNext
== lpmminfo
->pchEndWrite
502 && mmioFlush(hmmio
, MMIO_EMPTYBUF
)) break;
505 count
= mmioSendMessage(hmmio
, MMIOM_WRITE
, (LPARAM
) pch
, (LPARAM
) cch
);
506 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
509 GlobalUnlock16(hmmio
);
510 TRACE("count=%ld\n", count
);
514 /**************************************************************************
515 * mmioWrite [MMSYSTEM.1213]
517 LONG WINAPI
mmioWrite16(HMMIO16 hmmio
, HPCSTR pch
, LONG cch
)
519 return mmioWrite(hmmio
,pch
,cch
);
522 /**************************************************************************
523 * mmioSeek [MMSYSTEM.1214]
525 LONG WINAPI
mmioSeek(HMMIO hmmio
, LONG lOffset
, INT iOrigin
)
528 LPMMIOINFO16 lpmminfo
;
530 TRACE("(%04X, %08lX, %d);\n", hmmio
, lOffset
, iOrigin
);
532 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
533 if (lpmminfo
== NULL
)
536 offset
= (iOrigin
==SEEK_SET
)?(lOffset
- lpmminfo
->lBufOffset
):
537 (iOrigin
==SEEK_CUR
)?(lOffset
+
538 (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
)):-1;
540 if ((lpmminfo
->cchBuffer
<0)||
541 ((offset
>=0)&&(offset
<=(lpmminfo
->pchEndRead
-lpmminfo
->pchBuffer
)))) {
542 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
+ offset
;
543 GlobalUnlock16(hmmio
);
544 return lpmminfo
->lBufOffset
+ offset
;
547 if ((lpmminfo
->fccIOProc
==FOURCC_MEM
)||mmioFlush(hmmio
, MMIO_EMPTYBUF
)) {
548 GlobalUnlock16(hmmio
);
552 offset
= mmioSendMessage(hmmio
, MMIOM_SEEK
, (LPARAM
) lOffset
, (LPARAM
) iOrigin
);
553 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
555 GlobalUnlock16(hmmio
);
559 /**************************************************************************
560 * mmioSeek [MMSYSTEM.1214]
562 LONG WINAPI
mmioSeek16(HMMIO16 hmmio
, LONG lOffset
, INT16 iOrigin
)
564 return mmioSeek(hmmio
,lOffset
,iOrigin
);
567 /**************************************************************************
568 * mmioGetInfo [MMSYSTEM.1215]
570 UINT16 WINAPI
mmioGetInfo16(HMMIO16 hmmio
, MMIOINFO16
* lpmmioinfo
, UINT16 uFlags
)
572 LPMMIOINFO16 lpmminfo
;
573 TRACE("mmioGetInfo\n");
574 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
575 if (lpmminfo
== NULL
) return 0;
576 memcpy(lpmmioinfo
, lpmminfo
, sizeof(MMIOINFO16
));
577 GlobalUnlock16(hmmio
);
581 /**************************************************************************
582 * mmioGetInfo [WINMM.118]
584 UINT WINAPI
mmioGetInfo(HMMIO hmmio
, MMIOINFO
*lpmmioinfo
, UINT uFlags
)
587 LPMMIOINFO16 lpmminfo
=&mmioinfo
;
590 TRACE("(0x%04x,%p,0x%08x)\n",hmmio
,lpmmioinfo
,uFlags
);
591 ret
= mmioGetInfo16(hmmio
,&mmioinfo
,uFlags
);
594 lpmmioinfo
->dwFlags
= lpmminfo
->dwFlags
;
595 lpmmioinfo
->fccIOProc
= lpmminfo
->fccIOProc
;
596 lpmmioinfo
->pIOProc
= (LPMMIOPROC
)lpmminfo
->pIOProc
;
597 lpmmioinfo
->wErrorRet
= lpmminfo
->wErrorRet
;
598 lpmmioinfo
->htask
= lpmminfo
->htask
;
599 lpmmioinfo
->cchBuffer
= lpmminfo
->cchBuffer
;
600 lpmmioinfo
->pchBuffer
= lpmminfo
->pchBuffer
;
601 lpmmioinfo
->pchNext
= lpmminfo
->pchNext
;
602 lpmmioinfo
->pchEndRead
= lpmminfo
->pchEndRead
;
603 lpmmioinfo
->pchEndWrite
= lpmminfo
->pchEndWrite
;
604 lpmmioinfo
->lBufOffset
= lpmminfo
->lBufOffset
;
605 lpmmioinfo
->lDiskOffset
= lpmminfo
->lDiskOffset
;
606 memcpy(lpmmioinfo
->adwInfo
,lpmminfo
->adwInfo
,sizeof(lpmminfo
->adwInfo
));
607 lpmmioinfo
->dwReserved1
= lpmminfo
->dwReserved1
;
608 lpmmioinfo
->dwReserved2
= lpmminfo
->dwReserved2
;
609 lpmmioinfo
->hmmio
= lpmminfo
->hmmio
;
613 /**************************************************************************
614 * mmioSetInfo [MMSYSTEM.1216]
616 UINT16 WINAPI
mmioSetInfo16(HMMIO16 hmmio
, const MMIOINFO16
* lpmmioinfo
, UINT16 uFlags
)
618 LPMMIOINFO16 lpmminfo
;
619 TRACE("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 * mmioSetInfo [WINMM.130]
631 UINT WINAPI
mmioSetInfo(HMMIO hmmio
, const MMIOINFO
* lpmmioinfo
, UINT uFlags
)
633 LPMMIOINFO16 lpmminfo
;
634 TRACE("mmioSetInfo\n");
635 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
636 if (lpmminfo
== NULL
) return 0;
637 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
638 lpmminfo
->pchEndRead
= lpmmioinfo
->pchEndRead
;
639 GlobalUnlock16(hmmio
);
643 /**************************************************************************
644 * mmioSetBuffer [WINMM.129]
646 UINT WINAPI
mmioSetBuffer(HMMIO hmmio
, LPSTR pchBuffer
,
647 LONG cchBuffer
, UINT uFlags
)
649 LPMMIOINFO16 lpmminfo
;
651 if (mmioFlush(hmmio
, MMIO_EMPTYBUF
) != 0)
652 return MMIOERR_CANNOTWRITE
;
654 TRACE("(hmmio=%04x, pchBuf=%p, cchBuf=%ld, uFlags=%#08x)\n",
655 hmmio
, pchBuffer
, cchBuffer
, uFlags
);
657 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
658 if (lpmminfo
== NULL
) return 0;
659 if ((!cchBuffer
|| pchBuffer
) && lpmminfo
->dwFlags
&MMIO_ALLOCBUF
) {
660 GlobalUnlock16(lpmminfo
->dwReserved1
);
661 GlobalFree16(lpmminfo
->dwReserved1
);
662 lpmminfo
->dwFlags
&= ~MMIO_ALLOCBUF
;
665 lpmminfo
->pchBuffer
= pchBuffer
;
666 } else if (lpmminfo
->dwFlags
&MMIO_ALLOCBUF
) {
668 GlobalUnlock16(lpmminfo
->dwReserved1
);
669 hNewBuf
= GlobalReAlloc16(lpmminfo
->dwReserved1
, cchBuffer
, 0);
671 /* FIXME: this assumes the memory block didn't move */
672 GlobalLock16(lpmminfo
->dwReserved1
);
673 GlobalUnlock16(hmmio
);
674 return MMIOERR_OUTOFMEMORY
;
676 lpmminfo
->dwReserved1
= hNewBuf
;
677 lpmminfo
->pchBuffer
= GlobalLock16(hNewBuf
);
678 } else if (cchBuffer
) {
679 HGLOBAL16 hNewBuf
= GlobalAlloc16(GMEM_MOVEABLE
, cchBuffer
);
681 GlobalUnlock16(hmmio
);
682 return MMIOERR_OUTOFMEMORY
;
684 lpmminfo
->dwReserved1
= hNewBuf
;
685 lpmminfo
->pchBuffer
= GlobalLock16(hNewBuf
);
686 lpmminfo
->dwFlags
|= MMIO_ALLOCBUF
;
688 lpmminfo
->pchBuffer
= NULL
;
689 lpmminfo
->cchBuffer
= cchBuffer
;
690 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
691 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
692 lpmminfo
->pchEndWrite
= lpmminfo
->pchBuffer
+ cchBuffer
;
693 lpmminfo
->lBufOffset
= 0;
695 GlobalUnlock16(hmmio
);
699 /**************************************************************************
700 * mmioSetBuffer [MMSYSTEM.1217]
702 UINT16 WINAPI
mmioSetBuffer16(HMMIO16 hmmio
, LPSTR pchBuffer
,
703 LONG cchBuffer
, UINT16 uFlags
)
705 return mmioSetBuffer(hmmio
, pchBuffer
, cchBuffer
, uFlags
);
708 /**************************************************************************
709 * mmioFlush [WINMM.117]
711 UINT WINAPI
mmioFlush(HMMIO hmmio
, UINT uFlags
)
713 LPMMIOINFO16 lpmminfo
;
714 TRACE("(%04X, %04X)\n", hmmio
, uFlags
);
715 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
716 if (lpmminfo
== NULL
) return 0;
718 if ((!lpmminfo
->cchBuffer
)||(lpmminfo
->fccIOProc
==FOURCC_MEM
)) {
719 GlobalUnlock16(hmmio
);
722 /* not quite sure what to do here, but I'll guess */
723 if (lpmminfo
->dwFlags
& MMIO_DIRTY
) {
724 mmioSendMessage(hmmio
, MMIOM_SEEK
,
725 (LPARAM
) lpmminfo
->lBufOffset
,
727 mmioSendMessage(hmmio
, MMIOM_WRITE
,
728 (LPARAM
) lpmminfo
->pchBuffer
,
729 (LPARAM
) (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
) );
730 lpmminfo
->dwFlags
&= ~MMIO_DIRTY
;
732 if (uFlags
& MMIO_EMPTYBUF
) {
733 /* seems Windows doesn't do any seeking here, hopefully this
734 won't matter, otherwise a slight rewrite is necessary */
735 mmioSendMessage(hmmio
, MMIOM_SEEK
,
736 (LPARAM
) (lpmminfo
->lBufOffset
+
737 (lpmminfo
->pchNext
- lpmminfo
->pchBuffer
)),
739 lpmminfo
->pchNext
= lpmminfo
->pchBuffer
;
740 lpmminfo
->pchEndRead
= lpmminfo
->pchBuffer
;
741 lpmminfo
->lBufOffset
= lpmminfo
->lDiskOffset
;
744 GlobalUnlock16(hmmio
);
748 /**************************************************************************
749 * mmioFlush [MMSYSTEM.1218]
751 UINT16 WINAPI
mmioFlush16(HMMIO16 hmmio
, UINT16 uFlags
)
753 return mmioFlush(hmmio
,uFlags
);
756 /**************************************************************************
757 * mmioAdvance [MMSYSTEM.1219]
759 UINT WINAPI
mmioAdvance(HMMIO hmmio
,MMIOINFO
*lpmmioinfo
,UINT uFlags
)
761 LPMMIOINFO16 lpmminfo
;
762 TRACE("mmioAdvance\n");
763 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
764 if (lpmminfo
== NULL
) return 0;
765 if (!lpmminfo
->cchBuffer
) {
766 GlobalUnlock16(hmmio
);
767 return MMIOERR_UNBUFFERED
;
769 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
770 if (mmioFlush(hmmio
, MMIO_EMPTYBUF
)) {
771 GlobalUnlock16(hmmio
);
772 return MMIOERR_CANNOTWRITE
;
774 if (uFlags
== MMIO_READ
)
775 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchBuffer
+
776 mmioSendMessage(hmmio
, MMIOM_READ
,
777 (LPARAM
) lpmmioinfo
->pchBuffer
,
778 (LPARAM
) lpmmioinfo
->cchBuffer
);
779 #if 0 /* mmioFlush already did the writing */
780 if (uFlags
== MMIO_WRITE
)
781 mmioSendMessage(hmmio
, MMIOM_WRITE
,
782 (LPARAM
) lpmmioinfo
->pchBuffer
,
783 (LPARAM
) lpmmioinfo
->cchBuffer
);
785 lpmmioinfo
->pchNext
= lpmmioinfo
->pchBuffer
;
786 GlobalUnlock16(hmmio
);
790 /**************************************************************************
791 * mmioAdvance [MMSYSTEM.1219]
793 UINT16 WINAPI
mmioAdvance16(HMMIO16 hmmio
,MMIOINFO16
*lpmmioinfo
,UINT16 uFlags
)
795 LPMMIOINFO16 lpmminfo
;
796 TRACE("mmioAdvance\n");
797 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
798 if (lpmminfo
== NULL
) return 0;
799 if (!lpmminfo
->cchBuffer
) {
800 GlobalUnlock16(hmmio
);
801 return MMIOERR_UNBUFFERED
;
803 lpmminfo
->pchNext
= lpmmioinfo
->pchNext
;
804 if (mmioFlush(hmmio
, MMIO_EMPTYBUF
)) {
805 GlobalUnlock16(hmmio
);
806 return MMIOERR_CANNOTWRITE
;
808 if (uFlags
== MMIO_READ
)
809 lpmmioinfo
->pchEndRead
= lpmmioinfo
->pchBuffer
+
810 mmioSendMessage(hmmio
, MMIOM_READ
,
811 (LPARAM
) lpmmioinfo
->pchBuffer
,
812 (LPARAM
) lpmmioinfo
->cchBuffer
);
813 #if 0 /* mmioFlush already did the writing */
814 if (uFlags
== MMIO_WRITE
)
815 mmioSendMessage(hmmio
, MMIOM_WRITE
,
816 (LPARAM
) lpmmioinfo
->pchBuffer
,
817 (LPARAM
) lpmmioinfo
->cchBuffer
);
819 lpmmioinfo
->pchNext
= lpmmioinfo
->pchBuffer
;
820 GlobalUnlock16(hmmio
);
824 /**************************************************************************
825 * mmioStringToFOURCCA [WINMM.131]
827 FOURCC WINAPI
mmioStringToFOURCCA(LPCSTR sz
, UINT uFlags
)
829 return mmioStringToFOURCC16(sz
,uFlags
);
832 /**************************************************************************
833 * mmioStringToFOURCCW [WINMM.132]
835 FOURCC WINAPI
mmioStringToFOURCCW(LPCWSTR sz
, UINT uFlags
)
837 LPSTR szA
= HEAP_strdupWtoA(GetProcessHeap(),0,sz
);
838 FOURCC ret
= mmioStringToFOURCCA(szA
,uFlags
);
840 HeapFree(GetProcessHeap(),0,szA
);
844 /**************************************************************************
845 * mmioStringToFOURCC [MMSYSTEM.1220]
847 FOURCC WINAPI
mmioStringToFOURCC16(LPCSTR sz
, UINT16 uFlags
)
849 return mmioFOURCC(sz
[0],sz
[1],sz
[2],sz
[3]);
852 /**************************************************************************
853 * mmioInstallIOProc16 [MMSYSTEM.1221]
855 LPMMIOPROC16 WINAPI
mmioInstallIOProc16(FOURCC fccIOProc
,
856 LPMMIOPROC16 pIOProc
, DWORD dwFlags
)
858 TRACE("(%ld, %p, %08lX)\n",
859 fccIOProc
, pIOProc
, dwFlags
);
861 if (dwFlags
& MMIO_GLOBALPROC
) {
862 FIXME(" global procedures not implemented\n");
865 /* just handle the known procedures for now */
866 switch(dwFlags
& (MMIO_INSTALLPROC
|MMIO_REMOVEPROC
|MMIO_FINDPROC
)) {
867 case MMIO_INSTALLPROC
:
869 case MMIO_REMOVEPROC
:
872 if (fccIOProc
== FOURCC_DOS
)
873 return (LPMMIOPROC16
) mmioDosIOProc
;
874 else if (fccIOProc
== FOURCC_MEM
)
875 return (LPMMIOPROC16
) mmioMemIOProc
;
883 /**************************************************************************
884 * mmioInstallIOProcA [WINMM.120]
886 LPMMIOPROC WINAPI
mmioInstallIOProcA(FOURCC fccIOProc
,
887 LPMMIOPROC pIOProc
, DWORD dwFlags
)
889 FIXME("(%c%c%c%c,%p,0x%08lx) -- empty stub \n",
890 (char)((fccIOProc
&0xff000000)>>24),
891 (char)((fccIOProc
&0x00ff0000)>>16),
892 (char)((fccIOProc
&0x0000ff00)>> 8),
893 (char)(fccIOProc
&0x000000ff),
898 /**************************************************************************
899 * mmioSendMessage [MMSYSTEM.1222]
901 LRESULT WINAPI
mmioSendMessage(HMMIO16 hmmio
, UINT16 uMessage
,
902 LPARAM lParam1
, LPARAM lParam2
)
904 LPMMIOINFO16 lpmminfo
;
906 const char *msg
= NULL
;
910 #define msgname(x) case x: msg = #x; break;
912 msgname(MMIOM_CLOSE
);
914 msgname(MMIOM_WRITE
);
915 msgname(MMIOM_WRITEFLUSH
);
917 msgname(MMIOM_RENAME
);
923 TRACE("(%04X, %s, %ld, %ld)\n",
924 hmmio
, msg
, lParam1
, lParam2
);
926 TRACE("(%04X, %u, %ld, %ld)\n",
927 hmmio
, uMessage
, lParam1
, lParam2
);
929 lpmminfo
= (LPMMIOINFO16
)GlobalLock16(hmmio
);
931 if (lpmminfo
&& lpmminfo
->pIOProc
)
932 result
= (*lpmminfo
->pIOProc
)((LPSTR
)lpmminfo
, uMessage
, lParam1
, lParam2
);
934 result
= MMSYSERR_INVALPARAM
;
936 GlobalUnlock16(hmmio
);
941 /**************************************************************************
942 * mmioDescend [MMSYSTEM.1223]
944 UINT16 WINAPI
mmioDescend(HMMIO16 hmmio
, LPMMCKINFO lpck
,
945 const MMCKINFO
* lpckParent
, UINT16 uFlags
)
951 TRACE("(%04X, %p, %p, %04X);\n",hmmio
,lpck
,lpckParent
,uFlags
);
954 return MMSYSERR_INVALPARAM
;
956 dwOldPos
= mmioSeek(hmmio
, 0, SEEK_CUR
);
957 TRACE("dwOldPos=%ld\n", dwOldPos
);
959 if (lpckParent
!= NULL
) {
960 TRACE("seek inside parent at %ld !\n", lpckParent
->dwDataOffset
);
961 /* EPP: was dwOldPos = mmioSeek(hmmio,lpckParent->dwDataOffset,SEEK_SET); */
962 if (dwOldPos
< lpckParent
->dwDataOffset
|| dwOldPos
>= lpckParent
->dwDataOffset
+ lpckParent
->cksize
) {
963 ERR("outside parent chunk\n");
964 return MMIOERR_CHUNKNOTFOUND
;
968 /* The SDK docu says 'ckid' is used for all cases. Real World
969 * examples disagree -Marcus,990216.
972 searchcki
.fccType
= 0;
973 /* find_chunk looks for 'ckid' */
974 if (uFlags
& MMIO_FINDCHUNK
)
975 searchcki
.ckid
= lpck
->ckid
;
976 /* find_riff and find_list look for 'fccType' */
977 if (uFlags
& MMIO_FINDLIST
) {
978 searchcki
.ckid
= FOURCC_LIST
;
979 searchcki
.fccType
= lpck
->fccType
;
981 if (uFlags
& MMIO_FINDRIFF
) {
982 searchcki
.ckid
= FOURCC_RIFF
;
983 searchcki
.fccType
= lpck
->fccType
;
985 memcpy(&fcc
,&(searchcki
.fccType
),4);fcc
[4]=0;
986 memcpy(&ckid
,&(searchcki
.ckid
),4);ckid
[4]=0;
987 TRACE("searching for %s.%s\n",ckid
,searchcki
.fccType
?fcc
:"<any>");
989 if (uFlags
& (MMIO_FINDCHUNK
|MMIO_FINDLIST
|MMIO_FINDRIFF
)) {
993 ix
= mmioRead(hmmio
, (LPSTR
)lpck
, 3 * sizeof(DWORD
));
994 if (ix
< 2*sizeof(DWORD
)) {
995 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
996 WARN("return ChunkNotFound\n");
997 return MMIOERR_CHUNKNOTFOUND
;
999 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
1000 if (ix
< lpck
->dwDataOffset
- dwOldPos
) {
1001 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
1002 WARN("return ChunkNotFound\n");
1003 return MMIOERR_CHUNKNOTFOUND
;
1005 memcpy(ckid
,&lpck
->ckid
,4);
1006 memcpy(fcc
,&lpck
->fccType
,4);
1007 TRACE("ckid=%s fcc=%s cksize=%08lX !\n",
1008 ckid
, searchcki
.fccType
?fcc
:"<unused>",
1010 if ((searchcki
.ckid
== lpck
->ckid
) &&
1011 (!searchcki
.fccType
||
1012 (searchcki
.fccType
== lpck
->fccType
)
1017 dwOldPos
= lpck
->dwDataOffset
+ ((lpck
->cksize
+ 1) & ~1);
1018 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
1020 /* If we were looking for RIFF/LIST chunks, the final dataptr
1021 * is after the chunkid. If we were just looking for the chunk
1022 * it is after the cksize. So add 4 in RIFF/LIST case.
1024 if (uFlags
& (MMIO_FINDLIST
|MMIO_FINDRIFF
))
1025 lpck
->dwDataOffset
+=sizeof(DWORD
);
1027 /* FIXME: unverified, does it do this? */
1028 if (mmioRead(hmmio
, (LPSTR
)lpck
, 3 * sizeof(DWORD
)) < 3 * sizeof(DWORD
)) {
1029 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
1030 WARN("return ChunkNotFound 2nd\n");
1031 return MMIOERR_CHUNKNOTFOUND
;
1033 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
1035 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1036 lpck
->dwDataOffset
+= sizeof(DWORD
);
1038 mmioSeek(hmmio
, lpck
->dwDataOffset
, SEEK_SET
);
1039 memcpy(ckid
,&(lpck
->ckid
),4);
1040 TRACE("lpck->ckid=%s lpck->cksize=%ld !\n", ckid
, lpck
->cksize
);
1041 memcpy(fcc
,&(lpck
->fccType
),4);
1042 TRACE("lpck->fccType=%08lX (%s)!\n", lpck
->fccType
,searchcki
.fccType
?fcc
:"");
1046 /**************************************************************************
1047 * mmioAscend [WINMM.113]
1049 UINT WINAPI
mmioAscend(HMMIO hmmio
, MMCKINFO
* lpck
, UINT uFlags
)
1051 TRACE("(%04X, %p, %04X);\n",
1052 hmmio
, lpck
, uFlags
);
1053 if (lpck
->dwFlags
&MMIO_DIRTY
) {
1054 DWORD dwOldPos
, dwNewSize
, dwSizePos
;
1056 TRACE("chunk is marked MMIO_DIRTY, correcting chunk size\n");
1057 dwOldPos
= mmioSeek(hmmio
, 0, SEEK_CUR
);
1058 TRACE("dwOldPos=%ld\n", dwOldPos
);
1059 dwNewSize
= dwOldPos
- lpck
->dwDataOffset
;
1060 if (dwNewSize
!= lpck
->cksize
) {
1061 TRACE("dwNewSize=%ld\n", dwNewSize
);
1062 lpck
->cksize
= dwNewSize
;
1064 dwSizePos
= lpck
->dwDataOffset
- sizeof(DWORD
);
1065 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1066 dwSizePos
-= sizeof(DWORD
);
1067 TRACE("dwSizePos=%ld\n", dwSizePos
);
1069 mmioSeek(hmmio
, dwSizePos
, SEEK_SET
);
1070 mmioWrite(hmmio
, (LPSTR
)&dwNewSize
, sizeof(DWORD
));
1073 mmioSeek(hmmio
,lpck
->dwDataOffset
+lpck
->cksize
,SEEK_SET
);
1078 /**************************************************************************
1079 * mmioAscend [MMSYSTEM.1224]
1081 UINT16 WINAPI
mmioAscend16(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
1083 return mmioAscend(hmmio
,lpck
,uFlags
);
1086 /**************************************************************************
1087 * mmioCreateChunk [MMSYSTEM.1225]
1089 UINT16 WINAPI
mmioCreateChunk16(HMMIO16 hmmio
, MMCKINFO
* lpck
, UINT16 uFlags
)
1094 TRACE("(%04X, %p, %04X);\n",
1095 hmmio
, lpck
, uFlags
);
1097 dwOldPos
= mmioSeek(hmmio
, 0, SEEK_CUR
);
1098 TRACE("dwOldPos=%ld\n", dwOldPos
);
1100 if (uFlags
== MMIO_CREATELIST
)
1101 lpck
->ckid
= FOURCC_LIST
;
1102 else if (uFlags
== MMIO_CREATERIFF
)
1103 lpck
->ckid
= FOURCC_RIFF
;
1105 TRACE("ckid=%08lX\n", lpck
->ckid
);
1107 lpck
->dwDataOffset
= dwOldPos
+ 2 * sizeof(DWORD
);
1108 if (lpck
->ckid
== FOURCC_RIFF
|| lpck
->ckid
== FOURCC_LIST
)
1109 lpck
->dwDataOffset
+= sizeof(DWORD
);
1110 lpck
->dwFlags
= MMIO_DIRTY
;
1112 ix
= mmioWrite(hmmio
, (LPSTR
)lpck
, lpck
->dwDataOffset
- dwOldPos
);
1113 TRACE("after mmioWrite ix = %ld req = %ld, errno = %d\n",ix
,lpck
->dwDataOffset
- dwOldPos
,errno
);
1114 if (ix
< lpck
->dwDataOffset
- dwOldPos
) {
1116 mmioSeek(hmmio
, dwOldPos
, SEEK_SET
);
1117 WARN("return CannotWrite\n");
1118 return MMIOERR_CANNOTWRITE
;
1124 /**************************************************************************
1125 * mmioCreateChunk [WINMM.115]
1127 UINT WINAPI
mmioCreateChunk(HMMIO hmmio
, MMCKINFO
* lpck
, UINT uFlags
)
1129 return mmioCreateChunk16(hmmio
, lpck
, uFlags
);
1132 /**************************************************************************
1133 * mmioRename [MMSYSTEM.1226]
1135 UINT16 WINAPI
mmioRename16(LPCSTR szFileName
, LPCSTR szNewFileName
,
1136 MMIOINFO16
* lpmmioinfo
, DWORD dwRenameFlags
)
1139 LPMMIOINFO16 lpmminfo
;
1142 TRACE("('%s', '%s', %p, %08lX);\n",
1143 szFileName
, szNewFileName
, lpmmioinfo
, dwRenameFlags
);
1145 hmmio
= GlobalAlloc16(GHND
, sizeof(MMIOINFO16
));
1146 lpmminfo
= (LPMMIOINFO16
) GlobalLock16(hmmio
);
1149 memcpy(lpmminfo
, lpmmioinfo
, sizeof(MMIOINFO16
));
1151 /* assume DOS file if not otherwise specified */
1152 if (lpmminfo
->fccIOProc
== 0 && lpmminfo
->pIOProc
== NULL
) {
1154 lpmminfo
->fccIOProc
= mmioFOURCC('D', 'O', 'S', ' ');
1155 lpmminfo
->pIOProc
= (LPMMIOPROC16
) mmioDosIOProc
;
1158 /* if just the four character code is present, look up IO proc */
1159 else if (lpmminfo
->pIOProc
== NULL
) {
1161 lpmminfo
->pIOProc
= mmioInstallIOProc16(lpmminfo
->fccIOProc
, NULL
, MMIO_FINDPROC
);
1164 /* (if IO proc specified, use it and specified four character code) */
1166 result
= (UINT16
) mmioSendMessage(hmmio
, MMIOM_RENAME
, (LPARAM
) szFileName
, (LPARAM
) szNewFileName
);
1168 GlobalUnlock16(hmmio
);
1169 GlobalFree16(hmmio
);
1174 /**************************************************************************
1175 * mmioRenameA [WINMM.125]
1177 UINT WINAPI
mmioRenameA(LPCSTR szFileName
, LPCSTR szNewFileName
,
1178 MMIOINFO
* lpmmioinfo
, DWORD dwRenameFlags
)
1180 FIXME("This may fail\n");
1181 return mmioRename16(szFileName
, szNewFileName
, (MMIOINFO16
*)lpmmioinfo
, dwRenameFlags
);
1184 /**************************************************************************
1185 * mmioRenameW [WINMM.126]
1187 UINT WINAPI
mmioRenameW(LPCWSTR szFileName
, LPCWSTR szNewFileName
,
1188 MMIOINFO
* lpmmioinfo
, DWORD dwRenameFlags
)
1190 LPSTR szFn
= HEAP_strdupWtoA(GetProcessHeap(), 0, szFileName
);
1191 LPSTR sznFn
= HEAP_strdupWtoA(GetProcessHeap(), 0, szNewFileName
);
1192 UINT ret
= mmioRenameA(szFn
, sznFn
, lpmmioinfo
, dwRenameFlags
);
1194 HeapFree(GetProcessHeap(),0,szFn
);
1195 HeapFree(GetProcessHeap(),0,sznFn
);