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
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
34 #include "wine/winuser16.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(mmsys
);
41 /* ###################################################
43 * ###################################################
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) */
53 BYTE pushl_eax
; /* pushl %eax */
54 BYTE jmp
; /* ljmp MMIO_Callback1632 */
56 HMMIO hMmio
; /* Handle to 32bit mmio object */
57 SEGPTR segbuffer
; /* actual segmented ptr to buffer */
62 static CRITICAL_SECTION mmio_cs
;
63 static CRITICAL_SECTION_DEBUG mmio_critsect_debug
=
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
)
84 case MMIOM_WRITEFLUSH
:
85 *lp1
= MapLS( (void *)*lp1
);
88 *lp1
= MapLS( (void *)*lp1
);
89 *lp2
= MapLS( (void *)*lp2
);
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
)
112 case MMIOM_WRITEFLUSH
:
120 if (wMsg
< MMIOM_USER
)
121 TRACE("Not a mappable message (%d)\n", wMsg
);
123 return MMSYSERR_NOERROR
;
126 /******************************************************************
131 static LRESULT
MMIO_Callback3216(SEGPTR cb16
, LPMMIOINFO lpmmioinfo
, UINT uMessage
,
132 LPARAM lParam1
, LPARAM lParam2
)
135 MMIOINFO16 mmioInfo16
;
136 SEGPTR segmmioInfo16
;
137 LPARAM lp1
= lParam1
, lp2
= lParam2
;
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
)
151 segmmioInfo16
= MapLS(&mmioInfo16
);
152 args
[6] = HIWORD(segmmioInfo16
);
153 args
[5] = LOWORD(segmmioInfo16
);
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];
171 /******************************************************************
175 static struct mmio_thunk
* MMIO_AddThunk(LPMMIOPROC16 pfn16
, HPSTR segbuf
)
177 struct mmio_thunk
* thunk
;
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 */
189 thunk
->pushl_eax
= 0x50; /* pushl %eax */
190 thunk
->jmp
= 0xe9; /* jmp MMIO_Callback3216 */
191 thunk
->callback
= (char *)MMIO_Callback3216
- (char *)(&thunk
->callback
+ 1);
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
;
202 thunk
->segbuffer
= (SEGPTR
)segbuf
;
206 FIXME("Out of mmio-thunks. Bump MMIO_MAX_THUNKS\n");
210 /******************************************************************
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
;
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
,
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
);
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 */
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
)))
275 else thunk
->hMmio
= ret
;
276 if (ret
&& (dwOpenFlags
& MMIO_ALLOCBUF
))
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
);
289 ret
= mmioOpenA(szFileName
, NULL
, dwOpenFlags
);
291 return HMMIO_16(ret
);
294 /**************************************************************************
295 * mmioClose [MMSYSTEM.1211]
297 MMRESULT16 WINAPI
mmioClose16(HMMIO16 hmmio
, UINT16 uFlags
)
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
);
314 LeaveCriticalSection(&mmio_cs
);
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
)
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
);
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
)
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
),
433 if (ret
== MMSYSERR_NOERROR
)
435 struct mmio_thunk
* thunk
;
437 if ((thunk
= MMIO_HasThunk(HMMIO_32(hmmio
))) == NULL
)
440 return MMSYSERR_INVALHANDLE
;
442 MMIO_SetSegmentedBuffer(thunk
, (DWORD
)pchBuffer
, TRUE
);
445 UnMapLS((DWORD
)pchBuffer
);
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
)
465 /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which
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
);
477 ret
= mmioAdvance(HMMIO_32(hmmio
), NULL
, uFlags
);
479 if (ret
!= MMSYSERR_NOERROR
) return ret
;
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
,
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
);
520 if (!mmioInstallIOProcA(fccIOProc
, (LPMMIOPROC
)thunk
, dwFlags
))
526 case MMIO_REMOVEPROC
:
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
))
541 if (!thunk
) pIOProc
= NULL
;
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
;
557 WINE_FIXME("Unsupported flags %08x\n", dwFlags
);
560 LeaveCriticalSection(&mmio_cs
);
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
))))
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
;
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
)
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
,
638 memset(&mmioinfo
, 0, sizeof(mmioinfo
));
640 mmioinfo
.fccIOProc
= lpmmioinfo
->fccIOProc
;
641 ret
= mmioRenameA(szFileName
, szNewFileName
, &mmioinfo
, dwRenameFlags
);
643 mmioInstallIOProc16(lpmmioinfo
->fccIOProc
, NULL
, MMIO_REMOVEPROC
);