| /* |
| * MMSYSTEM mmio* functions |
| * |
| * Copyright 1993 Martin Ayotte |
| * 1998-2003,2009 Eric Pouech |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include <stdarg.h> |
| #include <string.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "mmsystem.h" |
| #include "winternl.h" |
| #include "wownt32.h" |
| #include "winnls.h" |
| |
| #include "wine/winuser16.h" |
| #include "winemm16.h" |
| |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(mmsys); |
| |
| /* ################################################### |
| * # MMIO # |
| * ################################################### |
| */ |
| #include <pshpack1.h> |
| #define MMIO_MAX_THUNKS 32 |
| |
| static struct mmio_thunk |
| { |
| BYTE popl_eax; /* popl %eax (return address) */ |
| BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */ |
| LPMMIOPROC16 pfn16; |
| BYTE pushl_eax; /* pushl %eax */ |
| BYTE jmp; /* ljmp MMIO_Callback1632 */ |
| DWORD callback; |
| HMMIO hMmio; /* Handle to 32bit mmio object */ |
| SEGPTR segbuffer; /* actual segmented ptr to buffer */ |
| } *MMIO_Thunks; |
| |
| #include <poppack.h> |
| |
| static CRITICAL_SECTION mmio_cs; |
| static CRITICAL_SECTION_DEBUG mmio_critsect_debug = |
| { |
| 0, 0, &mmio_cs, |
| { &mmio_critsect_debug.ProcessLocksList, &mmio_critsect_debug.ProcessLocksList }, |
| 0, 0, { (DWORD_PTR)(__FILE__ ": mmsystem_mmio_cs") } |
| }; |
| static CRITICAL_SECTION mmio_cs = { &mmio_critsect_debug, -1, 0, 0, 0, 0 }; |
| |
| /**************************************************************** |
| * MMIO_Map32To16 [INTERNAL] |
| */ |
| static LRESULT MMIO_Map32To16(DWORD wMsg, LPARAM* lp1, LPARAM* lp2) |
| { |
| switch (wMsg) { |
| case MMIOM_CLOSE: |
| case MMIOM_SEEK: |
| /* nothing to do */ |
| break; |
| case MMIOM_OPEN: |
| case MMIOM_READ: |
| case MMIOM_WRITE: |
| case MMIOM_WRITEFLUSH: |
| *lp1 = MapLS( (void *)*lp1 ); |
| break; |
| case MMIOM_RENAME: |
| *lp1 = MapLS( (void *)*lp1 ); |
| *lp2 = MapLS( (void *)*lp2 ); |
| break; |
| default: |
| if (wMsg < MMIOM_USER) |
| TRACE("Not a mappable message (%d)\n", wMsg); |
| } |
| return MMSYSERR_NOERROR; |
| } |
| |
| /**************************************************************** |
| * MMIO_UnMap32To16 [INTERNAL] |
| */ |
| static LRESULT MMIO_UnMap32To16(DWORD wMsg, LPARAM lParam1, LPARAM lParam2, |
| LPARAM lp1, LPARAM lp2) |
| { |
| switch (wMsg) { |
| case MMIOM_CLOSE: |
| case MMIOM_SEEK: |
| /* nothing to do */ |
| break; |
| case MMIOM_OPEN: |
| case MMIOM_READ: |
| case MMIOM_WRITE: |
| case MMIOM_WRITEFLUSH: |
| UnMapLS( lp1 ); |
| break; |
| case MMIOM_RENAME: |
| UnMapLS( lp1 ); |
| UnMapLS( lp2 ); |
| break; |
| default: |
| if (wMsg < MMIOM_USER) |
| TRACE("Not a mappable message (%d)\n", wMsg); |
| } |
| return MMSYSERR_NOERROR; |
| } |
| |
| /****************************************************************** |
| * MMIO_Callback3216 |
| * |
| * |
| */ |
| static LRESULT MMIO_Callback3216(SEGPTR cb16, LPMMIOINFO lpmmioinfo, UINT uMessage, |
| LPARAM lParam1, LPARAM lParam2) |
| { |
| DWORD result; |
| MMIOINFO16 mmioInfo16; |
| SEGPTR segmmioInfo16; |
| LPARAM lp1 = lParam1, lp2 = lParam2; |
| WORD args[7]; |
| |
| if (!cb16) return MMSYSERR_INVALPARAM; |
| |
| memset(&mmioInfo16, 0, sizeof(MMIOINFO16)); |
| mmioInfo16.lDiskOffset = lpmmioinfo->lDiskOffset; |
| mmioInfo16.adwInfo[0] = lpmmioinfo->adwInfo[0]; |
| mmioInfo16.adwInfo[1] = lpmmioinfo->adwInfo[1]; |
| mmioInfo16.adwInfo[2] = lpmmioinfo->adwInfo[2]; |
| /* map (lParam1, lParam2) into (lp1, lp2) 32=>16 */ |
| if ((result = MMIO_Map32To16(uMessage, &lp1, &lp2)) != MMSYSERR_NOERROR) |
| return result; |
| |
| segmmioInfo16 = MapLS(&mmioInfo16); |
| args[6] = HIWORD(segmmioInfo16); |
| args[5] = LOWORD(segmmioInfo16); |
| args[4] = uMessage; |
| args[3] = HIWORD(lp1); |
| args[2] = LOWORD(lp1); |
| args[1] = HIWORD(lp2); |
| args[0] = LOWORD(lp2); |
| WOWCallback16Ex( cb16, WCB16_PASCAL, sizeof(args), args, &result ); |
| UnMapLS(segmmioInfo16); |
| MMIO_UnMap32To16(uMessage, lParam1, lParam2, lp1, lp2); |
| |
| lpmmioinfo->lDiskOffset = mmioInfo16.lDiskOffset; |
| lpmmioinfo->adwInfo[0] = mmioInfo16.adwInfo[0]; |
| lpmmioinfo->adwInfo[1] = mmioInfo16.adwInfo[1]; |
| lpmmioinfo->adwInfo[2] = mmioInfo16.adwInfo[2]; |
| |
| return result; |
| } |
| |
| /****************************************************************** |
| * MMIO_AddThunk |
| * |
| */ |
| static struct mmio_thunk* MMIO_AddThunk(LPMMIOPROC16 pfn16, HPSTR segbuf) |
| { |
| struct mmio_thunk* thunk; |
| |
| if (!MMIO_Thunks) |
| { |
| MMIO_Thunks = VirtualAlloc(NULL, MMIO_MAX_THUNKS * sizeof(*MMIO_Thunks), MEM_COMMIT, |
| PAGE_EXECUTE_READWRITE); |
| if (!MMIO_Thunks) return NULL; |
| for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++) |
| { |
| thunk->popl_eax = 0x58; /* popl %eax */ |
| thunk->pushl_func = 0x68; /* pushl $pfn16 */ |
| thunk->pfn16 = 0; |
| thunk->pushl_eax = 0x50; /* pushl %eax */ |
| thunk->jmp = 0xe9; /* jmp MMIO_Callback3216 */ |
| thunk->callback = (char *)MMIO_Callback3216 - (char *)(&thunk->callback + 1); |
| thunk->hMmio = NULL; |
| thunk->segbuffer = 0; |
| } |
| } |
| for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++) |
| { |
| if (thunk->pfn16 == 0 && thunk->hMmio == NULL) |
| { |
| thunk->pfn16 = pfn16; |
| thunk->hMmio = NULL; |
| thunk->segbuffer = (SEGPTR)segbuf; |
| return thunk; |
| } |
| } |
| FIXME("Out of mmio-thunks. Bump MMIO_MAX_THUNKS\n"); |
| return NULL; |
| } |
| |
| /****************************************************************** |
| * MMIO_HasThunk |
| * |
| */ |
| static struct mmio_thunk* MMIO_HasThunk(HMMIO hmmio) |
| { |
| struct mmio_thunk* thunk; |
| |
| if (!MMIO_Thunks) return NULL; |
| for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++) |
| { |
| if (thunk->hMmio == hmmio) return thunk; |
| } |
| return NULL; |
| } |
| |
| /****************************************************************** |
| * MMIO_SetSegmentedBuffer |
| * |
| */ |
| static void MMIO_SetSegmentedBuffer(struct mmio_thunk* thunk, SEGPTR ptr, BOOL release) |
| { |
| if (release) UnMapLS(thunk->segbuffer); |
| thunk->segbuffer = ptr; |
| } |
| |
| /************************************************************************** |
| * mmioOpen [MMSYSTEM.1210] |
| */ |
| HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16* lpmmioinfo16, |
| DWORD dwOpenFlags) |
| { |
| HMMIO ret; |
| |
| if (lpmmioinfo16) { |
| MMIOINFO mmioinfo; |
| struct mmio_thunk* thunk = NULL; |
| |
| memset(&mmioinfo, 0, sizeof(mmioinfo)); |
| |
| EnterCriticalSection(&mmio_cs); |
| if (!(thunk = MMIO_AddThunk(lpmmioinfo16->pIOProc, lpmmioinfo16->pchBuffer))) |
| { |
| LeaveCriticalSection(&mmio_cs); |
| return 0; |
| } |
| |
| mmioinfo.dwFlags = lpmmioinfo16->dwFlags; |
| mmioinfo.fccIOProc = lpmmioinfo16->fccIOProc; |
| mmioinfo.pIOProc = lpmmioinfo16->pIOProc ? (LPMMIOPROC)thunk : 0; |
| mmioinfo.cchBuffer = lpmmioinfo16->cchBuffer; |
| mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo16->pchBuffer); |
| mmioinfo.adwInfo[0] = lpmmioinfo16->adwInfo[0]; |
| /* if we don't have a file name, it's likely a passed open file descriptor */ |
| if (!szFileName) |
| mmioinfo.adwInfo[0] = (DWORD)DosFileHandleToWin32Handle(mmioinfo.adwInfo[0]); |
| mmioinfo.adwInfo[1] = lpmmioinfo16->adwInfo[1]; |
| mmioinfo.adwInfo[2] = lpmmioinfo16->adwInfo[2]; |
| |
| ret = mmioOpenA(szFileName, &mmioinfo, dwOpenFlags); |
| if (!ret || (dwOpenFlags & (MMIO_PARSE|MMIO_EXIST))) |
| { |
| thunk->pfn16 = NULL; |
| thunk->hMmio = NULL; |
| } |
| else thunk->hMmio = ret; |
| if (ret && (dwOpenFlags & MMIO_ALLOCBUF)) |
| { |
| MMIOINFO m; |
| if (lpmmioinfo16->pchBuffer) FIXME("ooch\n"); |
| /* FIXME: check whether mmioOpen should set pchBuffer */ |
| mmioGetInfo(ret, &m, 0); |
| thunk->segbuffer = MapLS(m.pchBuffer); |
| } |
| LeaveCriticalSection(&mmio_cs); |
| |
| lpmmioinfo16->wErrorRet = mmioinfo.wErrorRet; |
| lpmmioinfo16->hmmio = HMMIO_16(mmioinfo.hmmio); |
| } else { |
| ret = mmioOpenA(szFileName, NULL, dwOpenFlags); |
| } |
| return HMMIO_16(ret); |
| } |
| |
| /************************************************************************** |
| * mmioClose [MMSYSTEM.1211] |
| */ |
| MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags) |
| { |
| MMRESULT ret; |
| |
| EnterCriticalSection(&mmio_cs); |
| ret = mmioClose(HMMIO_32(hmmio), uFlags); |
| if (ret == MMSYSERR_NOERROR) |
| { |
| struct mmio_thunk* thunk; |
| |
| if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio)))) |
| { |
| MMIO_SetSegmentedBuffer(thunk, 0, TRUE); |
| thunk->pfn16 = NULL; |
| thunk->hMmio = NULL; |
| } |
| } |
| LeaveCriticalSection(&mmio_cs); |
| return ret; |
| } |
| |
| /************************************************************************** |
| * mmioRead [MMSYSTEM.1212] |
| */ |
| LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch) |
| { |
| return mmioRead(HMMIO_32(hmmio), pch, cch); |
| } |
| |
| /************************************************************************** |
| * mmioWrite [MMSYSTEM.1213] |
| */ |
| LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch) |
| { |
| return mmioWrite(HMMIO_32(hmmio),pch,cch); |
| } |
| |
| /************************************************************************** |
| * mmioSeek [MMSYSTEM.1214] |
| */ |
| LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin) |
| { |
| return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin); |
| } |
| |
| /************************************************************************** |
| * mmioGetInfo [MMSYSTEM.1215] |
| */ |
| MMRESULT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags) |
| { |
| MMIOINFO mmioinfo; |
| MMRESULT ret; |
| struct mmio_thunk* thunk; |
| |
| TRACE("(0x%04x,%p,0x%08x)\n", hmmio, lpmmioinfo, uFlags); |
| |
| EnterCriticalSection(&mmio_cs); |
| if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))) == NULL) |
| { |
| LeaveCriticalSection(&mmio_cs); |
| return MMSYSERR_INVALHANDLE; |
| } |
| |
| ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags); |
| if (ret != MMSYSERR_NOERROR) |
| { |
| LeaveCriticalSection(&mmio_cs); |
| return ret; |
| } |
| |
| lpmmioinfo->dwFlags = mmioinfo.dwFlags; |
| lpmmioinfo->fccIOProc = mmioinfo.fccIOProc; |
| lpmmioinfo->pIOProc = thunk->pfn16; |
| lpmmioinfo->wErrorRet = mmioinfo.wErrorRet; |
| lpmmioinfo->hTask = HTASK_16(mmioinfo.hTask); |
| lpmmioinfo->cchBuffer = mmioinfo.cchBuffer; |
| lpmmioinfo->pchBuffer = (void*)thunk->segbuffer; |
| lpmmioinfo->pchNext = (void*)(thunk->segbuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer)); |
| lpmmioinfo->pchEndRead = (void*)(thunk->segbuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer)); |
| lpmmioinfo->pchEndWrite = (void*)(thunk->segbuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer)); |
| lpmmioinfo->lBufOffset = mmioinfo.lBufOffset; |
| lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset; |
| lpmmioinfo->adwInfo[0] = mmioinfo.adwInfo[0]; |
| lpmmioinfo->adwInfo[1] = mmioinfo.adwInfo[1]; |
| lpmmioinfo->adwInfo[2] = mmioinfo.adwInfo[2]; |
| lpmmioinfo->dwReserved1 = 0; |
| lpmmioinfo->dwReserved2 = 0; |
| lpmmioinfo->hmmio = HMMIO_16(mmioinfo.hmmio); |
| LeaveCriticalSection(&mmio_cs); |
| |
| return MMSYSERR_NOERROR; |
| } |
| |
| /************************************************************************** |
| * mmioSetInfo [MMSYSTEM.1216] |
| */ |
| MMRESULT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16* lpmmioinfo, UINT16 uFlags) |
| { |
| MMIOINFO mmioinfo; |
| MMRESULT ret; |
| |
| TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags); |
| |
| ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0); |
| if (ret != MMSYSERR_NOERROR) return ret; |
| |
| /* check if seg and lin buffers are the same */ |
| if (mmioinfo.cchBuffer != lpmmioinfo->cchBuffer || |
| mmioinfo.pchBuffer != MapSL((DWORD)lpmmioinfo->pchBuffer)) |
| return MMSYSERR_INVALPARAM; |
| |
| /* check pointers coherence */ |
| if (lpmmioinfo->pchNext < lpmmioinfo->pchBuffer || |
| lpmmioinfo->pchNext > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer || |
| lpmmioinfo->pchEndRead < lpmmioinfo->pchBuffer || |
| lpmmioinfo->pchEndRead > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer || |
| lpmmioinfo->pchEndWrite < lpmmioinfo->pchBuffer || |
| lpmmioinfo->pchEndWrite > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer) |
| return MMSYSERR_INVALPARAM; |
| |
| mmioinfo.pchNext = mmioinfo.pchBuffer + (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer); |
| mmioinfo.pchEndRead = mmioinfo.pchBuffer + (lpmmioinfo->pchEndRead - lpmmioinfo->pchBuffer); |
| mmioinfo.pchEndWrite = mmioinfo.pchBuffer + (lpmmioinfo->pchEndWrite - lpmmioinfo->pchBuffer); |
| |
| return mmioSetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags); |
| } |
| |
| /************************************************************************** |
| * mmioSetBuffer [MMSYSTEM.1217] |
| */ |
| MMRESULT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, SEGPTR pchBuffer, |
| LONG cchBuffer, UINT16 uFlags) |
| { |
| MMRESULT ret = mmioSetBuffer(HMMIO_32(hmmio), MapSL(pchBuffer), |
| cchBuffer, uFlags); |
| |
| if (ret == MMSYSERR_NOERROR) |
| { |
| struct mmio_thunk* thunk; |
| |
| if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio))) == NULL) |
| { |
| FIXME("really ?\n"); |
| return MMSYSERR_INVALHANDLE; |
| } |
| MMIO_SetSegmentedBuffer(thunk, pchBuffer, TRUE); |
| } |
| else |
| UnMapLS(pchBuffer); |
| return ret; |
| } |
| |
| /************************************************************************** |
| * mmioFlush [MMSYSTEM.1218] |
| */ |
| MMRESULT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags) |
| { |
| return mmioFlush(HMMIO_32(hmmio), uFlags); |
| } |
| |
| /*********************************************************************** |
| * mmioAdvance [MMSYSTEM.1219] |
| */ |
| MMRESULT16 WINAPI mmioAdvance16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags) |
| { |
| MMIOINFO mmioinfo; |
| LRESULT ret; |
| |
| /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which |
| * fields to init |
| */ |
| if (lpmmioinfo) |
| { |
| mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo->pchBuffer); |
| mmioinfo.pchNext = MapSL((DWORD)lpmmioinfo->pchNext); |
| mmioinfo.dwFlags = lpmmioinfo->dwFlags; |
| mmioinfo.lBufOffset = lpmmioinfo->lBufOffset; |
| ret = mmioAdvance(HMMIO_32(hmmio), &mmioinfo, uFlags); |
| } |
| else |
| ret = mmioAdvance(HMMIO_32(hmmio), NULL, uFlags); |
| |
| if (ret != MMSYSERR_NOERROR) return ret; |
| |
| if (lpmmioinfo) |
| { |
| lpmmioinfo->dwFlags = mmioinfo.dwFlags; |
| lpmmioinfo->pchNext = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer)); |
| lpmmioinfo->pchEndRead = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer)); |
| lpmmioinfo->pchEndWrite = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer)); |
| lpmmioinfo->lBufOffset = mmioinfo.lBufOffset; |
| lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset; |
| } |
| |
| return MMSYSERR_NOERROR; |
| } |
| |
| /************************************************************************** |
| * mmioStringToFOURCC [MMSYSTEM.1220] |
| */ |
| FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags) |
| { |
| return mmioStringToFOURCCA(sz, uFlags); |
| } |
| |
| /************************************************************************** |
| * mmioInstallIOProc [MMSYSTEM.1221] |
| */ |
| LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, LPMMIOPROC16 pIOProc, |
| DWORD dwFlags) |
| { |
| struct mmio_thunk* thunk = NULL; |
| LPMMIOPROC pIOProc32; |
| |
| EnterCriticalSection(&mmio_cs); |
| |
| switch (dwFlags & (MMIO_INSTALLPROC|MMIO_REMOVEPROC|MMIO_FINDPROC)) { |
| case MMIO_INSTALLPROC: |
| if (!(thunk = MMIO_AddThunk(pIOProc, NULL))) |
| { |
| LeaveCriticalSection(&mmio_cs); |
| return NULL; |
| } |
| if (!mmioInstallIOProcA(fccIOProc, (LPMMIOPROC)thunk, dwFlags)) |
| { |
| thunk->pfn16 = NULL; |
| pIOProc = NULL; |
| } |
| break; |
| case MMIO_REMOVEPROC: |
| if (MMIO_Thunks) |
| { |
| for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++) |
| { |
| if (thunk->pfn16 == pIOProc && thunk->segbuffer == 0) |
| { |
| if (mmioInstallIOProcA(fccIOProc, (LPMMIOPROC)thunk, dwFlags)) |
| thunk->pfn16 = NULL; |
| else |
| pIOProc = NULL; |
| break; |
| } |
| } |
| } |
| if (!thunk) pIOProc = NULL; |
| break; |
| case MMIO_FINDPROC: |
| if ((pIOProc32 = mmioInstallIOProcA(fccIOProc, NULL, dwFlags)) && MMIO_Thunks) |
| { |
| for (thunk = MMIO_Thunks; thunk < &MMIO_Thunks[MMIO_MAX_THUNKS]; thunk++) |
| { |
| if ((LPMMIOPROC)thunk == pIOProc32) |
| { |
| pIOProc = thunk->pfn16; |
| break; |
| } |
| } |
| } |
| break; |
| default: |
| FIXME("Unsupported flags %08x\n", dwFlags); |
| pIOProc = NULL; |
| } |
| LeaveCriticalSection(&mmio_cs); |
| |
| return pIOProc; |
| } |
| |
| /************************************************************************** |
| * mmioSendMessage [MMSYSTEM.1222] |
| */ |
| LRESULT WINAPI mmioSendMessage16(HMMIO16 hmmio, UINT16 uMessage, |
| LPARAM lParam1, LPARAM lParam2) |
| { |
| struct mmio_thunk* thunk; |
| |
| if ((thunk = MMIO_HasThunk(HMMIO_32(hmmio)))) |
| { |
| MMIOINFO mmioinfo; |
| if (mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0) == MMSYSERR_NOERROR) |
| { |
| return MMIO_Callback3216((SEGPTR)thunk->pfn16, &mmioinfo, uMessage, lParam1, lParam2); |
| } |
| return MMSYSERR_INVALHANDLE; |
| } |
| else |
| { |
| /* FIXME: we need to map lParam1 and lParam2 to 32bit entities */ |
| return mmioSendMessage(HMMIO_32(hmmio), uMessage, lParam1, lParam2); |
| } |
| } |
| |
| /************************************************************************** |
| * mmioDescend [MMSYSTEM.1223] |
| */ |
| MMRESULT16 WINAPI mmioDescend16(HMMIO16 hmmio, LPMMCKINFO lpck, |
| const MMCKINFO* lpckParent, UINT16 uFlags) |
| { |
| return mmioDescend(HMMIO_32(hmmio), lpck, lpckParent, uFlags); |
| } |
| |
| /************************************************************************** |
| * mmioAscend [MMSYSTEM.1224] |
| */ |
| MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags) |
| { |
| return mmioAscend(HMMIO_32(hmmio),lpck,uFlags); |
| } |
| |
| /************************************************************************** |
| * mmioCreateChunk [MMSYSTEM.1225] |
| */ |
| MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags) |
| { |
| return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags); |
| } |
| |
| /************************************************************************** |
| * mmioRename [MMSYSTEM.1226] |
| */ |
| MMRESULT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName, |
| MMIOINFO16* lpmmioinfo, DWORD dwRenameFlags) |
| { |
| BOOL inst = FALSE; |
| MMRESULT ret; |
| MMIOINFO mmioinfo; |
| |
| if (lpmmioinfo != NULL && lpmmioinfo->pIOProc != NULL && |
| lpmmioinfo->fccIOProc == 0) { |
| FIXME("Can't handle this case yet\n"); |
| return MMSYSERR_ERROR; |
| } |
| |
| /* this is a bit hacky, but it'll work if we get a fourCC code or nothing. |
| * but a non installed ioproc without a fourcc won't do |
| */ |
| if (lpmmioinfo && lpmmioinfo->fccIOProc && lpmmioinfo->pIOProc) { |
| mmioInstallIOProc16(lpmmioinfo->fccIOProc, lpmmioinfo->pIOProc, |
| MMIO_INSTALLPROC); |
| inst = TRUE; |
| } |
| memset(&mmioinfo, 0, sizeof(mmioinfo)); |
| if (lpmmioinfo) |
| mmioinfo.fccIOProc = lpmmioinfo->fccIOProc; |
| ret = mmioRenameA(szFileName, szNewFileName, &mmioinfo, dwRenameFlags); |
| if (inst) { |
| mmioInstallIOProc16(lpmmioinfo->fccIOProc, NULL, MMIO_REMOVEPROC); |
| } |
| return ret; |
| } |