ddraw/tests: Add another invalid arguments test for surface QI.
[wine.git] / dlls / mmsystem.dll16 / mmio16.c
blob366d4a573b6f7f9e0e021b3b5e4832e20485bb93
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 #include "windef.h"
26 #include "winbase.h"
27 #include "mmsystem.h"
28 #include "winternl.h"
29 #include "wownt32.h"
30 #include "winnls.h"
32 #include "wine/winuser16.h"
33 #include "winemm16.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
39 /* ###################################################
40 * # MMIO #
41 * ###################################################
43 #include <pshpack1.h>
44 #define MMIO_MAX_THUNKS 32
46 static struct mmio_thunk
48 BYTE popl_eax; /* popl %eax (return address) */
49 BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */
50 LPMMIOPROC16 pfn16;
51 BYTE pushl_eax; /* pushl %eax */
52 BYTE jmp; /* ljmp MMIO_Callback1632 */
53 DWORD callback;
54 HMMIO hMmio; /* Handle to 32bit mmio object */
55 SEGPTR segbuffer; /* actual segmented ptr to buffer */
56 } *MMIO_Thunks;
58 #include <poppack.h>
60 static CRITICAL_SECTION mmio_cs;
61 static CRITICAL_SECTION_DEBUG mmio_critsect_debug =
63 0, 0, &mmio_cs,
64 { &mmio_critsect_debug.ProcessLocksList, &mmio_critsect_debug.ProcessLocksList },
65 0, 0, { (DWORD_PTR)(__FILE__ ": mmsystem_mmio_cs") }
67 static CRITICAL_SECTION mmio_cs = { &mmio_critsect_debug, -1, 0, 0, 0, 0 };
69 /****************************************************************
70 * MMIO_Map32To16 [INTERNAL]
72 static LRESULT MMIO_Map32To16(DWORD wMsg, LPARAM* lp1, LPARAM* lp2)
74 switch (wMsg) {
75 case MMIOM_CLOSE:
76 case MMIOM_SEEK:
77 /* nothing to do */
78 break;
79 case MMIOM_OPEN:
80 case MMIOM_READ:
81 case MMIOM_WRITE:
82 case MMIOM_WRITEFLUSH:
83 *lp1 = MapLS( (void *)*lp1 );
84 break;
85 case MMIOM_RENAME:
86 *lp1 = MapLS( (void *)*lp1 );
87 *lp2 = MapLS( (void *)*lp2 );
88 break;
89 default:
90 if (wMsg < MMIOM_USER)
91 TRACE("Not a mappable message (%d)\n", wMsg);
93 return MMSYSERR_NOERROR;
96 /****************************************************************
97 * MMIO_UnMap32To16 [INTERNAL]
99 static LRESULT MMIO_UnMap32To16(DWORD wMsg, LPARAM lParam1, LPARAM lParam2,
100 LPARAM lp1, LPARAM lp2)
102 switch (wMsg) {
103 case MMIOM_CLOSE:
104 case MMIOM_SEEK:
105 /* nothing to do */
106 break;
107 case MMIOM_OPEN:
108 case MMIOM_READ:
109 case MMIOM_WRITE:
110 case MMIOM_WRITEFLUSH:
111 UnMapLS( lp1 );
112 break;
113 case MMIOM_RENAME:
114 UnMapLS( lp1 );
115 UnMapLS( lp2 );
116 break;
117 default:
118 if (wMsg < MMIOM_USER)
119 TRACE("Not a mappable message (%d)\n", wMsg);
121 return MMSYSERR_NOERROR;
124 /******************************************************************
125 * MMIO_Callback3216
129 static LRESULT MMIO_Callback3216(SEGPTR cb16, LPMMIOINFO lpmmioinfo, UINT uMessage,
130 LPARAM lParam1, LPARAM lParam2)
132 DWORD result;
133 MMIOINFO16 mmioInfo16;
134 SEGPTR segmmioInfo16;
135 LPARAM lp1 = lParam1, lp2 = lParam2;
136 WORD args[7];
138 if (!cb16) return MMSYSERR_INVALPARAM;
140 memset(&mmioInfo16, 0, sizeof(MMIOINFO16));
141 mmioInfo16.lDiskOffset = lpmmioinfo->lDiskOffset;
142 mmioInfo16.adwInfo[0] = lpmmioinfo->adwInfo[0];
143 mmioInfo16.adwInfo[1] = lpmmioinfo->adwInfo[1];
144 mmioInfo16.adwInfo[2] = lpmmioinfo->adwInfo[2];
145 /* map (lParam1, lParam2) into (lp1, lp2) 32=>16 */
146 if ((result = MMIO_Map32To16(uMessage, &lp1, &lp2)) != MMSYSERR_NOERROR)
147 return result;
149 segmmioInfo16 = MapLS(&mmioInfo16);
150 args[6] = HIWORD(segmmioInfo16);
151 args[5] = LOWORD(segmmioInfo16);
152 args[4] = uMessage;
153 args[3] = HIWORD(lp1);
154 args[2] = LOWORD(lp1);
155 args[1] = HIWORD(lp2);
156 args[0] = LOWORD(lp2);
157 WOWCallback16Ex( cb16, WCB16_PASCAL, sizeof(args), args, &result );
158 UnMapLS(segmmioInfo16);
159 MMIO_UnMap32To16(uMessage, lParam1, lParam2, lp1, lp2);
161 lpmmioinfo->lDiskOffset = mmioInfo16.lDiskOffset;
162 lpmmioinfo->adwInfo[0] = mmioInfo16.adwInfo[0];
163 lpmmioinfo->adwInfo[1] = mmioInfo16.adwInfo[1];
164 lpmmioinfo->adwInfo[2] = mmioInfo16.adwInfo[2];
166 return result;
169 /******************************************************************
170 * MMIO_AddThunk
173 static struct mmio_thunk* MMIO_AddThunk(LPMMIOPROC16 pfn16, HPSTR segbuf)
175 struct mmio_thunk* thunk;
177 if (!MMIO_Thunks)
179 MMIO_Thunks = VirtualAlloc(NULL, MMIO_MAX_THUNKS * sizeof(*MMIO_Thunks), MEM_COMMIT,
180 PAGE_EXECUTE_READWRITE);
181 if (!MMIO_Thunks) return NULL;
182 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
184 thunk->popl_eax = 0x58; /* popl %eax */
185 thunk->pushl_func = 0x68; /* pushl $pfn16 */
186 thunk->pfn16 = 0;
187 thunk->pushl_eax = 0x50; /* pushl %eax */
188 thunk->jmp = 0xe9; /* jmp MMIO_Callback3216 */
189 thunk->callback = (char *)MMIO_Callback3216 - (char *)(&thunk->callback + 1);
190 thunk->hMmio = NULL;
191 thunk->segbuffer = 0;
194 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
196 if (thunk->pfn16 == 0 && thunk->hMmio == NULL)
198 thunk->pfn16 = pfn16;
199 thunk->hMmio = NULL;
200 thunk->segbuffer = (SEGPTR)segbuf;
201 return thunk;
204 FIXME("Out of mmio-thunks. Bump MMIO_MAX_THUNKS\n");
205 return NULL;
208 /******************************************************************
209 * MMIO_HasThunk
212 static struct mmio_thunk* MMIO_HasThunk(HMMIO hmmio)
214 struct mmio_thunk* thunk;
216 if (!MMIO_Thunks) return NULL;
217 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
219 if (thunk->hMmio == hmmio) return thunk;
221 return NULL;
224 /******************************************************************
225 * MMIO_SetSegmentedBuffer
228 static void MMIO_SetSegmentedBuffer(struct mmio_thunk* thunk, SEGPTR ptr, BOOL release)
230 if (release) UnMapLS(thunk->segbuffer);
231 thunk->segbuffer = ptr;
234 /**************************************************************************
235 * mmioOpen [MMSYSTEM.1210]
237 HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16* lpmmioinfo16,
238 DWORD dwOpenFlags)
240 HMMIO ret;
242 if (lpmmioinfo16) {
243 MMIOINFO mmioinfo;
244 struct mmio_thunk* thunk = NULL;
246 memset(&mmioinfo, 0, sizeof(mmioinfo));
248 EnterCriticalSection(&mmio_cs);
249 if (!(thunk = MMIO_AddThunk(lpmmioinfo16->pIOProc, lpmmioinfo16->pchBuffer)))
251 LeaveCriticalSection(&mmio_cs);
252 return 0;
255 mmioinfo.dwFlags = lpmmioinfo16->dwFlags;
256 mmioinfo.fccIOProc = lpmmioinfo16->fccIOProc;
257 mmioinfo.pIOProc = lpmmioinfo16->pIOProc ? (LPMMIOPROC)thunk : 0;
258 mmioinfo.cchBuffer = lpmmioinfo16->cchBuffer;
259 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo16->pchBuffer);
260 mmioinfo.adwInfo[0] = lpmmioinfo16->adwInfo[0];
261 /* if we don't have a file name, it's likely a passed open file descriptor */
262 if (!szFileName)
263 mmioinfo.adwInfo[0] = (DWORD)DosFileHandleToWin32Handle(mmioinfo.adwInfo[0]);
264 mmioinfo.adwInfo[1] = lpmmioinfo16->adwInfo[1];
265 mmioinfo.adwInfo[2] = lpmmioinfo16->adwInfo[2];
267 ret = mmioOpenA(szFileName, &mmioinfo, dwOpenFlags);
268 if (!ret || (dwOpenFlags & (MMIO_PARSE|MMIO_EXIST)))
270 thunk->pfn16 = NULL;
271 thunk->hMmio = NULL;
273 else thunk->hMmio = ret;
274 if (ret && (dwOpenFlags & MMIO_ALLOCBUF))
276 MMIOINFO m;
277 if (lpmmioinfo16->pchBuffer) FIXME("ooch\n");
278 /* FIXME: check whether mmioOpen should set pchBuffer */
279 mmioGetInfo(ret, &m, 0);
280 thunk->segbuffer = MapLS(m.pchBuffer);
282 LeaveCriticalSection(&mmio_cs);
284 lpmmioinfo16->wErrorRet = mmioinfo.wErrorRet;
285 lpmmioinfo16->hmmio = HMMIO_16(mmioinfo.hmmio);
286 } else {
287 ret = mmioOpenA(szFileName, NULL, dwOpenFlags);
289 return HMMIO_16(ret);
292 /**************************************************************************
293 * mmioClose [MMSYSTEM.1211]
295 MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags)
297 MMRESULT ret;
299 EnterCriticalSection(&mmio_cs);
300 ret = mmioClose(HMMIO_32(hmmio), uFlags);
301 if (ret == MMSYSERR_NOERROR)
303 struct mmio_thunk* thunk;
305 if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))))
307 MMIO_SetSegmentedBuffer(thunk, 0, TRUE);
308 thunk->pfn16 = NULL;
309 thunk->hMmio = NULL;
312 LeaveCriticalSection(&mmio_cs);
313 return ret;
316 /**************************************************************************
317 * mmioRead [MMSYSTEM.1212]
319 LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch)
321 return mmioRead(HMMIO_32(hmmio), pch, cch);
324 /**************************************************************************
325 * mmioWrite [MMSYSTEM.1213]
327 LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
329 return mmioWrite(HMMIO_32(hmmio),pch,cch);
332 /**************************************************************************
333 * mmioSeek [MMSYSTEM.1214]
335 LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
337 return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin);
340 /**************************************************************************
341 * mmioGetInfo [MMSYSTEM.1215]
343 MMRESULT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
345 MMIOINFO mmioinfo;
346 MMRESULT ret;
347 struct mmio_thunk* thunk;
349 TRACE("(0x%04x,%p,0x%08x)\n", hmmio, lpmmioinfo, uFlags);
351 EnterCriticalSection(&mmio_cs);
352 if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))) == NULL)
354 LeaveCriticalSection(&mmio_cs);
355 return MMSYSERR_INVALHANDLE;
358 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
359 if (ret != MMSYSERR_NOERROR)
361 LeaveCriticalSection(&mmio_cs);
362 return ret;
365 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
366 lpmmioinfo->fccIOProc = mmioinfo.fccIOProc;
367 lpmmioinfo->pIOProc = thunk->pfn16;
368 lpmmioinfo->wErrorRet = mmioinfo.wErrorRet;
369 lpmmioinfo->hTask = HTASK_16(mmioinfo.hTask);
370 lpmmioinfo->cchBuffer = mmioinfo.cchBuffer;
371 lpmmioinfo->pchBuffer = (void*)thunk->segbuffer;
372 lpmmioinfo->pchNext = (void*)(thunk->segbuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer));
373 lpmmioinfo->pchEndRead = (void*)(thunk->segbuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
374 lpmmioinfo->pchEndWrite = (void*)(thunk->segbuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
375 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
376 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
377 lpmmioinfo->adwInfo[0] = mmioinfo.adwInfo[0];
378 lpmmioinfo->adwInfo[1] = mmioinfo.adwInfo[1];
379 lpmmioinfo->adwInfo[2] = mmioinfo.adwInfo[2];
380 lpmmioinfo->dwReserved1 = 0;
381 lpmmioinfo->dwReserved2 = 0;
382 lpmmioinfo->hmmio = HMMIO_16(mmioinfo.hmmio);
383 LeaveCriticalSection(&mmio_cs);
385 return MMSYSERR_NOERROR;
388 /**************************************************************************
389 * mmioSetInfo [MMSYSTEM.1216]
391 MMRESULT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16* lpmmioinfo, UINT16 uFlags)
393 MMIOINFO mmioinfo;
394 MMRESULT ret;
396 TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
398 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0);
399 if (ret != MMSYSERR_NOERROR) return ret;
401 /* check if seg and lin buffers are the same */
402 if (mmioinfo.cchBuffer != lpmmioinfo->cchBuffer ||
403 mmioinfo.pchBuffer != MapSL((DWORD)lpmmioinfo->pchBuffer))
404 return MMSYSERR_INVALPARAM;
406 /* check pointers coherence */
407 if (lpmmioinfo->pchNext < lpmmioinfo->pchBuffer ||
408 lpmmioinfo->pchNext > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
409 lpmmioinfo->pchEndRead < lpmmioinfo->pchBuffer ||
410 lpmmioinfo->pchEndRead > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
411 lpmmioinfo->pchEndWrite < lpmmioinfo->pchBuffer ||
412 lpmmioinfo->pchEndWrite > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer)
413 return MMSYSERR_INVALPARAM;
415 mmioinfo.pchNext = mmioinfo.pchBuffer + (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer);
416 mmioinfo.pchEndRead = mmioinfo.pchBuffer + (lpmmioinfo->pchEndRead - lpmmioinfo->pchBuffer);
417 mmioinfo.pchEndWrite = mmioinfo.pchBuffer + (lpmmioinfo->pchEndWrite - lpmmioinfo->pchBuffer);
419 return mmioSetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
422 /**************************************************************************
423 * mmioSetBuffer [MMSYSTEM.1217]
425 MMRESULT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, SEGPTR pchBuffer,
426 LONG cchBuffer, UINT16 uFlags)
428 MMRESULT ret = mmioSetBuffer(HMMIO_32(hmmio), MapSL(pchBuffer),
429 cchBuffer, uFlags);
431 if (ret == MMSYSERR_NOERROR)
433 struct mmio_thunk* thunk;
435 if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))) == NULL)
437 FIXME("really ?\n");
438 return MMSYSERR_INVALHANDLE;
440 MMIO_SetSegmentedBuffer(thunk, pchBuffer, TRUE);
442 else
443 UnMapLS(pchBuffer);
444 return ret;
447 /**************************************************************************
448 * mmioFlush [MMSYSTEM.1218]
450 MMRESULT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags)
452 return mmioFlush(HMMIO_32(hmmio), uFlags);
455 /***********************************************************************
456 * mmioAdvance [MMSYSTEM.1219]
458 MMRESULT16 WINAPI mmioAdvance16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
460 MMIOINFO mmioinfo;
461 LRESULT ret;
463 /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which
464 * fields to init
466 if (lpmmioinfo)
468 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo->pchBuffer);
469 mmioinfo.pchNext = MapSL((DWORD)lpmmioinfo->pchNext);
470 mmioinfo.dwFlags = lpmmioinfo->dwFlags;
471 mmioinfo.lBufOffset = lpmmioinfo->lBufOffset;
472 ret = mmioAdvance(HMMIO_32(hmmio), &mmioinfo, uFlags);
474 else
475 ret = mmioAdvance(HMMIO_32(hmmio), NULL, uFlags);
477 if (ret != MMSYSERR_NOERROR) return ret;
479 if (lpmmioinfo)
481 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
482 lpmmioinfo->pchNext = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer));
483 lpmmioinfo->pchEndRead = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
484 lpmmioinfo->pchEndWrite = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
485 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
486 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
489 return MMSYSERR_NOERROR;
492 /**************************************************************************
493 * mmioStringToFOURCC [MMSYSTEM.1220]
495 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
497 return mmioStringToFOURCCA(sz, uFlags);
500 /**************************************************************************
501 * mmioInstallIOProc [MMSYSTEM.1221]
503 LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, LPMMIOPROC16 pIOProc,
504 DWORD dwFlags)
506 struct mmio_thunk* thunk = NULL;
507 LPMMIOPROC pIOProc32;
509 EnterCriticalSection(&mmio_cs);
511 switch (dwFlags & (MMIO_INSTALLPROC|MMIO_REMOVEPROC|MMIO_FINDPROC)) {
512 case MMIO_INSTALLPROC:
513 if (!(thunk = MMIO_AddThunk(pIOProc, NULL)))
515 LeaveCriticalSection(&mmio_cs);
516 return NULL;
518 if (!mmioInstallIOProcA(fccIOProc, (LPMMIOPROC)thunk, dwFlags))
520 thunk->pfn16 = NULL;
521 pIOProc = NULL;
523 break;
524 case MMIO_REMOVEPROC:
525 if (MMIO_Thunks)
527 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
529 if (thunk->pfn16 == pIOProc && thunk->segbuffer == 0)
531 if (mmioInstallIOProcA(fccIOProc, (LPMMIOPROC)thunk, dwFlags))
532 thunk->pfn16 = NULL;
533 else
534 pIOProc = NULL;
535 break;
539 if (!thunk) pIOProc = NULL;
540 break;
541 case MMIO_FINDPROC:
542 if ((pIOProc32 = mmioInstallIOProcA(fccIOProc, NULL, dwFlags)) && MMIO_Thunks)
544 for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++)
546 if ((LPMMIOPROC)thunk == pIOProc32)
548 pIOProc = thunk->pfn16;
549 break;
553 break;
554 default:
555 FIXME("Unsupported flags %08x\n", dwFlags);
556 pIOProc = NULL;
558 LeaveCriticalSection(&mmio_cs);
560 return pIOProc;
563 /**************************************************************************
564 * mmioSendMessage [MMSYSTEM.1222]
566 LRESULT WINAPI mmioSendMessage16(HMMIO16 hmmio, UINT16 uMessage,
567 LPARAM lParam1, LPARAM lParam2)
569 struct mmio_thunk* thunk;
571 if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))))
573 MMIOINFO mmioinfo;
574 if (mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0) == MMSYSERR_NOERROR)
576 return MMIO_Callback3216((SEGPTR)thunk->pfn16, &mmioinfo, uMessage, lParam1, lParam2);
578 return MMSYSERR_INVALHANDLE;
580 else
582 /* FIXME: we need to map lParam1 and lParam2 to 32bit entities */
583 return mmioSendMessage(HMMIO_32(hmmio), uMessage, lParam1, lParam2);
587 /**************************************************************************
588 * mmioDescend [MMSYSTEM.1223]
590 MMRESULT16 WINAPI mmioDescend16(HMMIO16 hmmio, LPMMCKINFO lpck,
591 const MMCKINFO* lpckParent, UINT16 uFlags)
593 return mmioDescend(HMMIO_32(hmmio), lpck, lpckParent, uFlags);
596 /**************************************************************************
597 * mmioAscend [MMSYSTEM.1224]
599 MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
601 return mmioAscend(HMMIO_32(hmmio),lpck,uFlags);
604 /**************************************************************************
605 * mmioCreateChunk [MMSYSTEM.1225]
607 MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
609 return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags);
612 /**************************************************************************
613 * mmioRename [MMSYSTEM.1226]
615 MMRESULT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName,
616 MMIOINFO16* lpmmioinfo, DWORD dwRenameFlags)
618 BOOL inst = FALSE;
619 MMRESULT ret;
620 MMIOINFO mmioinfo;
622 if (lpmmioinfo != NULL && lpmmioinfo->pIOProc != NULL &&
623 lpmmioinfo->fccIOProc == 0) {
624 FIXME("Can't handle this case yet\n");
625 return MMSYSERR_ERROR;
628 /* this is a bit hacky, but it'll work if we get a fourCC code or nothing.
629 * but a non installed ioproc without a fourcc won't do
631 if (lpmmioinfo && lpmmioinfo->fccIOProc && lpmmioinfo->pIOProc) {
632 mmioInstallIOProc16(lpmmioinfo->fccIOProc, lpmmioinfo->pIOProc,
633 MMIO_INSTALLPROC);
634 inst = TRUE;
636 memset(&mmioinfo, 0, sizeof(mmioinfo));
637 if (lpmmioinfo)
638 mmioinfo.fccIOProc = lpmmioinfo->fccIOProc;
639 ret = mmioRenameA(szFileName, szNewFileName, &mmioinfo, dwRenameFlags);
640 if (inst) {
641 mmioInstallIOProc16(lpmmioinfo->fccIOProc, NULL, MMIO_REMOVEPROC);
643 return ret;