Release 980503
[wine] / multimedia / mmio.c
1 /*
2  * MMIO functions
3  *
4  * Copyright 1998 Andrew Taylor
5  *
6  * NOTES:  I/O is still unbuffered;  mmioSetBuffer must be implemented
7  * and mmio{Read,Write,Seek,others?} need buffer support.
8  * Buffering should almost give us memory files for free.
9  */
10
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <errno.h>
16 #include "windows.h"
17 #include "win.h"
18 #include "heap.h"
19 #include "user.h"
20 #include "file.h"
21 #include "mmsystem.h"
22 #include "debug.h"
23 #include "xmalloc.h"
24
25 /**************************************************************************
26 *               mmioDosIOProc           [internal]
27 */
28 static LRESULT mmioDosIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lParam1, LPARAM lParam2) {
29         TRACE(mmio, "(%p, %X, %ld, %ld);\n", lpmmioinfo, uMessage, lParam1, lParam2);
30
31         switch (uMessage) {
32
33                 case MMIOM_OPEN: {
34                         /* Parameters:
35                          * lParam1 = szFileName parameter from mmioOpen
36                          * lParam2 = unused
37                          * Returns: zero on success, error code on error
38                          * NOTE: lDiskOffset automatically set to zero
39                          */
40
41                         OFSTRUCT ofs;
42                         LPSTR szFileName = (LPSTR) lParam1;
43
44                         if (lpmmioinfo->dwFlags & MMIO_GETTEMP) {
45                                 FIXME(mmio, "MMIO_GETTEMP not implemented\n");
46                                 return MMIOERR_CANNOTOPEN;
47                         }
48
49                         /* if filename NULL, assume open file handle in adwInfo[0] */
50                         if (!szFileName)
51                                 return 0;
52
53                         lpmmioinfo->adwInfo[0] =
54                                 (DWORD) OpenFile32(szFileName, &ofs, lpmmioinfo->dwFlags);
55                         if (lpmmioinfo->adwInfo[0] == -1)
56                                 return MMIOERR_CANNOTOPEN;
57
58                         return 0;
59                 }
60
61                 case MMIOM_CLOSE: {
62                         /* Parameters:
63                          * lParam1 = wFlags parameter from mmioClose
64                          * lParam2 = unused
65                          * Returns: zero on success, error code on error
66                          */
67
68                         UINT16 uFlags = (UINT16) lParam1;
69
70                         if (uFlags & MMIO_FHOPEN)
71                                 return 0;
72
73                         _lclose32((HFILE32)lpmmioinfo->adwInfo[0]);
74                         return 0;
75
76                 }
77
78                 case MMIOM_READ: {
79                         /* Parameters:
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
83                          *         in wErrorRet)
84                          * NOTE: lDiskOffset should be updated
85                          */
86
87                         HPSTR pch = (HPSTR) lParam1;
88                         LONG cch = (LONG) lParam2;
89                         LONG count;
90
91                         count = _lread32((HFILE32)lpmmioinfo->adwInfo[0], pch, cch);
92                         if (count != -1)
93                                 lpmmioinfo->lDiskOffset += count;
94
95                         return count;
96                 }
97
98                 case MMIOM_WRITE:
99                 case MMIOM_WRITEFLUSH: { 
100                         /* no internal buffering, so WRITEFLUSH handled same as WRITE */
101
102                         /* Parameters:
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
106                          *              wErrorRet)
107                          * NOTE: lDiskOffset should be updated
108                          */
109
110                         HPSTR pch = (HPSTR) lParam1;
111                         LONG cch = (LONG) lParam2;
112                         LONG count;
113
114                         count = _hwrite16((HFILE32)lpmmioinfo->adwInfo[0], pch, cch);
115                         if (count != -1)
116                                 lpmmioinfo->lDiskOffset += count;
117
118                         return count;
119                 }
120
121                 case MMIOM_SEEK: {
122             /* Parameters:
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
127              */
128
129             LONG Offset = (LONG) lParam1; 
130             LONG Whence = (LONG) lParam2; 
131             LONG pos;
132
133             pos = _llseek32((HFILE32)lpmmioinfo->adwInfo[0], Offset, Whence);
134             if (pos != -1)
135                 lpmmioinfo->lDiskOffset = pos;
136
137             return pos;
138                 }
139                   
140                 case MMIOM_RENAME: {
141             /* Parameters:
142              * lParam1 = old name
143              * lParam2 = new name
144              * Returns: zero on success, non-zero on failure
145              */
146
147             FIXME(mmio, "MMIOM_RENAME unimplemented\n");
148             return MMIOERR_FILENOTFOUND;
149                 }
150
151                 default:
152                         WARN(mmio, "unexpected message %u\n", uMessage);
153                         return 0;
154         }
155         
156         return 0;
157 }
158
159 /**************************************************************************
160 *               mmioDosIOProc           [internal]
161 */
162 static LRESULT mmioMemIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lParam1, LPARAM lParam2) {
163         return 0;
164 }
165
166 /**************************************************************************
167  *                              mmioOpenW                       [WINMM.123]
168  */
169 HMMIO32 WINAPI mmioOpen32W(LPWSTR szFileName, MMIOINFO32 * lpmmioinfo,
170                           DWORD dwOpenFlags)
171 {
172         LPSTR   szFn = HEAP_strdupWtoA(GetProcessHeap(),0,szFileName);
173         HMMIO32 ret = mmioOpen16(szFn,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags);
174
175         HeapFree(GetProcessHeap(),0,szFn);
176         return ret;
177 }
178
179 /**************************************************************************
180  *                              mmioOpenA                       [WINMM.122]
181  */
182 HMMIO32 WINAPI mmioOpen32A(LPSTR szFileName, MMIOINFO32 * lpmmioinfo,
183                           DWORD dwOpenFlags)
184 {
185         return mmioOpen16(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags);
186 }
187
188 /**************************************************************************
189  *                              mmioOpen                [MMSYSTEM.1210]
190  */
191 HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo,
192                           DWORD dwOpenFlags)
193 {
194         LPMMIOINFO16 lpmminfo;
195         HMMIO16 hmmio;
196         UINT16 result;
197
198         TRACE(mmio, "('%s', %p, %08lX);\n", szFileName, lpmmioinfo, dwOpenFlags);
199
200         hmmio = GlobalAlloc16(GHND, sizeof(MMIOINFO16));
201         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
202         if (lpmminfo == NULL)
203                 return 0;
204         memset(lpmminfo, 0, sizeof(MMIOINFO16));
205
206         /* assume DOS file if not otherwise specified */
207         if (!lpmmioinfo ||
208                 (lpmmioinfo->fccIOProc == 0 && lpmmioinfo->pIOProc == NULL)) {
209
210                 lpmminfo->fccIOProc = mmioFOURCC('D', 'O', 'S', ' ');
211                 lpmminfo->pIOProc = (LPMMIOPROC16) mmioDosIOProc;
212         }
213         /* if just the four character code is present, look up IO proc */
214         else if (lpmmioinfo->pIOProc == NULL) {
215
216                 lpmminfo->fccIOProc = lpmmioinfo->fccIOProc;
217                 lpmminfo->pIOProc = mmioInstallIOProc16(lpmmioinfo->fccIOProc, NULL, MMIO_FINDPROC);
218
219         } 
220         /* if IO proc specified, use it and specified four character code */
221         else {
222
223                 lpmminfo->fccIOProc = lpmmioinfo->fccIOProc;
224                 lpmminfo->pIOProc = lpmmioinfo->pIOProc;
225         }
226
227         if (dwOpenFlags & MMIO_ALLOCBUF) {
228                 if ((result = mmioSetBuffer(hmmio, NULL, MMIO_DEFAULTBUFFER, 0))) {
229                         if (lpmmioinfo)
230                                 lpmmioinfo->wErrorRet = result;
231                         return 0;
232                 }
233         }
234
235         lpmminfo->hmmio = hmmio;
236
237         /* call IO proc to actually open file */
238         result = (UINT16) mmioSendMessage(hmmio, MMIOM_OPEN, (LPARAM) szFileName, (LPARAM) 0);
239
240         GlobalUnlock16(hmmio);
241
242         if (result != 0) {
243                 GlobalFree16(hmmio);
244                 return 0;
245         }
246
247         return hmmio;
248 }
249
250     
251 /**************************************************************************
252 *                               mmioClose               [MMSYSTEM.1211]
253 */
254 UINT16 WINAPI mmioClose(HMMIO16 hmmio, UINT16 uFlags)
255 {
256         LPMMIOINFO16 lpmminfo;
257         UINT16 result;
258
259         TRACE(mmio, "(%04X, %04X);\n", hmmio, uFlags);
260
261         lpmminfo = (LPMMIOINFO16) GlobalLock16(hmmio);
262         if (lpmminfo == NULL)
263                 return 0;
264
265         /* flush the file - if error reported, ignore */
266         if (mmioFlush(hmmio, MMIO_EMPTYBUF) != 0)
267                 lpmminfo->dwFlags &= ~MMIO_DIRTY;
268
269         result = (UINT16) mmioSendMessage(hmmio, MMIOM_CLOSE, (LPARAM) uFlags, (LPARAM) 0);
270
271         mmioSetBuffer(hmmio, NULL, 0, 0);
272
273         GlobalUnlock16(hmmio);
274         GlobalFree16(hmmio);
275
276         return result;
277 }
278
279
280
281 /**************************************************************************
282 *                               mmioRead                [MMSYSTEM.1212]
283 */
284 LONG WINAPI mmioRead(HMMIO16 hmmio, HPSTR pch, LONG cch)
285 {
286         LONG count;
287         LPMMIOINFO16 lpmminfo;
288
289         TRACE(mmio, "(%04X, %p, %ld);\n", hmmio, pch, cch);
290
291         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
292         if (lpmminfo == NULL)
293                 return -1;
294
295         count = mmioSendMessage(hmmio, MMIOM_READ, (LPARAM) pch, (LPARAM) cch);
296
297         GlobalUnlock16(hmmio);
298         TRACE(mmio, "count=%ld\n", count);
299         return count;
300 }
301
302
303
304 /**************************************************************************
305 *                               mmioWrite               [MMSYSTEM.1213]
306 */
307 LONG WINAPI mmioWrite(HMMIO16 hmmio, HPCSTR pch, LONG cch)
308 {
309         LONG count;
310         LPMMIOINFO16 lpmminfo;
311
312         TRACE(mmio, "(%04X, %p, %ld);\n", hmmio, pch, cch);
313
314         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
315         if (lpmminfo == NULL)
316                 return -1;
317
318         count = mmioSendMessage(hmmio, MMIOM_WRITE, (LPARAM) pch, (LPARAM) cch);
319
320         GlobalUnlock16(hmmio);
321         TRACE(mmio, "count=%ld\n", count);
322         return count;
323 }
324
325 /**************************************************************************
326 *                               mmioSeek                [MMSYSTEM.1214]
327 */
328 LONG WINAPI mmioSeek(HMMIO16 hmmio, LONG lOffset, int iOrigin)
329 {
330         int offset;
331         LPMMIOINFO16 lpmminfo;
332
333         TRACE(mmio, "(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
334
335         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
336         if (lpmminfo == NULL)
337                 return 0;
338
339     offset = mmioSendMessage(hmmio, MMIOM_SEEK, (LPARAM) lOffset, (LPARAM) iOrigin);
340
341         GlobalUnlock16(hmmio);
342         return offset;
343 }
344
345 /**************************************************************************
346 *                               mmioGetInfo             [MMSYSTEM.1215]
347 */
348 UINT16 WINAPI mmioGetInfo(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
349 {
350         LPMMIOINFO16    lpmminfo;
351         TRACE(mmio, "mmioGetInfo\n");
352         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
353         if (lpmminfo == NULL) return 0;
354         memcpy(lpmmioinfo, lpmminfo, sizeof(MMIOINFO16));
355         GlobalUnlock16(hmmio);
356         return 0;
357 }
358
359 /**************************************************************************
360 *                               mmioSetInfo             [MMSYSTEM.1216]
361 */
362 UINT16 WINAPI mmioSetInfo(HMMIO16 hmmio, const MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
363 {
364         LPMMIOINFO16    lpmminfo;
365         TRACE(mmio, "mmioSetInfo\n");
366         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
367         if (lpmminfo == NULL) return 0;
368         GlobalUnlock16(hmmio);
369         return 0;
370 }
371
372 /**************************************************************************
373 *                               mmioSetBuffer           [MMSYSTEM.1217]
374 */
375 UINT16 WINAPI mmioSetBuffer(HMMIO16 hmmio, LPSTR pchBuffer, 
376                             LONG cchBuffer, UINT16 uFlags)
377 {
378         FIXME(mmio, "(hmmio=%d, pchBuf=%p, cchBuf=%d, uFlags=%#08x): stub\n",
379               hmmio, pchBuffer, cchBuffer, uFlags);
380         return MMIOERR_OUTOFMEMORY;
381 }
382
383 /**************************************************************************
384 *                               mmioFlush               [MMSYSTEM.1218]
385 */
386 UINT16 WINAPI mmioFlush(HMMIO16 hmmio, UINT16 uFlags)
387 {
388         LPMMIOINFO16    lpmminfo;
389         TRACE(mmio, "(%04X, %04X)\n", hmmio, uFlags);
390         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
391         if (lpmminfo == NULL) return 0;
392         GlobalUnlock16(hmmio);
393         return 0;
394 }
395
396 /**************************************************************************
397 *                               mmioAdvance             [MMSYSTEM.1219]
398 */
399 UINT16 WINAPI mmioAdvance(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
400 {
401         int             count = 0;
402         LPMMIOINFO16    lpmminfo;
403         TRACE(mmio, "mmioAdvance\n");
404         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
405         if (lpmminfo == NULL) return 0;
406         if (uFlags == MMIO_READ) {
407                 count = _lread32(LOWORD(lpmminfo->adwInfo[0]), 
408                         lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
409                 }
410         if (uFlags == MMIO_WRITE) {
411                 count = _lwrite32(LOWORD(lpmminfo->adwInfo[0]),
412                         lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
413                 }
414         lpmmioinfo->pchNext     += count;
415         GlobalUnlock16(hmmio);
416         lpmminfo->lDiskOffset = _llseek32((HFILE32)lpmminfo->adwInfo[0], 0, SEEK_CUR);
417         return 0;
418 }
419
420 /**************************************************************************
421  *                              mmioStringToFOURCCA     [WINMM.131]
422  */
423 FOURCC WINAPI mmioStringToFOURCC32A(LPCSTR sz, UINT32 uFlags)
424 {
425         return mmioStringToFOURCC16(sz,uFlags);
426 }
427
428 /**************************************************************************
429  *                              mmioStringToFOURCCW     [WINMM.132]
430  */
431 FOURCC WINAPI mmioStringToFOURCC32W(LPCWSTR sz, UINT32 uFlags)
432 {
433         LPSTR   szA = HEAP_strdupWtoA(GetProcessHeap(),0,sz);
434         FOURCC  ret = mmioStringToFOURCC32A(szA,uFlags);
435
436         HeapFree(GetProcessHeap(),0,szA);
437         return ret;
438 }
439
440 /**************************************************************************
441  *                              mmioStringToFOURCC      [MMSYSTEM.1220]
442  */
443 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
444 {
445         FIXME(mmio, "empty stub \n");
446         return 0;
447 }
448
449 /**************************************************************************
450 *                               mmioInstallIOProc16     [MMSYSTEM.1221]
451 */
452 LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, 
453                                         LPMMIOPROC16 pIOProc, DWORD dwFlags)
454 {
455         TRACE(mmio, "(%ld, %p, %08lX)\n",
456                                  fccIOProc, pIOProc, dwFlags);
457
458         if (dwFlags & MMIO_GLOBALPROC) {
459                 FIXME(mmio, " global procedures not implemented\n");
460         }
461
462         /* just handle the known procedures for now */
463         switch(dwFlags & (MMIO_INSTALLPROC|MMIO_REMOVEPROC|MMIO_FINDPROC)) {
464                 case MMIO_INSTALLPROC:
465                         return NULL;
466                 case MMIO_REMOVEPROC:
467                         return NULL;
468                 case MMIO_FINDPROC:
469                         if (fccIOProc == FOURCC_DOS)
470                                 return (LPMMIOPROC16) mmioDosIOProc;
471                         else if (fccIOProc == FOURCC_MEM)
472                                 return (LPMMIOPROC16) mmioMemIOProc;
473                         else
474                                 return NULL;
475                 default:
476                         return NULL;
477         }
478 }
479
480 /**************************************************************************
481  *                              mmioInstallIOProc32A   [WINMM.120]
482  */
483 LPMMIOPROC32 WINAPI mmioInstallIOProc32A(FOURCC fccIOProc, 
484                                          LPMMIOPROC32 pIOProc, DWORD dwFlags)
485 {
486         FIXME(mmio, "(%c%c%c%c,%p,0x%08lx) -- empty stub \n",
487                      (char)((fccIOProc&0xff000000)>>24),
488                      (char)((fccIOProc&0x00ff0000)>>16),
489                      (char)((fccIOProc&0x0000ff00)>> 8),
490                      (char)(fccIOProc&0x000000ff),
491                      pIOProc, dwFlags );
492         return 0;
493 }
494
495 /**************************************************************************
496 *                               mmioSendMessage         [MMSYSTEM.1222]
497 */
498 LRESULT WINAPI mmioSendMessage(HMMIO16 hmmio, UINT16 uMessage,
499                                LPARAM lParam1, LPARAM lParam2)
500 {
501         LPMMIOINFO16 lpmminfo;
502         LRESULT result;
503         const char *msg = NULL;
504
505 #ifdef DEBUG_RUNTIME
506         switch (uMessage) {
507 #define msgname(x) case x: msg = #x; break;
508                 msgname(MMIOM_OPEN);
509                 msgname(MMIOM_CLOSE);
510                 msgname(MMIOM_READ);
511                 msgname(MMIOM_WRITE);
512                 msgname(MMIOM_WRITEFLUSH);
513                 msgname(MMIOM_SEEK);
514                 msgname(MMIOM_RENAME);
515 #undef msgname
516         }
517 #endif
518
519         if (msg)
520                 TRACE(mmio, "(%04X, %s, %ld, %ld)\n",
521                                          hmmio, msg, lParam1, lParam2);
522         else
523                 TRACE(mmio, "(%04X, %u, %ld, %ld)\n",
524                                          hmmio, uMessage, lParam1, lParam2);
525         
526         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
527
528         if (lpmminfo && lpmminfo->pIOProc)
529                 result = (*lpmminfo->pIOProc)((LPSTR)lpmminfo, uMessage, lParam1, lParam2);
530         else
531                 result = MMSYSERR_INVALPARAM;
532
533         GlobalUnlock16(hmmio);
534
535         return result;
536 }
537
538 /**************************************************************************
539 *                               mmioDescend             [MMSYSTEM.1223]
540 */
541 UINT16 WINAPI mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
542                           const MMCKINFO * lpckParent, UINT16 uFlags)
543 {
544         DWORD   dwfcc, dwOldPos;
545
546         TRACE(mmio, "(%04X, %p, %p, %04X);\n", 
547                                 hmmio, lpck, lpckParent, uFlags);
548
549         if (lpck == NULL)
550             return 0;
551
552         dwfcc = lpck->ckid;
553         TRACE(mmio, "dwfcc=%08lX\n", dwfcc);
554
555         dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
556         TRACE(mmio, "dwOldPos=%ld\n", dwOldPos);
557
558         if (lpckParent != NULL) {
559                 TRACE(mmio, "seek inside parent at %ld !\n", lpckParent->dwDataOffset);
560                 dwOldPos = mmioSeek(hmmio, lpckParent->dwDataOffset, SEEK_SET);
561         }
562 /*
563
564    It seems to be that FINDRIFF should not be treated the same as the 
565    other FINDxxx so I treat it as a MMIO_FINDxxx
566
567         if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDRIFF) || 
568                 (uFlags & MMIO_FINDLIST)) {
569 */
570         if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDLIST)) {
571                 TRACE(mmio, "MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc);
572                 while (TRUE) {
573                         LONG ix;
574
575                         ix = mmioRead(hmmio, (LPSTR)lpck, sizeof(MMCKINFO));
576                         TRACE(mmio, "after _lread32 ix = %ld req = %d, errno = %d\n",ix,sizeof(MMCKINFO),errno);
577                         if (ix < sizeof(MMCKINFO)) {
578
579                                 mmioSeek(hmmio, dwOldPos, SEEK_SET);
580                                 WARN(mmio, "return ChunkNotFound\n");
581                                 return MMIOERR_CHUNKNOTFOUND;
582                         }
583                         TRACE(mmio, "dwfcc=%08lX ckid=%08lX cksize=%08lX !\n", 
584                                                                         dwfcc, lpck->ckid, lpck->cksize);
585                         if (dwfcc == lpck->ckid)
586                                 break;
587
588                         dwOldPos += lpck->cksize + 2 * sizeof(DWORD);
589                         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
590                                 dwOldPos += sizeof(DWORD);
591                         mmioSeek(hmmio, dwOldPos, SEEK_SET);
592                 }
593         }
594         else {
595                 if (mmioRead(hmmio, (LPSTR)lpck, sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
596                         mmioSeek(hmmio, dwOldPos, SEEK_SET);
597                         WARN(mmio, "return ChunkNotFound 2nd\n");
598                         return MMIOERR_CHUNKNOTFOUND;
599                 }
600         }
601         lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
602         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
603                 lpck->dwDataOffset += sizeof(DWORD);
604         mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
605
606         TRACE(mmio, "lpck->ckid=%08lX lpck->cksize=%ld !\n", 
607                                                                 lpck->ckid, lpck->cksize);
608         TRACE(mmio, "lpck->fccType=%08lX !\n", lpck->fccType);
609
610         return 0;
611 }
612
613 /**************************************************************************
614 *                               mmioAscend              [MMSYSTEM.1224]
615 */
616 UINT16 WINAPI mmioAscend(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
617 {
618         FIXME(mmio, "empty stub !\n");
619         return 0;
620 }
621
622 /**************************************************************************
623 *                               mmioCreateChunk         [MMSYSTEM.1225]
624 */
625 UINT16 WINAPI mmioCreateChunk(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
626 {
627         FIXME(mmio, "empty stub \n");
628         return 0;
629 }
630
631
632 /**************************************************************************
633 *                               mmioRename              [MMSYSTEM.1226]
634 */
635 UINT16 WINAPI mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
636                          MMIOINFO16 * lpmmioinfo, DWORD dwRenameFlags)
637 {
638         UINT16 result;
639         LPMMIOINFO16 lpmminfo;
640         HMMIO16 hmmio;
641
642         TRACE(mmio, "('%s', '%s', %p, %08lX);\n",
643                                  szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
644
645         hmmio = GlobalAlloc16(GHND, sizeof(MMIOINFO16));
646         lpmminfo = (LPMMIOINFO16) GlobalLock16(hmmio);
647
648         if (lpmmioinfo)
649                 memcpy(lpmminfo, lpmmioinfo, sizeof(MMIOINFO16));
650         
651         /* assume DOS file if not otherwise specified */
652         if (lpmminfo->fccIOProc == 0 && lpmminfo->pIOProc == NULL) {
653
654                 lpmminfo->fccIOProc = mmioFOURCC('D', 'O', 'S', ' ');
655                 lpmminfo->pIOProc = (LPMMIOPROC16) mmioDosIOProc;
656
657         }
658         /* if just the four character code is present, look up IO proc */
659         else if (lpmminfo->pIOProc == NULL) {
660
661                 lpmminfo->pIOProc = mmioInstallIOProc16(lpmminfo->fccIOProc, NULL, MMIO_FINDPROC);
662
663         } 
664         /* (if IO proc specified, use it and specified four character code) */
665
666         result = (UINT16) mmioSendMessage(hmmio, MMIOM_RENAME, (LPARAM) szFileName, (LPARAM) szNewFileName);
667         
668         GlobalUnlock16(hmmio);
669         GlobalFree16(hmmio);
670
671         return result;
672 }
673