Cosmetic fixes.
[wine] / multimedia / mmio.c
1 /*
2  * MMIO functions
3  *
4  * Copyright 1998 Andrew Taylor
5  * Copyright 1998 Ove Kåven
6  *
7  */
8
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <errno.h>
13 #include "windef.h"
14 #include "wine/winbase16.h"
15 #include "heap.h"
16 #include "file.h"
17 #include "mmsystem.h"
18 #include "debug.h"
19 #include "xmalloc.h"
20
21 /**************************************************************************
22  *               mmioDosIOProc           [internal]
23  */
24 static LRESULT mmioDosIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lParam1, LPARAM lParam2) {
25         TRACE(mmio, "(%p, %X, %ld, %ld);\n", lpmmioinfo, uMessage, lParam1, lParam2);
26
27         switch (uMessage) {
28
29                 case MMIOM_OPEN: {
30                         /* Parameters:
31                          * lParam1 = szFileName parameter from mmioOpen
32                          * lParam2 = reserved (we use it for 16-bitness)
33                          * Returns: zero on success, error code on error
34                          * NOTE: lDiskOffset automatically set to zero
35                          */
36
37                         OFSTRUCT ofs;
38                         LPSTR szFileName = (LPSTR) lParam1;
39
40                         if (lpmmioinfo->dwFlags & MMIO_GETTEMP) {
41                                 FIXME(mmio, "MMIO_GETTEMP not implemented\n");
42                                 return MMIOERR_CANNOTOPEN;
43                         }
44
45                         /* if filename NULL, assume open file handle in adwInfo[0] */
46                         if (!szFileName) {
47                                 if (lParam2) lpmmioinfo->adwInfo[0] =
48                                         FILE_GetHandle(lpmmioinfo->adwInfo[0]);
49                                 return 0;
50                         }
51
52                         lpmmioinfo->adwInfo[0] =
53                                 (DWORD) OpenFile(szFileName, &ofs, lpmmioinfo->dwFlags);
54                         if (lpmmioinfo->adwInfo[0] == -1)
55                                 return MMIOERR_CANNOTOPEN;
56
57                         return 0;
58                 }
59
60                 case MMIOM_CLOSE: {
61                         /* Parameters:
62                          * lParam1 = wFlags parameter from mmioClose
63                          * lParam2 = unused
64                          * Returns: zero on success, error code on error
65                          */
66
67                         UINT16 uFlags = (UINT16) lParam1;
68
69                         if (uFlags & MMIO_FHOPEN)
70                                 return 0;
71
72                         _lclose((HFILE)lpmmioinfo->adwInfo[0]);
73                         return 0;
74
75                 }
76
77                 case MMIOM_READ: {
78                         /* Parameters:
79                          * lParam1 = huge pointer to read buffer
80                          * lParam2 = number of bytes to read
81                          * Returns: number of bytes read, 0 for EOF, -1 for error (error code
82                          *         in wErrorRet)
83                          * NOTE: lDiskOffset should be updated
84                          */
85
86                         HPSTR pch = (HPSTR) lParam1;
87                         LONG cch = (LONG) lParam2;
88                         LONG count;
89
90                         count = _lread((HFILE)lpmmioinfo->adwInfo[0], pch, cch);
91                         if (count != -1)
92                                 lpmmioinfo->lDiskOffset += count;
93
94                         return count;
95                 }
96
97                 case MMIOM_WRITE:
98                 case MMIOM_WRITEFLUSH: { 
99                         /* no internal buffering, so WRITEFLUSH handled same as WRITE */
100
101                         /* Parameters:
102                          * lParam1 = huge pointer to write buffer
103                          * lParam2 = number of bytes to write
104                          * Returns: number of bytes written, -1 for error (error code in
105                          *              wErrorRet)
106                          * NOTE: lDiskOffset should be updated
107                          */
108
109                         HPSTR pch = (HPSTR) lParam1;
110                         LONG cch = (LONG) lParam2;
111                         LONG count;
112
113                         count = _hwrite((HFILE)lpmmioinfo->adwInfo[0], pch, cch);
114                         if (count != -1)
115                                 lpmmioinfo->lDiskOffset += count;
116
117                         return count;
118                 }
119
120                 case MMIOM_SEEK: {
121             /* Parameters:
122              * lParam1 = new position
123              * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
124              * Returns: new file postion, -1 on error
125              * NOTE: lDiskOffset should be updated
126              */
127
128             LONG Offset = (LONG) lParam1; 
129             LONG Whence = (LONG) lParam2; 
130             LONG pos;
131
132             pos = _llseek((HFILE)lpmmioinfo->adwInfo[0], Offset, Whence);
133             if (pos != -1)
134                 lpmmioinfo->lDiskOffset = pos;
135
136             return pos;
137                 }
138                   
139                 case MMIOM_RENAME: {
140             /* Parameters:
141              * lParam1 = old name
142              * lParam2 = new name
143              * Returns: zero on success, non-zero on failure
144              */
145
146             FIXME(mmio, "MMIOM_RENAME unimplemented\n");
147             return MMIOERR_FILENOTFOUND;
148                 }
149
150                 default:
151                         FIXME(mmio, "unexpected message %u\n", uMessage);
152                         return 0;
153         }
154         
155         return 0;
156 }
157
158 /**************************************************************************
159 *               mmioMemIOProc           [internal]
160 */
161 static LRESULT mmioMemIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lParam1, LPARAM lParam2) {
162         TRACE(mmio,"(%p,0x%04x,0x%08lx,0x%08lx)\n",lpmmioinfo,uMessage,lParam1,lParam2);
163         switch (uMessage) {
164
165                 case MMIOM_OPEN: {
166                         /* Parameters:
167                          * lParam1 = filename (must be NULL)
168                          * lParam2 = reserved (we use it for 16-bitness)
169                          * Returns: zero on success, error code on error
170                          * NOTE: lDiskOffset automatically set to zero
171                          */
172
173                         if (!(lpmmioinfo->dwFlags & MMIO_CREATE))
174                                 lpmmioinfo->pchEndRead = lpmmioinfo->pchEndWrite;
175
176                         return 0;
177                 }
178
179                 case MMIOM_CLOSE: {
180                         /* Parameters:
181                          * lParam1 = wFlags parameter from mmioClose
182                          * lParam2 = unused
183                          * Returns: zero on success, error code on error
184                          */
185
186                         return 0;
187
188                 }
189
190                 case MMIOM_READ: {
191                         /* Parameters:
192                          * lParam1 = huge pointer to read buffer
193                          * lParam2 = number of bytes to read
194                          * Returns: number of bytes read, 0 for EOF, -1 for error (error code
195                          *         in wErrorRet)
196                          * NOTE: lDiskOffset should be updated
197                          */
198
199                         /* HPSTR pch = (HPSTR) lParam1; */
200                         /* LONG cch = (LONG) lParam2; */
201
202                         FIXME(mmio,"MMIOM_READ on memory files should not occur, buffer may be lost!\n");
203                         return 0;
204                 }
205
206                 case MMIOM_WRITE:
207                 case MMIOM_WRITEFLUSH: { 
208                         /* no internal buffering, so WRITEFLUSH handled same as WRITE */
209
210                         /* Parameters:
211                          * lParam1 = huge pointer to write buffer
212                          * lParam2 = number of bytes to write
213                          * Returns: number of bytes written, -1 for error (error code in
214                          *              wErrorRet)
215                          * NOTE: lDiskOffset should be updated
216                          */
217
218                         /* HPSTR pch = (HPSTR) lParam1; */
219                         /* LONG cch = (LONG) lParam2; */
220
221                         FIXME(mmio,"MMIOM_WRITE on memory files should not occur, buffer may be lost!\n");
222                         return 0;
223                 }
224
225                 case MMIOM_SEEK: {
226                         /* Parameters:
227                          * lParam1 = new position
228                          * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
229                          * Returns: new file postion, -1 on error
230                          * NOTE: lDiskOffset should be updated
231                          */
232
233                         /* LONG Offset = (LONG) lParam1; */
234                         /* LONG Whence = (LONG) lParam2; */
235
236                         FIXME(mmio,"MMIOM_SEEK on memory files should not occur, buffer may be lost!\n");
237                         return -1;
238                 }
239                   
240                 default:
241                         FIXME(mmio, "unexpected message %u\n", uMessage);
242                         return 0;
243         }
244         
245         return 0;
246 }
247
248 /**************************************************************************
249  *              MMIO_Open               [internal]
250  */
251 static HMMIO16 MMIO_Open(LPSTR szFileName, MMIOINFO16 * lpmmioinfo,
252                         DWORD dwOpenFlags, int use16)
253 {
254         LPMMIOINFO16 lpmminfo;
255         HMMIO16 hmmio;
256         UINT16 result;
257
258         TRACE(mmio, "('%s', %p, %08lX);\n", szFileName, lpmmioinfo, dwOpenFlags);
259
260         hmmio = GlobalAlloc16(GHND, sizeof(MMIOINFO16));
261         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
262         if (lpmminfo == NULL)
263                 return 0;
264         memset(lpmminfo, 0, sizeof(MMIOINFO16));
265
266         /* assume DOS file if not otherwise specified */
267         if (!lpmmioinfo ||
268                 (lpmmioinfo->fccIOProc == 0 && lpmmioinfo->pIOProc == NULL)) {
269
270                 lpmminfo->fccIOProc = FOURCC_DOS;
271                 lpmminfo->pIOProc = (LPMMIOPROC16) mmioDosIOProc;
272         }
273         /* if just the four character code is present, look up IO proc */
274         else if (lpmmioinfo->pIOProc == NULL) {
275
276                 lpmminfo->fccIOProc = lpmmioinfo->fccIOProc;
277                 lpmminfo->pIOProc = mmioInstallIOProc16(lpmmioinfo->fccIOProc, NULL, MMIO_FINDPROC);
278
279         } 
280         /* if IO proc specified, use it and specified four character code */
281         else {
282
283                 lpmminfo->fccIOProc = lpmmioinfo->fccIOProc;
284                 lpmminfo->pIOProc = lpmmioinfo->pIOProc;
285         }
286
287         if (dwOpenFlags & MMIO_ALLOCBUF) {
288                 if ((result = mmioSetBuffer16(hmmio, NULL, MMIO_DEFAULTBUFFER, 0))) {
289                         if (lpmmioinfo)
290                                 lpmmioinfo->wErrorRet = result;
291                         return 0;
292                 }
293         } else
294         if (lpmminfo->fccIOProc == FOURCC_MEM) {
295                 if ((result = mmioSetBuffer16(hmmio, lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer, 0))) {
296                         if (lpmmioinfo)
297                                 lpmmioinfo->wErrorRet = result;
298                         return 0;
299                 }
300         }
301
302         lpmminfo->dwFlags = dwOpenFlags;
303         lpmminfo->hmmio = hmmio;
304
305         /* call IO proc to actually open file */
306         result = (UINT16) mmioSendMessage(hmmio, MMIOM_OPEN, (LPARAM) szFileName, (LPARAM) use16);
307
308         GlobalUnlock16(hmmio);
309
310         if (result != 0) {
311                 GlobalFree16(hmmio);
312                 return 0;
313         }
314
315         return hmmio;
316 }
317
318 /**************************************************************************
319  *                              mmioOpenW                       [WINMM.123]
320  */
321 HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO * lpmmioinfo,
322                           DWORD dwOpenFlags)
323 {
324         LPSTR   szFn = HEAP_strdupWtoA(GetProcessHeap(),0,szFileName);
325         HMMIO ret = MMIO_Open(szFn,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags,FALSE);
326
327         HeapFree(GetProcessHeap(),0,szFn);
328         return ret;
329 }
330
331 /**************************************************************************
332  *                              mmioOpenA                       [WINMM.122]
333  */
334 HMMIO WINAPI mmioOpenA(LPSTR szFileName, MMIOINFO * lpmmioinfo,
335                           DWORD dwOpenFlags)
336 {
337         return MMIO_Open(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags,FALSE);
338 }
339
340 /**************************************************************************
341  *                              mmioOpen                [MMSYSTEM.1210]
342  */
343 HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo,
344                           DWORD dwOpenFlags)
345 {
346         return MMIO_Open(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags,TRUE);
347 }
348
349     
350 /**************************************************************************
351  *                              mmioClose               [WINMM.114]
352  */
353 MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
354 {
355         LPMMIOINFO16 lpmminfo;
356         MMRESULT result;
357
358         TRACE(mmio, "(%04X, %04X);\n", hmmio, uFlags);
359
360         lpmminfo = (LPMMIOINFO16) GlobalLock16(hmmio);
361         if (lpmminfo == NULL)
362                 return 0;
363
364         /* flush the file - if error reported, ignore */
365         if (mmioFlush(hmmio, MMIO_EMPTYBUF) != 0)
366                 lpmminfo->dwFlags &= ~MMIO_DIRTY;
367
368         result = mmioSendMessage(hmmio,MMIOM_CLOSE,(LPARAM)uFlags,(LPARAM)0);
369
370         mmioSetBuffer16(hmmio, NULL, 0, 0);
371
372         GlobalUnlock16(hmmio);
373         GlobalFree16(hmmio);
374
375         return result;
376 }
377
378
379 /**************************************************************************
380  *                              mmioClose               [MMSYSTEM.1211]
381  */
382 MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags)
383 {
384         return mmioClose(hmmio,uFlags);
385 }
386
387
388
389 /**************************************************************************
390  *                              mmioRead                [WINMM.124]
391  */
392 LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
393 {
394         LONG count;
395         LPMMIOINFO16 lpmminfo;
396
397         TRACE(mmio, "(%04X, %p, %ld);\n", hmmio, pch, cch);
398
399         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
400         if (lpmminfo == NULL)
401                 return -1;
402
403         if (lpmminfo->pchNext != lpmminfo->pchEndRead) {
404                 count = lpmminfo->pchEndRead - lpmminfo->pchNext;
405                 if (count > cch || count < 0) count = cch;
406                 memcpy(pch, lpmminfo->pchNext, count);
407                 lpmminfo->pchNext += count;
408                 pch += count;
409                 cch -= count;
410         } else
411                 count = 0;
412
413         if (cch&&(lpmminfo->fccIOProc!=FOURCC_MEM)) {
414                 if (lpmminfo->cchBuffer) {
415                         mmioFlush(hmmio, MMIO_EMPTYBUF);
416
417                         while (cch) {
418                                 LONG size;
419                                 lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
420                                 lpmminfo->pchNext = lpmminfo->pchBuffer;
421                                 lpmminfo->pchEndRead = lpmminfo->pchBuffer;
422                                 size = mmioSendMessage(hmmio, MMIOM_READ,
423                                                 (LPARAM) lpmminfo->pchBuffer,
424                                                 (LPARAM) lpmminfo->cchBuffer);
425                                 if (size<=0) break;
426                                 lpmminfo->pchEndRead = lpmminfo->pchBuffer + size;
427                                 if (size > cch) size = cch;
428                                 memcpy(pch, lpmminfo->pchNext, size);
429                                 lpmminfo->pchNext += size;
430                                 pch += size;
431                                 cch -= size;
432                                 count += size;
433                         }
434                 } else {
435                         count += mmioSendMessage(hmmio, MMIOM_READ, (LPARAM) pch, (LPARAM) cch);
436                         if (count>0) lpmminfo->lBufOffset += count;
437                 }
438         }
439
440         GlobalUnlock16(hmmio);
441         TRACE(mmio, "count=%ld\n", count);
442         return count;
443 }
444
445 /**************************************************************************
446  *                              mmioRead                [MMSYSTEM.1212]
447  */
448 LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch)
449 {
450         return mmioRead(hmmio,pch,cch);
451 }
452
453 /**************************************************************************
454  *                              mmioWrite               [WINMM.133]
455  */
456 LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
457 {
458         LONG count;
459         LPMMIOINFO16 lpmminfo;
460
461         TRACE(mmio, "(%04X, %p, %ld);\n", hmmio, pch, cch);
462
463         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
464         if (lpmminfo == NULL)
465                 return -1;
466
467         if (lpmminfo->cchBuffer) {
468                 count = 0;
469                 while (cch) {
470                         if (lpmminfo->pchNext != lpmminfo->pchEndWrite) {
471                                 count = lpmminfo->pchEndWrite - lpmminfo->pchNext;
472                                 if (count > cch || count < 0) count = cch;
473                                 memcpy(lpmminfo->pchNext, pch, count);
474                                 lpmminfo->pchNext += count;
475                                 pch += count;
476                                 cch -= count;
477                                 lpmminfo->dwFlags |= MMIO_DIRTY;
478                         } else
479                         if (lpmminfo->fccIOProc==FOURCC_MEM) {
480                                 if (lpmminfo->adwInfo[0]) {
481                                         /* from where would we get the memory handle? */
482                                         FIXME(mmio, "memory file expansion not implemented!\n");
483                                 } else break;
484                         }
485
486                         if (lpmminfo->pchNext == lpmminfo->pchEndWrite
487                                 && mmioFlush(hmmio, MMIO_EMPTYBUF)) break;
488                 }
489         } else {
490                 count = mmioSendMessage(hmmio, MMIOM_WRITE, (LPARAM) pch, (LPARAM) cch);
491                 lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
492         }
493
494         GlobalUnlock16(hmmio);
495         TRACE(mmio, "count=%ld\n", count);
496         return count;
497 }
498
499 /**************************************************************************
500  *                              mmioWrite               [MMSYSTEM.1213]
501  */
502 LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
503 {
504         return mmioWrite(hmmio,pch,cch);
505 }
506
507 /**************************************************************************
508  *                              mmioSeek                [MMSYSTEM.1214]
509  */
510 LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
511 {
512         int offset;
513         LPMMIOINFO16 lpmminfo;
514
515         TRACE(mmio, "(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
516
517         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
518         if (lpmminfo == NULL)
519                 return -1;
520
521         offset = (iOrigin==SEEK_SET)?(lOffset - lpmminfo->lBufOffset):
522                  (iOrigin==SEEK_CUR)?(lOffset +
523                  (lpmminfo->pchNext - lpmminfo->pchBuffer)):-1;
524
525         if ((lpmminfo->cchBuffer<0)||
526             ((offset>=0)&&(offset<=(lpmminfo->pchEndRead-lpmminfo->pchBuffer)))) {
527                 lpmminfo->pchNext = lpmminfo->pchBuffer + offset;
528                 GlobalUnlock16(hmmio);
529                 return lpmminfo->lBufOffset + offset;
530         }
531
532         if ((lpmminfo->fccIOProc==FOURCC_MEM)||mmioFlush(hmmio, MMIO_EMPTYBUF)) {
533                 GlobalUnlock16(hmmio);
534                 return -1;
535         }
536
537         offset = mmioSendMessage(hmmio, MMIOM_SEEK, (LPARAM) lOffset, (LPARAM) iOrigin);
538         lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
539
540         GlobalUnlock16(hmmio);
541         return offset;
542 }
543
544 /**************************************************************************
545  *                              mmioSeek                [MMSYSTEM.1214]
546  */
547 LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
548 {
549         return mmioSeek(hmmio,lOffset,iOrigin);
550 }
551
552 /**************************************************************************
553  *                              mmioGetInfo             [MMSYSTEM.1215]
554  */
555 UINT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
556 {
557         LPMMIOINFO16    lpmminfo;
558         TRACE(mmio, "mmioGetInfo\n");
559         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
560         if (lpmminfo == NULL) return 0;
561         memcpy(lpmmioinfo, lpmminfo, sizeof(MMIOINFO16));
562         GlobalUnlock16(hmmio);
563         return 0;
564 }
565
566 /**************************************************************************
567  *                              mmioGetInfo             [WINMM.118]
568  */
569 UINT WINAPI mmioGetInfo(HMMIO hmmio, MMIOINFO*lpmmioinfo, UINT uFlags)
570 {
571         MMIOINFO16      mmioinfo;
572         LPMMIOINFO16    lpmminfo=&mmioinfo;
573         UINT16          ret;
574
575         TRACE(mmio, "(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
576         ret = mmioGetInfo16(hmmio,&mmioinfo,uFlags);
577         if (!ret)
578                 return 0;
579         lpmmioinfo->dwFlags     = lpmminfo->dwFlags;
580         lpmmioinfo->fccIOProc   = lpmminfo->fccIOProc;
581         lpmmioinfo->pIOProc     = (LPMMIOPROC)lpmminfo->pIOProc;
582         lpmmioinfo->wErrorRet   = lpmminfo->wErrorRet;
583         lpmmioinfo->htask       = lpmminfo->htask;
584         lpmmioinfo->cchBuffer   = lpmminfo->cchBuffer;
585         lpmmioinfo->pchBuffer   = lpmminfo->pchBuffer;
586         lpmmioinfo->pchNext     = lpmminfo->pchNext;
587         lpmmioinfo->pchEndRead  = lpmminfo->pchEndRead;
588         lpmmioinfo->pchEndWrite = lpmminfo->pchEndWrite;
589         lpmmioinfo->lBufOffset  = lpmminfo->lBufOffset;
590         lpmmioinfo->lDiskOffset = lpmminfo->lDiskOffset;
591         memcpy(lpmmioinfo->adwInfo,lpmminfo->adwInfo,sizeof(lpmminfo->adwInfo));
592         lpmmioinfo->dwReserved1 = lpmminfo->dwReserved1;
593         lpmmioinfo->dwReserved2 = lpmminfo->dwReserved2;
594         lpmmioinfo->hmmio       = lpmminfo->hmmio;
595         return 0;
596 }
597
598 /**************************************************************************
599  *                              mmioSetInfo             [MMSYSTEM.1216]
600  */
601 UINT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
602 {
603         LPMMIOINFO16    lpmminfo;
604         TRACE(mmio, "mmioSetInfo\n");
605         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
606         if (lpmminfo == NULL) return 0;
607         lpmminfo->pchNext       = lpmmioinfo->pchNext;
608         lpmminfo->pchEndRead    = lpmmioinfo->pchEndRead;
609         GlobalUnlock16(hmmio);
610         return 0;
611 }
612
613 /**************************************************************************
614  *                              mmioSetInfo             [WINMM.130]
615  */
616 UINT WINAPI mmioSetInfo(HMMIO hmmio, const MMIOINFO * lpmmioinfo, UINT uFlags)
617 {
618         LPMMIOINFO16    lpmminfo;
619         TRACE(mmio, "mmioSetInfo\n");
620         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
621         if (lpmminfo == NULL) return 0;
622         lpmminfo->pchNext       = lpmmioinfo->pchNext;
623         lpmminfo->pchEndRead    = lpmmioinfo->pchEndRead;
624         GlobalUnlock16(hmmio);
625         return 0;
626 }
627
628 /**************************************************************************
629 *                               mmioSetBuffer           [WINMM.129]
630 */
631 UINT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, 
632                                                                                 LONG cchBuffer, UINT uFlags)
633 {
634         LPMMIOINFO16    lpmminfo;
635
636         if (mmioFlush(hmmio, MMIO_EMPTYBUF) != 0)
637                 return MMIOERR_CANNOTWRITE;
638
639         TRACE(mmio, "(hmmio=%04x, pchBuf=%p, cchBuf=%ld, uFlags=%#08x)\n",
640               hmmio, pchBuffer, cchBuffer, uFlags);
641
642         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
643         if (lpmminfo == NULL) return 0;
644         if ((!cchBuffer || pchBuffer) && lpmminfo->dwFlags&MMIO_ALLOCBUF) {
645                 GlobalUnlock16(lpmminfo->dwReserved1);
646                 GlobalFree16(lpmminfo->dwReserved1);
647                 lpmminfo->dwFlags &= ~MMIO_ALLOCBUF;
648         }
649         if (pchBuffer) {
650                 lpmminfo->pchBuffer = pchBuffer;
651         } else if (lpmminfo->dwFlags&MMIO_ALLOCBUF) {
652                 HGLOBAL16 hNewBuf;
653                 GlobalUnlock16(lpmminfo->dwReserved1);
654                 hNewBuf = GlobalReAlloc16(lpmminfo->dwReserved1, cchBuffer, 0);
655                 if (!hNewBuf) {
656                         /* FIXME: this assumes the memory block didn't move */
657                         GlobalLock16(lpmminfo->dwReserved1);
658                         GlobalUnlock16(hmmio);
659                         return MMIOERR_OUTOFMEMORY;
660                 }
661                 lpmminfo->dwReserved1 = hNewBuf;
662                 lpmminfo->pchBuffer = GlobalLock16(hNewBuf);
663         } else if (cchBuffer) {
664                 HGLOBAL16 hNewBuf = GlobalAlloc16(GMEM_MOVEABLE, cchBuffer);
665                 if (!hNewBuf) {
666                         GlobalUnlock16(hmmio);
667                         return MMIOERR_OUTOFMEMORY;
668                 }
669                 lpmminfo->dwReserved1 = hNewBuf;
670                 lpmminfo->pchBuffer = GlobalLock16(hNewBuf);
671                 lpmminfo->dwFlags |= MMIO_ALLOCBUF;
672         } else
673                 lpmminfo->pchBuffer = NULL;
674         lpmminfo->cchBuffer = cchBuffer;
675         lpmminfo->pchNext = lpmminfo->pchBuffer;
676         lpmminfo->pchEndRead = lpmminfo->pchBuffer;
677         lpmminfo->pchEndWrite = lpmminfo->pchBuffer + cchBuffer;
678         lpmminfo->lBufOffset = 0;
679
680         GlobalUnlock16(hmmio);
681         return (UINT16) 0;
682 }
683
684 /**************************************************************************
685 *                               mmioSetBuffer           [MMSYSTEM.1217]
686 */
687 UINT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, LPSTR pchBuffer, 
688                                                                                 LONG cchBuffer, UINT16 uFlags)
689 {
690         return mmioSetBuffer(hmmio, pchBuffer, cchBuffer, uFlags);
691 }
692
693 /**************************************************************************
694  *                              mmioFlush               [WINMM.117]
695  */
696 UINT WINAPI mmioFlush(HMMIO hmmio, UINT uFlags)
697 {
698         LPMMIOINFO16    lpmminfo;
699         TRACE(mmio, "(%04X, %04X)\n", hmmio, uFlags);
700         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
701         if (lpmminfo == NULL) return 0;
702
703         if ((!lpmminfo->cchBuffer)||(lpmminfo->fccIOProc==FOURCC_MEM)) {
704                 GlobalUnlock16(hmmio);
705                 return 0;
706         }
707         /* not quite sure what to do here, but I'll guess */
708         if (lpmminfo->dwFlags & MMIO_DIRTY) {
709                 mmioSendMessage(hmmio, MMIOM_SEEK,
710                         (LPARAM) lpmminfo->lBufOffset,
711                         (LPARAM) SEEK_SET);
712                 mmioSendMessage(hmmio, MMIOM_WRITE,
713                         (LPARAM) lpmminfo->pchBuffer,
714                         (LPARAM) (lpmminfo->pchNext - lpmminfo->pchBuffer) );
715                 lpmminfo->dwFlags &= ~MMIO_DIRTY;
716         }
717         if (uFlags & MMIO_EMPTYBUF) {
718                 /* seems Windows doesn't do any seeking here, hopefully this
719                    won't matter, otherwise a slight rewrite is necessary */
720                 mmioSendMessage(hmmio, MMIOM_SEEK,
721                         (LPARAM) (lpmminfo->lBufOffset +
722                                   (lpmminfo->pchNext - lpmminfo->pchBuffer)),
723                         (LPARAM) SEEK_SET);
724                 lpmminfo->pchNext = lpmminfo->pchBuffer;
725                 lpmminfo->pchEndRead = lpmminfo->pchBuffer;
726                 lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
727         }
728
729         GlobalUnlock16(hmmio);
730         return 0;
731 }
732
733 /**************************************************************************
734  *                              mmioFlush               [MMSYSTEM.1218]
735  */
736 UINT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags)
737 {
738         return mmioFlush(hmmio,uFlags);
739 }
740
741 /**************************************************************************
742  *                              mmioAdvance             [MMSYSTEM.1219]
743  */
744 UINT WINAPI mmioAdvance(HMMIO hmmio,MMIOINFO*lpmmioinfo,UINT uFlags)
745 {
746         LPMMIOINFO16    lpmminfo;
747         TRACE(mmio, "mmioAdvance\n");
748         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
749         if (lpmminfo == NULL) return 0;
750         if (!lpmminfo->cchBuffer) {
751                 GlobalUnlock16(hmmio);
752                 return MMIOERR_UNBUFFERED;
753         }
754         lpmminfo->pchNext = lpmmioinfo->pchNext;
755         if (mmioFlush(hmmio, MMIO_EMPTYBUF)) {
756                 GlobalUnlock16(hmmio);
757                 return MMIOERR_CANNOTWRITE;
758         }
759         if (uFlags == MMIO_READ)
760                 lpmmioinfo->pchEndRead = lpmmioinfo->pchBuffer +
761                     mmioSendMessage(hmmio, MMIOM_READ,
762                         (LPARAM) lpmmioinfo->pchBuffer,
763                         (LPARAM) lpmmioinfo->cchBuffer);
764 #if 0   /* mmioFlush already did the writing */
765         if (uFlags == MMIO_WRITE)
766                     mmioSendMessage(hmmio, MMIOM_WRITE,
767                         (LPARAM) lpmmioinfo->pchBuffer,
768                         (LPARAM) lpmmioinfo->cchBuffer);
769 #endif
770         lpmmioinfo->pchNext = lpmmioinfo->pchBuffer;
771         GlobalUnlock16(hmmio);
772         return 0;
773 }
774
775 /**************************************************************************
776  *                              mmioAdvance             [MMSYSTEM.1219]
777  */
778 UINT16 WINAPI mmioAdvance16(HMMIO16 hmmio,MMIOINFO16*lpmmioinfo,UINT16 uFlags)
779 {
780         LPMMIOINFO16    lpmminfo;
781         TRACE(mmio, "mmioAdvance\n");
782         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
783         if (lpmminfo == NULL) return 0;
784         if (!lpmminfo->cchBuffer) {
785                 GlobalUnlock16(hmmio);
786                 return MMIOERR_UNBUFFERED;
787         }
788         lpmminfo->pchNext = lpmmioinfo->pchNext;
789         if (mmioFlush(hmmio, MMIO_EMPTYBUF)) {
790                 GlobalUnlock16(hmmio);
791                 return MMIOERR_CANNOTWRITE;
792         }
793         if (uFlags == MMIO_READ)
794                 lpmmioinfo->pchEndRead = lpmmioinfo->pchBuffer +
795                     mmioSendMessage(hmmio, MMIOM_READ,
796                         (LPARAM) lpmmioinfo->pchBuffer,
797                         (LPARAM) lpmmioinfo->cchBuffer);
798 #if 0   /* mmioFlush already did the writing */
799         if (uFlags == MMIO_WRITE)
800                     mmioSendMessage(hmmio, MMIOM_WRITE,
801                         (LPARAM) lpmmioinfo->pchBuffer,
802                         (LPARAM) lpmmioinfo->cchBuffer);
803 #endif
804         lpmmioinfo->pchNext = lpmmioinfo->pchBuffer;
805         GlobalUnlock16(hmmio);
806         return 0;
807 }
808
809 /**************************************************************************
810  *                              mmioStringToFOURCCA     [WINMM.131]
811  */
812 FOURCC WINAPI mmioStringToFOURCCA(LPCSTR sz, UINT uFlags)
813 {
814         return mmioStringToFOURCC16(sz,uFlags);
815 }
816
817 /**************************************************************************
818  *                              mmioStringToFOURCCW     [WINMM.132]
819  */
820 FOURCC WINAPI mmioStringToFOURCCW(LPCWSTR sz, UINT uFlags)
821 {
822         LPSTR   szA = HEAP_strdupWtoA(GetProcessHeap(),0,sz);
823         FOURCC  ret = mmioStringToFOURCCA(szA,uFlags);
824
825         HeapFree(GetProcessHeap(),0,szA);
826         return ret;
827 }
828
829 /**************************************************************************
830  *                              mmioStringToFOURCC      [MMSYSTEM.1220]
831  */
832 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
833 {
834         return mmioFOURCC(sz[0],sz[1],sz[2],sz[3]);
835 }
836
837 /**************************************************************************
838 *                               mmioInstallIOProc16     [MMSYSTEM.1221]
839 */
840 LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, 
841                                         LPMMIOPROC16 pIOProc, DWORD dwFlags)
842 {
843         TRACE(mmio, "(%ld, %p, %08lX)\n",
844                                  fccIOProc, pIOProc, dwFlags);
845
846         if (dwFlags & MMIO_GLOBALPROC) {
847                 FIXME(mmio, " global procedures not implemented\n");
848         }
849
850         /* just handle the known procedures for now */
851         switch(dwFlags & (MMIO_INSTALLPROC|MMIO_REMOVEPROC|MMIO_FINDPROC)) {
852                 case MMIO_INSTALLPROC:
853                         return NULL;
854                 case MMIO_REMOVEPROC:
855                         return NULL;
856                 case MMIO_FINDPROC:
857                         if (fccIOProc == FOURCC_DOS)
858                                 return (LPMMIOPROC16) mmioDosIOProc;
859                         else if (fccIOProc == FOURCC_MEM)
860                                 return (LPMMIOPROC16) mmioMemIOProc;
861                         else
862                                 return NULL;
863                 default:
864                         return NULL;
865         }
866 }
867
868 /**************************************************************************
869  *                              mmioInstallIOProcA                                                                 [WINMM.120]
870  */
871 LPMMIOPROC WINAPI mmioInstallIOProcA(FOURCC fccIOProc, 
872                                          LPMMIOPROC pIOProc, DWORD dwFlags)
873 {
874         FIXME(mmio, "(%c%c%c%c,%p,0x%08lx) -- empty stub \n",
875                      (char)((fccIOProc&0xff000000)>>24),
876                      (char)((fccIOProc&0x00ff0000)>>16),
877                      (char)((fccIOProc&0x0000ff00)>> 8),
878                      (char)(fccIOProc&0x000000ff),
879                      pIOProc, dwFlags );
880         return 0;
881 }
882
883 /**************************************************************************
884 *                               mmioSendMessage         [MMSYSTEM.1222]
885 */
886 LRESULT WINAPI mmioSendMessage(HMMIO16 hmmio, UINT16 uMessage,
887                                LPARAM lParam1, LPARAM lParam2)
888 {
889         LPMMIOINFO16 lpmminfo;
890         LRESULT result;
891         const char *msg = NULL;
892
893 #ifdef DEBUG_RUNTIME
894         switch (uMessage) {
895 #define msgname(x) case x: msg = #x; break;
896                 msgname(MMIOM_OPEN);
897                 msgname(MMIOM_CLOSE);
898                 msgname(MMIOM_READ);
899                 msgname(MMIOM_WRITE);
900                 msgname(MMIOM_WRITEFLUSH);
901                 msgname(MMIOM_SEEK);
902                 msgname(MMIOM_RENAME);
903 #undef msgname
904         }
905 #endif
906
907         if (msg)
908                 TRACE(mmio, "(%04X, %s, %ld, %ld)\n",
909                                          hmmio, msg, lParam1, lParam2);
910         else
911                 TRACE(mmio, "(%04X, %u, %ld, %ld)\n",
912                                          hmmio, uMessage, lParam1, lParam2);
913         
914         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
915
916         if (lpmminfo && lpmminfo->pIOProc)
917                 result = (*lpmminfo->pIOProc)((LPSTR)lpmminfo, uMessage, lParam1, lParam2);
918         else
919                 result = MMSYSERR_INVALPARAM;
920
921         GlobalUnlock16(hmmio);
922
923         return result;
924 }
925
926 /**************************************************************************
927 *                               mmioDescend             [MMSYSTEM.1223]
928 */
929 UINT16 WINAPI mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
930                           const MMCKINFO * lpckParent, UINT16 uFlags)
931 {
932         DWORD           dwOldPos;
933         MMCKINFO        searchcki;
934         char            ckid[5],fcc[5];
935
936         TRACE(mmio,"(%04X, %p, %p, %04X);\n",hmmio,lpck,lpckParent,uFlags);
937
938         if (lpck == NULL)
939             return 0;
940         dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
941         TRACE(mmio, "dwOldPos=%ld\n", dwOldPos);
942
943         if (lpckParent != NULL) {
944                 TRACE(mmio, "seek inside parent at %ld !\n", lpckParent->dwDataOffset);
945                 dwOldPos = mmioSeek(hmmio,lpckParent->dwDataOffset,SEEK_SET);
946         }
947
948         /* The SDK docu says 'ckid' is used for all cases. Real World
949          * examples disagree -Marcus,990216. 
950          */
951
952         searchcki.fccType = 0;
953         /* find_chunk looks for 'ckid' */
954         if (uFlags & MMIO_FINDCHUNK)
955                 searchcki.ckid = lpck->ckid;
956         /* find_riff and find_list look for 'fccType' */
957         if (uFlags & MMIO_FINDLIST) {
958                 searchcki.ckid = FOURCC_LIST;
959                 searchcki.fccType = lpck->fccType;
960         }
961         if (uFlags & MMIO_FINDRIFF) {
962                 searchcki.ckid = FOURCC_RIFF;
963                 searchcki.fccType = lpck->fccType;
964         }
965         memcpy(&fcc,&(searchcki.fccType),4);fcc[4]=0;
966         memcpy(&ckid,&(searchcki.ckid),4);ckid[4]=0;
967         TRACE(mmio,"searching for %s.%s\n",ckid,searchcki.fccType?fcc:"<any>");
968
969         if (uFlags & (MMIO_FINDCHUNK|MMIO_FINDLIST|MMIO_FINDRIFF)) {
970                 while (TRUE) {
971                         LONG ix;
972
973                         ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
974                         if (ix < 2*sizeof(DWORD)) {
975                                 mmioSeek(hmmio, dwOldPos, SEEK_SET);
976                                 WARN(mmio, "return ChunkNotFound\n");
977                                 return MMIOERR_CHUNKNOTFOUND;
978                         }
979                         lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
980                         if (ix < lpck->dwDataOffset - dwOldPos) {
981                                 mmioSeek(hmmio, dwOldPos, SEEK_SET);
982                                 WARN(mmio, "return ChunkNotFound\n");
983                                 return MMIOERR_CHUNKNOTFOUND;
984                         }
985                         memcpy(ckid,&lpck->ckid,4);
986                         memcpy(fcc,&lpck->fccType,4);
987                         TRACE(mmio, "ckid=%s fcc=%s cksize=%08lX !\n",
988                                 ckid, searchcki.fccType?fcc:"<unused>",
989                                 lpck->cksize
990                         );
991                         if ((searchcki.ckid == lpck->ckid) &&
992                             (!searchcki.fccType ||
993                               (searchcki.fccType == lpck->fccType)
994                             )
995                         )
996                                 break;
997
998                         dwOldPos = lpck->dwDataOffset + lpck->cksize;
999                         mmioSeek(hmmio, dwOldPos, SEEK_SET);
1000                 }
1001                 /* If we were looking for RIFF/LIST chunks, the final dataptr
1002                  * is after the chunkid. If we were just looking for the chunk
1003                  * it is after the cksize. So add 4 in RIFF/LIST case.
1004                  */
1005                 if (uFlags & (MMIO_FINDLIST|MMIO_FINDRIFF))
1006                         lpck->dwDataOffset+=sizeof(DWORD);
1007         } else {
1008                 /* FIXME: unverified, does it do this? */
1009                 if (mmioRead(hmmio, (LPSTR)lpck, sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
1010                         mmioSeek(hmmio, dwOldPos, SEEK_SET);
1011                         WARN(mmio, "return ChunkNotFound 2nd\n");
1012                         return MMIOERR_CHUNKNOTFOUND;
1013                 }
1014                 lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
1015                 if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
1016                         lpck->dwDataOffset += sizeof(DWORD);
1017         }
1018         mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
1019         memcpy(ckid,&(lpck->ckid),4);
1020         TRACE(mmio, "lpck->ckid=%s lpck->cksize=%ld !\n", ckid, lpck->cksize);
1021         memcpy(fcc,&(lpck->fccType),4);
1022         TRACE(mmio, "lpck->fccType=%08lX (%s)!\n", lpck->fccType,searchcki.fccType?fcc:"");
1023         return 0;
1024 }
1025
1026 /**************************************************************************
1027  *                              mmioAscend              [WINMM.113]
1028  */
1029 UINT WINAPI mmioAscend(HMMIO hmmio, MMCKINFO * lpck, UINT uFlags)
1030 {
1031         TRACE(mmio, "(%04X, %p, %04X);\n", 
1032                                 hmmio, lpck, uFlags);
1033         if (lpck->dwFlags&MMIO_DIRTY) {
1034                 DWORD   dwOldPos, dwNewSize, dwSizePos;
1035
1036                 TRACE(mmio, "chunk is marked MMIO_DIRTY, correcting chunk size\n");
1037                 dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
1038                 TRACE(mmio, "dwOldPos=%ld\n", dwOldPos);
1039                 dwNewSize = dwOldPos - lpck->dwDataOffset;
1040                 if (dwNewSize != lpck->cksize) {
1041                         TRACE(mmio, "dwNewSize=%ld\n", dwNewSize);
1042                         lpck->cksize = dwNewSize;
1043
1044                         dwSizePos = lpck->dwDataOffset - sizeof(DWORD);
1045                         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
1046                                 dwSizePos -= sizeof(DWORD);
1047                         TRACE(mmio, "dwSizePos=%ld\n", dwSizePos);
1048
1049                         mmioSeek(hmmio, dwSizePos, SEEK_SET);
1050                         mmioWrite(hmmio, (LPSTR)&dwNewSize, sizeof(DWORD));
1051                 }
1052         }
1053         mmioSeek(hmmio,lpck->dwDataOffset+lpck->cksize,SEEK_SET);
1054
1055         return 0;
1056 }
1057
1058 /**************************************************************************
1059  *                              mmioAscend              [MMSYSTEM.1224]
1060  */
1061 UINT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
1062 {
1063         return mmioAscend(hmmio,lpck,uFlags);
1064 }
1065
1066 /**************************************************************************
1067  *                              mmioCreateChunk         [MMSYSTEM.1225]
1068  */
1069 UINT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
1070 {
1071         DWORD   dwOldPos;
1072         LONG ix;
1073
1074         TRACE(mmio, "(%04X, %p, %04X);\n", 
1075                                 hmmio, lpck, uFlags);
1076
1077         dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
1078         TRACE(mmio, "dwOldPos=%ld\n", dwOldPos);
1079
1080         if (uFlags == MMIO_CREATELIST)
1081                 lpck->ckid = FOURCC_LIST;
1082         else if (uFlags == MMIO_CREATERIFF)
1083                 lpck->ckid = FOURCC_RIFF;
1084
1085         TRACE(mmio, "ckid=%08lX\n", lpck->ckid);
1086
1087         lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
1088         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
1089                 lpck->dwDataOffset += sizeof(DWORD);
1090         lpck->dwFlags = MMIO_DIRTY;
1091
1092         ix = mmioWrite(hmmio, (LPSTR)lpck, lpck->dwDataOffset - dwOldPos);
1093         TRACE(mmio, "after mmioWrite ix = %ld req = %ld, errno = %d\n",ix,lpck->dwDataOffset - dwOldPos,errno);
1094         if (ix < lpck->dwDataOffset - dwOldPos) {
1095
1096                 mmioSeek(hmmio, dwOldPos, SEEK_SET);
1097                 WARN(mmio, "return CannotWrite\n");
1098                 return MMIOERR_CANNOTWRITE;
1099         }
1100
1101         return 0;
1102 }
1103
1104 /**************************************************************************
1105  *                                      mmioCreateChunk                                 [WINMM.115]
1106  */
1107 UINT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO * lpck, UINT uFlags)
1108 {
1109         return mmioCreateChunk16(hmmio, lpck, uFlags);
1110 }
1111
1112 /**************************************************************************
1113  *                              mmioRename              [MMSYSTEM.1226]
1114  */
1115 UINT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName,
1116                          MMIOINFO16 * lpmmioinfo, DWORD dwRenameFlags)
1117 {
1118         UINT16 result;
1119         LPMMIOINFO16 lpmminfo;
1120         HMMIO16 hmmio;
1121
1122         TRACE(mmio, "('%s', '%s', %p, %08lX);\n",
1123                                  szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
1124
1125         hmmio = GlobalAlloc16(GHND, sizeof(MMIOINFO16));
1126         lpmminfo = (LPMMIOINFO16) GlobalLock16(hmmio);
1127
1128         if (lpmmioinfo)
1129                 memcpy(lpmminfo, lpmmioinfo, sizeof(MMIOINFO16));
1130         
1131         /* assume DOS file if not otherwise specified */
1132         if (lpmminfo->fccIOProc == 0 && lpmminfo->pIOProc == NULL) {
1133
1134                 lpmminfo->fccIOProc = mmioFOURCC('D', 'O', 'S', ' ');
1135                 lpmminfo->pIOProc = (LPMMIOPROC16) mmioDosIOProc;
1136
1137         }
1138         /* if just the four character code is present, look up IO proc */
1139         else if (lpmminfo->pIOProc == NULL) {
1140
1141                 lpmminfo->pIOProc = mmioInstallIOProc16(lpmminfo->fccIOProc, NULL, MMIO_FINDPROC);
1142
1143         } 
1144         /* (if IO proc specified, use it and specified four character code) */
1145
1146         result = (UINT16) mmioSendMessage(hmmio, MMIOM_RENAME, (LPARAM) szFileName, (LPARAM) szNewFileName);
1147         
1148         GlobalUnlock16(hmmio);
1149         GlobalFree16(hmmio);
1150
1151         return result;
1152 }
1153
1154 /**************************************************************************
1155  *                              mmioRenameA                             [WINMM.125]
1156  */
1157 UINT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
1158                          MMIOINFO* lpmmioinfo, DWORD dwRenameFlags)
1159 {
1160         FIXME(mmio, "This may fail\n");
1161         return mmioRename16(szFileName, szNewFileName, (MMIOINFO16*)lpmmioinfo, dwRenameFlags);
1162 }
1163
1164 /**************************************************************************
1165  *                              mmioRenameW                             [WINMM.126]
1166  */
1167 UINT WINAPI mmioRenameW(LPCWSTR szFileName, LPCWSTR szNewFileName,
1168                                                                          MMIOINFO* lpmmioinfo, DWORD dwRenameFlags)
1169 {
1170         LPSTR           szFn = HEAP_strdupWtoA(GetProcessHeap(), 0, szFileName);
1171         LPSTR           sznFn = HEAP_strdupWtoA(GetProcessHeap(), 0, szNewFileName);
1172         UINT    ret = mmioRenameA(szFn, sznFn, lpmmioinfo, dwRenameFlags);
1173
1174         HeapFree(GetProcessHeap(),0,szFn);
1175         HeapFree(GetProcessHeap(),0,sznFn);
1176         return ret;
1177 }