regedit: An English (United States) spelling fix.
[wine/multimedia.git] / dlls / mmsystem.dll16 / mmio16.c
blobff55ce9f85d3b9c51fc357c19176ea95b3eb4018
1 /*
2 * MMSYSTEM mmio* functions
4 * Copyright 1993 Martin Ayotte
5 * 1998-2003,2009 Eric Pouech
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27 #include "windef.h"
28 #include "winbase.h"
29 #include "mmsystem.h"
30 #include "winternl.h"
31 #include "wownt32.h"
32 #include "winnls.h"
34 #include "wine/winuser16.h"
35 #include "winemm16.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
41 /* ###################################################
42 * # MMIO #
43 * ###################################################
45 #include <pshpack1.h>
46 #define MMIO_MAX_THUNKS 32
48 static struct mmio_thunk
50 BYTE popl_eax; /* popl %eax (return address) */
51 BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */
52 LPMMIOPROC16 pfn16;
53 BYTE pushl_eax; /* pushl %eax */
54 BYTE jmp; /* ljmp MMIO_Callback1632 */
55 DWORD callback;
56 HMMIO hMmio; /* Handle to 32bit mmio object */
57 SEGPTR segbuffer; /* actual segmented ptr to buffer */
58 } *MMIO_Thunks;
60 #include <poppack.h>
62 static CRITICAL_SECTION mmio_cs;
63 static CRITICAL_SECTION_DEBUG mmio_critsect_debug =
65 0, 0, &mmio_cs,
66 { &mmio_critsect_debug.ProcessLocksList, &mmio_critsect_debug.ProcessLocksList },
67 0, 0, { (DWORD_PTR)(__FILE__ ": mmsystem_mmio_cs") }
69 static CRITICAL_SECTION mmio_cs = { &mmio_critsect_debug, -1, 0, 0, 0, 0 };
71 /****************************************************************
72 * MMIO_Map32To16 [INTERNAL]
74 static LRESULT MMIO_Map32To16(DWORD wMsg, LPARAM* lp1, LPARAM* lp2)
76 switch (wMsg) {
77 case MMIOM_CLOSE:
78 case MMIOM_SEEK:
79 /* nothing to do */
80 break;
81 case MMIOM_OPEN:
82 case MMIOM_READ:
83 case MMIOM_WRITE:
84 case MMIOM_WRITEFLUSH:
85 *lp1 = MapLS( (void *)*lp1 );
86 break;
87 case MMIOM_RENAME:
88 *lp1 = MapLS( (void *)*lp1 );
89 *lp2 = MapLS( (void *)*lp2 );
90 break;
91 default:
92 if (wMsg < MMIOM_USER)
93 TRACE("Not a mappable message (%d)\n", wMsg);
95 return MMSYSERR_NOERROR;
98 /****************************************************************
99 * MMIO_UnMap32To16 [INTERNAL]
101 static LRESULT MMIO_UnMap32To16(DWORD wMsg, LPARAM lParam1, LPARAM lParam2,
102 LPARAM lp1, LPARAM lp2)
104 switch (wMsg) {
105 case MMIOM_CLOSE:
106 case MMIOM_SEEK:
107 /* nothing to do */
108 break;
109 case MMIOM_OPEN:
110 case MMIOM_READ:
111 case MMIOM_WRITE:
112 case MMIOM_WRITEFLUSH:
113 UnMapLS( lp1 );
114 break;
115 case MMIOM_RENAME:
116 UnMapLS( lp1 );
117 UnMapLS( lp2 );
118 break;
119 default:
120 if (wMsg < MMIOM_USER)
121 TRACE("Not a mappable message (%d)\n", wMsg);
123 return MMSYSERR_NOERROR;
126 /******************************************************************
127 * MMIO_Callback3216
131 static LRESULT MMIO_Callback3216(SEGPTR cb16, LPMMIOINFO lpmmioinfo, UINT uMessage,
132 LPARAM lParam1, LPARAM lParam2)
134 DWORD result;
135 MMIOINFO16 mmioInfo16;
136 SEGPTR segmmioInfo16;
137 LPARAM lp1 = lParam1, lp2 = lParam2;
138 WORD args[7];
140 if (!cb16) return MMSYSERR_INVALPARAM;
142 memset(&mmioInfo16, 0, sizeof(MMIOINFO16));
143 mmioInfo16.lDiskOffset = lpmmioinfo->lDiskOffset;
144 mmioInfo16.adwInfo[0] = lpmmioinfo->adwInfo[0];
145 mmioInfo16.adwInfo[1] = lpmmioinfo->adwInfo[1];
146 mmioInfo16.adwInfo[2] = lpmmioinfo->adwInfo[2];
147 /* map (lParam1, lParam2) into (lp1, lp2) 32=>16 */
148 if ((result = MMIO_Map32To16(uMessage, &lp1, &lp2)) != MMSYSERR_NOERROR)
149 return result;
151 segmmioInfo16 = MapLS(&mmioInfo16);
152 args[6] = HIWORD(segmmioInfo16);
153 args[5] = LOWORD(segmmioInfo16);
154 args[4] = uMessage;
155 args[3] = HIWORD(lp1);
156 args[2] = LOWORD(lp1);
157 args[1] = HIWORD(lp2);
158 args[0] = LOWORD(lp2);
159 WOWCallback16Ex( cb16, WCB16_PASCAL, sizeof(args), args, &result );
160 UnMapLS(segmmioInfo16);
161 MMIO_UnMap32To16(uMessage, lParam1, lParam2, lp1, lp2);
163 lpmmioinfo->lDiskOffset = mmioInfo16.lDiskOffset;
164 lpmmioinfo->adwInfo[0] = mmioInfo16.adwInfo[0];
165 lpmmioinfo->adwInfo[1] = mmioInfo16.adwInfo[1];
166 lpmmioinfo->adwInfo[2] = mmioInfo16.adwInfo[2];
168 return result;
171 /******************************************************************
172 * MMIO_AddThunk
175 static struct mmio_thunk* MMIO_AddThunk(LPMMIOPROC16 pfn16, HPSTR segbuf)
177 struct mmio_thunk* thunk;
179 if (!MMIO_Thunks)
181 MMIO_Thunks = VirtualAlloc(NULL, MMIO_MAX_THUNKS * sizeof(*MMIO_Thunks), MEM_COMMIT,
182 PAGE_EXECUTE_READWRITE);
183 if (!MMIO_Thunks) return NULL;
184 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
186 thunk->popl_eax = 0x58; /* popl %eax */
187 thunk->pushl_func = 0x68; /* pushl $pfn16 */
188 thunk->pfn16 = 0;
189 thunk->pushl_eax = 0x50; /* pushl %eax */
190 thunk->jmp = 0xe9; /* jmp MMIO_Callback3216 */
191 thunk->callback = (char *)MMIO_Callback3216 - (char *)(&thunk->callback + 1);
192 thunk->hMmio = NULL;
193 thunk->segbuffer = 0;
196 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
198 if (thunk->pfn16 == 0 && thunk->hMmio == NULL)
200 thunk->pfn16 = pfn16;
201 thunk->hMmio = NULL;
202 thunk->segbuffer = (SEGPTR)segbuf;
203 return thunk;
206 FIXME("Out of mmio-thunks. Bump MMIO_MAX_THUNKS\n");
207 return NULL;
210 /******************************************************************
211 * MMIO_HasThunk
214 static struct mmio_thunk* MMIO_HasThunk(HMMIO hmmio)
216 struct mmio_thunk* thunk;
218 if (!MMIO_Thunks) return NULL;
219 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
221 if (thunk->hMmio == hmmio) return thunk;
223 return NULL;
226 /******************************************************************
227 * MMIO_SetSegmentedBuffer
230 static void MMIO_SetSegmentedBuffer(struct mmio_thunk* thunk, SEGPTR ptr, BOOL release)
232 if (release) UnMapLS(thunk->segbuffer);
233 thunk->segbuffer = ptr;
236 /**************************************************************************
237 * mmioOpen [MMSYSTEM.1210]
239 HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16* lpmmioinfo16,
240 DWORD dwOpenFlags)
242 HMMIO ret;
244 if (lpmmioinfo16) {
245 MMIOINFO mmioinfo;
246 struct mmio_thunk* thunk = NULL;
248 memset(&mmioinfo, 0, sizeof(mmioinfo));
250 EnterCriticalSection(&mmio_cs);
251 if (!(thunk = MMIO_AddThunk(lpmmioinfo16->pIOProc, lpmmioinfo16->pchBuffer)))
253 LeaveCriticalSection(&mmio_cs);
254 return 0;
257 mmioinfo.dwFlags = lpmmioinfo16->dwFlags;
258 mmioinfo.fccIOProc = lpmmioinfo16->fccIOProc;
259 mmioinfo.pIOProc = lpmmioinfo16->pIOProc ? (LPMMIOPROC)thunk : 0;
260 mmioinfo.cchBuffer = lpmmioinfo16->cchBuffer;
261 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo16->pchBuffer);
262 mmioinfo.adwInfo[0] = lpmmioinfo16->adwInfo[0];
263 /* if we don't have a file name, it's likely a passed open file descriptor */
264 if (!szFileName)
265 mmioinfo.adwInfo[0] = (DWORD)DosFileHandleToWin32Handle(mmioinfo.adwInfo[0]);
266 mmioinfo.adwInfo[1] = lpmmioinfo16->adwInfo[1];
267 mmioinfo.adwInfo[2] = lpmmioinfo16->adwInfo[2];
269 ret = mmioOpenA(szFileName, &mmioinfo, dwOpenFlags);
270 if (!ret || (dwOpenFlags & (MMIO_PARSE|MMIO_EXIST)))
272 thunk->pfn16 = NULL;
273 thunk->hMmio = NULL;
275 else thunk->hMmio = ret;
276 if (ret && (dwOpenFlags & MMIO_ALLOCBUF))
278 MMIOINFO m;
279 if (lpmmioinfo16->pchBuffer) FIXME("ooch\n");
280 /* FIXME: check whether mmioOpen should set pchBuffer */
281 mmioGetInfo(ret, &m, 0);
282 thunk->segbuffer = MapLS(m.pchBuffer);
284 LeaveCriticalSection(&mmio_cs);
286 lpmmioinfo16->wErrorRet = mmioinfo.wErrorRet;
287 lpmmioinfo16->hmmio = HMMIO_16(mmioinfo.hmmio);
288 } else {
289 ret = mmioOpenA(szFileName, NULL, dwOpenFlags);
291 return HMMIO_16(ret);
294 /**************************************************************************
295 * mmioClose [MMSYSTEM.1211]
297 MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags)
299 MMRESULT ret;
301 EnterCriticalSection(&mmio_cs);
302 ret = mmioClose(HMMIO_32(hmmio), uFlags);
303 if (ret == MMSYSERR_NOERROR)
305 struct mmio_thunk* thunk;
307 if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))))
309 MMIO_SetSegmentedBuffer(thunk, 0, TRUE);
310 thunk->pfn16 = NULL;
311 thunk->hMmio = NULL;
314 LeaveCriticalSection(&mmio_cs);
315 return ret;
318 /**************************************************************************
319 * mmioRead [MMSYSTEM.1212]
321 LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch)
323 return mmioRead(HMMIO_32(hmmio), pch, cch);
326 /**************************************************************************
327 * mmioWrite [MMSYSTEM.1213]
329 LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
331 return mmioWrite(HMMIO_32(hmmio),pch,cch);
334 /**************************************************************************
335 * mmioSeek [MMSYSTEM.1214]
337 LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
339 return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin);
342 /**************************************************************************
343 * mmioGetInfo [MMSYSTEM.1215]
345 MMRESULT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
347 MMIOINFO mmioinfo;
348 MMRESULT ret;
349 struct mmio_thunk* thunk;
351 TRACE("(0x%04x,%p,0x%08x)\n", hmmio, lpmmioinfo, uFlags);
353 EnterCriticalSection(&mmio_cs);
354 if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))) == NULL)
356 LeaveCriticalSection(&mmio_cs);
357 return MMSYSERR_INVALHANDLE;
360 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
361 if (ret != MMSYSERR_NOERROR)
363 LeaveCriticalSection(&mmio_cs);
364 return ret;
367 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
368 lpmmioinfo->fccIOProc = mmioinfo.fccIOProc;
369 lpmmioinfo->pIOProc = thunk->pfn16;
370 lpmmioinfo->wErrorRet = mmioinfo.wErrorRet;
371 lpmmioinfo->hTask = HTASK_16(mmioinfo.hTask);
372 lpmmioinfo->cchBuffer = mmioinfo.cchBuffer;
373 lpmmioinfo->pchBuffer = (void*)thunk->segbuffer;
374 lpmmioinfo->pchNext = (void*)(thunk->segbuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer));
375 lpmmioinfo->pchEndRead = (void*)(thunk->segbuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
376 lpmmioinfo->pchEndWrite = (void*)(thunk->segbuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
377 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
378 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
379 lpmmioinfo->adwInfo[0] = mmioinfo.adwInfo[0];
380 lpmmioinfo->adwInfo[1] = mmioinfo.adwInfo[1];
381 lpmmioinfo->adwInfo[2] = mmioinfo.adwInfo[2];
382 lpmmioinfo->dwReserved1 = 0;
383 lpmmioinfo->dwReserved2 = 0;
384 lpmmioinfo->hmmio = HMMIO_16(mmioinfo.hmmio);
385 LeaveCriticalSection(&mmio_cs);
387 return MMSYSERR_NOERROR;
390 /**************************************************************************
391 * mmioSetInfo [MMSYSTEM.1216]
393 MMRESULT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16* lpmmioinfo, UINT16 uFlags)
395 MMIOINFO mmioinfo;
396 MMRESULT ret;
398 TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
400 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0);
401 if (ret != MMSYSERR_NOERROR) return ret;
403 /* check if seg and lin buffers are the same */
404 if (mmioinfo.cchBuffer != lpmmioinfo->cchBuffer ||
405 mmioinfo.pchBuffer != MapSL((DWORD)lpmmioinfo->pchBuffer))
406 return MMSYSERR_INVALPARAM;
408 /* check pointers coherence */
409 if (lpmmioinfo->pchNext < lpmmioinfo->pchBuffer ||
410 lpmmioinfo->pchNext > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
411 lpmmioinfo->pchEndRead < lpmmioinfo->pchBuffer ||
412 lpmmioinfo->pchEndRead > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
413 lpmmioinfo->pchEndWrite < lpmmioinfo->pchBuffer ||
414 lpmmioinfo->pchEndWrite > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer)
415 return MMSYSERR_INVALPARAM;
417 mmioinfo.pchNext = mmioinfo.pchBuffer + (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer);
418 mmioinfo.pchEndRead = mmioinfo.pchBuffer + (lpmmioinfo->pchEndRead - lpmmioinfo->pchBuffer);
419 mmioinfo.pchEndWrite = mmioinfo.pchBuffer + (lpmmioinfo->pchEndWrite - lpmmioinfo->pchBuffer);
421 return mmioSetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
424 /**************************************************************************
425 * mmioSetBuffer [MMSYSTEM.1217]
427 MMRESULT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, LPSTR pchBuffer,
428 LONG cchBuffer, UINT16 uFlags)
430 MMRESULT ret = mmioSetBuffer(HMMIO_32(hmmio), MapSL((DWORD)pchBuffer),
431 cchBuffer, uFlags);
433 if (ret == MMSYSERR_NOERROR)
435 struct mmio_thunk* thunk;
437 if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))) == NULL)
439 FIXME("really ?\n");
440 return MMSYSERR_INVALHANDLE;
442 MMIO_SetSegmentedBuffer(thunk, (DWORD)pchBuffer, TRUE);
444 else
445 UnMapLS((DWORD)pchBuffer);
446 return ret;
449 /**************************************************************************
450 * mmioFlush [MMSYSTEM.1218]
452 MMRESULT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags)
454 return mmioFlush(HMMIO_32(hmmio), uFlags);
457 /***********************************************************************
458 * mmioAdvance [MMSYSTEM.1219]
460 MMRESULT16 WINAPI mmioAdvance16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
462 MMIOINFO mmioinfo;
463 LRESULT ret;
465 /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which
466 * fields to init
468 if (lpmmioinfo)
470 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo->pchBuffer);
471 mmioinfo.pchNext = MapSL((DWORD)lpmmioinfo->pchNext);
472 mmioinfo.dwFlags = lpmmioinfo->dwFlags;
473 mmioinfo.lBufOffset = lpmmioinfo->lBufOffset;
474 ret = mmioAdvance(HMMIO_32(hmmio), &mmioinfo, uFlags);
476 else
477 ret = mmioAdvance(HMMIO_32(hmmio), NULL, uFlags);
479 if (ret != MMSYSERR_NOERROR) return ret;
481 if (lpmmioinfo)
483 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
484 lpmmioinfo->pchNext = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer));
485 lpmmioinfo->pchEndRead = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
486 lpmmioinfo->pchEndWrite = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
487 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
488 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
491 return MMSYSERR_NOERROR;
494 /**************************************************************************
495 * mmioStringToFOURCC [MMSYSTEM.1220]
497 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
499 return mmioStringToFOURCCA(sz, uFlags);
502 /**************************************************************************
503 * mmioInstallIOProc [MMSYSTEM.1221]
505 LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, LPMMIOPROC16 pIOProc,
506 DWORD dwFlags)
508 struct mmio_thunk* thunk = NULL;
509 LPMMIOPROC pIOProc32;
511 EnterCriticalSection(&mmio_cs);
513 switch (dwFlags & (MMIO_INSTALLPROC|MMIO_REMOVEPROC|MMIO_FINDPROC)) {
514 case MMIO_INSTALLPROC:
515 if (!(thunk = MMIO_AddThunk(pIOProc, NULL)))
517 LeaveCriticalSection(&mmio_cs);
518 return NULL;
520 if (!mmioInstallIOProcA(fccIOProc, (LPMMIOPROC)thunk, dwFlags))
522 thunk->pfn16 = NULL;
523 pIOProc = NULL;
525 break;
526 case MMIO_REMOVEPROC:
527 if (MMIO_Thunks)
529 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
531 if (thunk->pfn16 == pIOProc && thunk->segbuffer == 0)
533 if (mmioInstallIOProcA(fccIOProc, (LPMMIOPROC)thunk, dwFlags))
534 thunk->pfn16 = NULL;
535 else
536 pIOProc = NULL;
537 break;
541 if (!thunk) pIOProc = NULL;
542 break;
543 case MMIO_FINDPROC:
544 if ((pIOProc32 = mmioInstallIOProcA(fccIOProc, NULL, dwFlags)) && MMIO_Thunks)
546 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
548 if ((LPMMIOPROC)thunk == pIOProc32)
550 pIOProc = thunk->pfn16;
551 break;
555 break;
556 default:
557 WINE_FIXME("Unsupported flags %08x\n", dwFlags);
558 pIOProc = NULL;
560 LeaveCriticalSection(&mmio_cs);
562 return pIOProc;
565 /**************************************************************************
566 * mmioSendMessage [MMSYSTEM.1222]
568 LRESULT WINAPI mmioSendMessage16(HMMIO16 hmmio, UINT16 uMessage,
569 LPARAM lParam1, LPARAM lParam2)
571 struct mmio_thunk* thunk;
573 if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))))
575 MMIOINFO mmioinfo;
576 if (mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0) == MMSYSERR_NOERROR)
578 return MMIO_Callback3216((SEGPTR)thunk->pfn16, &mmioinfo, uMessage, lParam1, lParam2);
580 return MMSYSERR_INVALHANDLE;
582 else
584 /* FIXME: we need to map lParam1 and lParam2 to 32bit entities */
585 return mmioSendMessage(HMMIO_32(hmmio), uMessage, lParam1, lParam2);
589 /**************************************************************************
590 * mmioDescend [MMSYSTEM.1223]
592 MMRESULT16 WINAPI mmioDescend16(HMMIO16 hmmio, LPMMCKINFO lpck,
593 const MMCKINFO* lpckParent, UINT16 uFlags)
595 return mmioDescend(HMMIO_32(hmmio), lpck, lpckParent, uFlags);
598 /**************************************************************************
599 * mmioAscend [MMSYSTEM.1224]
601 MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
603 return mmioAscend(HMMIO_32(hmmio),lpck,uFlags);
606 /**************************************************************************
607 * mmioCreateChunk [MMSYSTEM.1225]
609 MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
611 return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags);
614 /**************************************************************************
615 * mmioRename [MMSYSTEM.1226]
617 MMRESULT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName,
618 MMIOINFO16* lpmmioinfo, DWORD dwRenameFlags)
620 BOOL inst = FALSE;
621 MMRESULT ret;
622 MMIOINFO mmioinfo;
624 if (lpmmioinfo != NULL && lpmmioinfo->pIOProc != NULL &&
625 lpmmioinfo->fccIOProc == 0) {
626 FIXME("Can't handle this case yet\n");
627 return MMSYSERR_ERROR;
630 /* this is a bit hacky, but it'll work if we get a fourCC code or nothing.
631 * but a non installed ioproc without a fourcc won't do
633 if (lpmmioinfo && lpmmioinfo->fccIOProc && lpmmioinfo->pIOProc) {
634 mmioInstallIOProc16(lpmmioinfo->fccIOProc, lpmmioinfo->pIOProc,
635 MMIO_INSTALLPROC);
636 inst = TRUE;
638 memset(&mmioinfo, 0, sizeof(mmioinfo));
639 if (lpmmioinfo)
640 mmioinfo.fccIOProc = lpmmioinfo->fccIOProc;
641 ret = mmioRenameA(szFileName, szNewFileName, &mmioinfo, dwRenameFlags);
642 if (inst) {
643 mmioInstallIOProc16(lpmmioinfo->fccIOProc, NULL, MMIO_REMOVEPROC);
645 return ret;