From d34041569e71fc9bd772354e94dc9d16061072a5 Mon Sep 17 00:00:00 2001 From: arpi_esp Date: Sat, 24 Feb 2001 20:28:24 +0000 Subject: Initial revision git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2 b3059339-0415-0410-9bf9-f77b7e298cf2 --- loader/Makefile | 30 + loader/afl.c | 763 ++++++++++++ loader/com.h | 66 ++ loader/config.h | 74 ++ loader/driver.c | 223 ++++ loader/elfdll.c | 305 +++++ loader/ext.c | 565 +++++++++ loader/loader.h | 286 +++++ loader/module.c | 618 ++++++++++ loader/pe_image.c | 936 +++++++++++++++ loader/pe_resource.c | 391 +++++++ loader/registry.c | 421 +++++++ loader/registry.h | 24 + loader/resource.c | 478 ++++++++ loader/stubs.s | 36 + loader/vfl.c | 330 ++++++ loader/win32.c | 1706 +++++++++++++++++++++++++++ loader/win32.h | 1 + loader/wine/avifmt.h | 246 ++++ loader/wine/basetsd.h | 145 +++ loader/wine/config.h | 442 +++++++ loader/wine/debugtools.h | 93 ++ loader/wine/driver.h | 112 ++ loader/wine/elfdll.h | 14 + loader/wine/heap.h | 56 + loader/wine/ldt.h | 98 ++ loader/wine/mmreg.h | 104 ++ loader/wine/module.h | 198 ++++ loader/wine/msacm.h | 942 +++++++++++++++ loader/wine/msacmdrv.h | 203 ++++ loader/wine/ntdef.h | 101 ++ loader/wine/pe_image.h | 81 ++ loader/wine/poppack.h | 15 + loader/wine/pshpack1.h | 13 + loader/wine/pshpack2.h | 12 + loader/wine/pshpack4.h | 15 + loader/wine/pshpack8.h | 12 + loader/wine/vfw.h | 654 +++++++++++ loader/wine/winbase.h | 1791 ++++++++++++++++++++++++++++ loader/wine/windef.h | 656 +++++++++++ loader/wine/windows.h | 38 + loader/wine/winerror.h | 1658 ++++++++++++++++++++++++++ loader/wine/winestring.h | 13 + loader/wine/winnt.h | 2665 +++++++++++++++++++++++++++++++++++++++++ loader/wine/winreg.h | 57 + loader/wine/winuser.h | 2929 ++++++++++++++++++++++++++++++++++++++++++++++ loader/wineacm.h | 55 + 47 files changed, 20671 insertions(+) create mode 100644 loader/Makefile create mode 100644 loader/afl.c create mode 100644 loader/com.h create mode 100644 loader/config.h create mode 100644 loader/driver.c create mode 100644 loader/elfdll.c create mode 100644 loader/ext.c create mode 100644 loader/loader.h create mode 100644 loader/module.c create mode 100644 loader/pe_image.c create mode 100644 loader/pe_resource.c create mode 100644 loader/registry.c create mode 100644 loader/registry.h create mode 100644 loader/resource.c create mode 100644 loader/stubs.s create mode 100644 loader/vfl.c create mode 100644 loader/win32.c create mode 100644 loader/win32.h create mode 100644 loader/wine/avifmt.h create mode 100644 loader/wine/basetsd.h create mode 100644 loader/wine/config.h create mode 100644 loader/wine/debugtools.h create mode 100644 loader/wine/driver.h create mode 100644 loader/wine/elfdll.h create mode 100644 loader/wine/heap.h create mode 100644 loader/wine/ldt.h create mode 100644 loader/wine/mmreg.h create mode 100644 loader/wine/module.h create mode 100644 loader/wine/msacm.h create mode 100644 loader/wine/msacmdrv.h create mode 100644 loader/wine/ntdef.h create mode 100644 loader/wine/pe_image.h create mode 100644 loader/wine/poppack.h create mode 100644 loader/wine/pshpack1.h create mode 100644 loader/wine/pshpack2.h create mode 100644 loader/wine/pshpack4.h create mode 100644 loader/wine/pshpack8.h create mode 100644 loader/wine/vfw.h create mode 100644 loader/wine/winbase.h create mode 100644 loader/wine/windef.h create mode 100644 loader/wine/windows.h create mode 100644 loader/wine/winerror.h create mode 100644 loader/wine/winestring.h create mode 100644 loader/wine/winnt.h create mode 100644 loader/wine/winreg.h create mode 100644 loader/wine/winuser.h create mode 100644 loader/wineacm.h (limited to 'loader') diff --git a/loader/Makefile b/loader/Makefile new file mode 100644 index 0000000000..2ecc1c32fe --- /dev/null +++ b/loader/Makefile @@ -0,0 +1,30 @@ +include ../config.mak + +# Generated automatically from Makefile.in by configure. +DEFINES=-rdynamic -fPIC $(WIN32_PATH) $(CDOPT) -D__WINE__ -Ddbg_printf=__vprintf \ + -DTRACE=__vprintf +# -DDETAILED_OUT + +LIB_OBJECTS= pe_image.o module.o \ +ext.o win32.o driver.o pe_resource.o \ +resource.o registry.o elfdll.o afl.o vfl.o + +CFLAGS=-g -I. + +CDOPT=-g +all: libloader.a + +clean: + -rm -f *.o libloader.a + +distclean: clean + +.c.o: $@ + $(CC) $(CFLAGS) $(DEFINES) -c $< + +libloader.a: $(LIB_OBJECTS) stubs.s + $(CC) -c ./stubs.s -o stubs.o + $(AR) -r libloader.a $(LIB_OBJECTS) stubs.o + +dep: + echo "dependency not required/supported" diff --git a/loader/afl.c b/loader/afl.c new file mode 100644 index 0000000000..7816a3f139 --- /dev/null +++ b/loader/afl.c @@ -0,0 +1,763 @@ +/************************************************************************** + + + This file will contain an interface to ACM drivers. + Its content will be based mainly on wine/dlls/msacm32 + actually, for audio decompression only the following functions + are needed: + + acmStreamOpen ( takes formats of src and dest, returns stream handle ) + acmStreamPrepareHeader ( takes stream handler and info on data ) + acmStreamConvert ( the same as PrepareHeader ) + acmStreamUnprepareHeader + acmStreamClose + acmStreamSize + maybe acmStreamReset + + In future I'll also add functions for format enumeration, + but not right now. + + +***************************************************************************/ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wineacm.h" +#pragma pack(1) +#define OpenDriverA DrvOpen +extern HDRVR VFWAPI DrvOpen(long); +#define CloseDriver DrvClose +extern HDRVR VFWAPI DrvClose(long); + +static PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has) +{ + return (PWINE_ACMSTREAM)has; +} + +/*********************************************************************** + * acmDriverAddA (MSACM32.2) + */ +MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule, + LPARAM lParam, DWORD dwPriority, DWORD fdwAdd) +{ + if (!phadid) + return MMSYSERR_INVALPARAM; + + /* Check if any unknown flags */ + if (fdwAdd & + ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND| + ACM_DRIVERADDF_GLOBAL)) + return MMSYSERR_INVALFLAG; + + /* Check if any incompatible flags */ + if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && + (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND)) + return MMSYSERR_INVALFLAG; + + /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a + * LoadDriver on it, to be sure we can call SendDriverMessage on the + * hDrvr handle. + */ + *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule); + + /* FIXME: lParam, dwPriority and fdwAdd ignored */ + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverClose (MSACM32.4) + */ +MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose) +{ + PWINE_ACMDRIVER p; + PWINE_ACMDRIVER* tp; + + if (fdwClose) + return MMSYSERR_INVALFLAG; + + p = MSACM_GetDriver(had); + if (!p) + return MMSYSERR_INVALHANDLE; + + for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) { + if (*tp == p) { + *tp = (*tp)->pNextACMDriver; + break; + } + } + + if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList) + CloseDriver(p->hDrvr); + + HeapFree(MSACM_hHeap, 0, p); + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverEnum (MSACM32.7) + */ +MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum) +{ + PWINE_ACMDRIVERID p; + DWORD fdwSupport; + + if (!fnCallback) { + return MMSYSERR_INVALPARAM; + } + + if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) { + return MMSYSERR_INVALFLAG; + } + + for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) { + fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; + if (!p->bEnabled) { + if (fdwEnum & ACM_DRIVERENUMF_DISABLED) + fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED; + else + continue; + } + (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport); + } + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverID (MSACM32.8) + */ +MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID) +{ + PWINE_ACMOBJ pao; + + pao = MSACM_GetObj(hao); + if (!pao) + return MMSYSERR_INVALHANDLE; + + if (!phadid) + return MMSYSERR_INVALPARAM; + + if (fdwDriverID) + return MMSYSERR_INVALFLAG; + + *phadid = (HACMDRIVERID) pao->pACMDriverID; + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverMessage (MSACM32.9) + * FIXME + * Not implemented + */ +LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2) +{ + PWINE_ACMDRIVER pad = MSACM_GetDriver(had); + if (!pad) + return MMSYSERR_INVALPARAM; + + /* FIXME: Check if uMsg legal */ + + if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2)) + return MMSYSERR_NOTSUPPORTED; + + return MMSYSERR_NOERROR; +} + + +/*********************************************************************** + * acmDriverOpen (MSACM32.10) + */ +MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen) +{ + PWINE_ACMDRIVERID padid; + PWINE_ACMDRIVER pad; + ICOPEN icopen; + HDRVR hdrv; + + + + TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen); + + if (!phad) + return MMSYSERR_INVALPARAM; + + padid = MSACM_GetDriverID(hadid); + if (!padid) + return MMSYSERR_INVALHANDLE; + + if (fdwOpen) + return MMSYSERR_INVALFLAG; + + pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER)); + if (!pad) return MMSYSERR_NOMEM; + + pad->obj.pACMDriverID = padid; + icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c'); + icopen.fccHandler = (long)padid->pszFileName; + icopen.dwSize = sizeof(ICOPEN); + icopen.dwFlags = 0; + + if (!padid->hInstModule) + pad->hDrvr = OpenDriverA((long)&icopen); + else + pad->hDrvr = padid->hInstModule; + + if (!pad->hDrvr) { + HeapFree(MSACM_hHeap, 0, pad); + return MMSYSERR_ERROR; + } + + pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc"); + + /* insert new pad at beg of list */ + pad->pNextACMDriver = padid->pACMDriverList; + padid->pACMDriverList = pad; + + /* FIXME: Create a WINE_ACMDRIVER32 */ + *phad = (HACMDRIVER)pad; + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverRemove (MSACM32.12) + */ +MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove) +{ + PWINE_ACMDRIVERID padid; + + padid = MSACM_GetDriverID(hadid); + if (!padid) + return MMSYSERR_INVALHANDLE; + + if (fdwRemove) + return MMSYSERR_INVALFLAG; + + MSACM_UnregisterDriver(padid); + + return MMSYSERR_NOERROR; +} + + + +/**********************************************************************/ + +HANDLE MSACM_hHeap = (HANDLE) NULL; +PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL; +PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL; + +/*********************************************************************** + * MSACM_RegisterDriver32() + */ +PWINE_ACMDRIVERID MSACM_RegisterDriver(LPSTR pszDriverAlias, LPSTR pszFileName, + HINSTANCE hinstModule) +// +// File names are stored in driver.c. I reuse this variable to store driver ID +// in it. If it's <0x10000, it is primary codec for corresponding format. +// +{ + PWINE_ACMDRIVERID padid; + + TRACE("('%s', '%x', 0x%08x)\n", pszDriverAlias, pszFileName, hinstModule); + + padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID)); + padid->pszDriverAlias = (char*)malloc(strlen(pszDriverAlias)+1); + strcpy(padid->pszDriverAlias, pszDriverAlias); +// 1~strdup(pszDriverAlias); + padid->pszFileName = pszFileName; + padid->hInstModule = hinstModule; + padid->bEnabled = TRUE; + padid->pACMDriverList = NULL; + padid->pNextACMDriverID = NULL; + padid->pPrevACMDriverID = MSACM_pLastACMDriverID; + if (MSACM_pLastACMDriverID) + MSACM_pLastACMDriverID->pNextACMDriverID = padid; + MSACM_pLastACMDriverID = padid; + if (!MSACM_pFirstACMDriverID) + MSACM_pFirstACMDriverID = padid; + + return padid; +} + +/*********************************************************************** + * MSACM_RegisterAllDrivers32() + */ +void MSACM_RegisterAllDrivers(void) +{ + LPSTR pszBuffer; + DWORD dwBufferLength; + + if (MSACM_pFirstACMDriverID) + return; + + MSACM_RegisterDriver("divxa32", (LPSTR)0x161, 0); // DivX/WMA [07] + MSACM_RegisterDriver("msadp32", (LPSTR)0x2, 0); // MS ADPCM [08] + MSACM_RegisterDriver("l3codeca", (LPSTR)0x55, 0); // MPEG Layer-3 [12] +// MSACM_RegisterDriver("imaadp32", (LPSTR)0x11, 0); // IMA ADPCM [13] +// MSACM_RegisterDriver("msgsm32", (LPSTR)0x32, 0); // MS GSM 6.10 [14] +} + +/*********************************************************************** + * MSACM_UnregisterDriver32() + */ +PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p) +{ + PWINE_ACMDRIVERID pNextACMDriverID; + + while (p->pACMDriverList) + acmDriverClose((HACMDRIVER) p->pACMDriverList, 0); + + if (p->pszDriverAlias) + HeapFree(MSACM_hHeap, 0, p->pszDriverAlias); +// if (p->pszFileName) +// HeapFree(MSACM_hHeap, 0, p->pszFileName); + + if (p == MSACM_pFirstACMDriverID) + MSACM_pFirstACMDriverID = p->pNextACMDriverID; + if (p == MSACM_pLastACMDriverID) + MSACM_pLastACMDriverID = p->pPrevACMDriverID; + + if (p->pPrevACMDriverID) + p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID; + if (p->pNextACMDriverID) + p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID; + + pNextACMDriverID = p->pNextACMDriverID; + + HeapFree(MSACM_hHeap, 0, p); + + return pNextACMDriverID; +} + +/*********************************************************************** + * MSACM_UnregisterAllDrivers32() + * FIXME + * Where should this function be called? + */ +void MSACM_UnregisterAllDrivers(void) +{ + PWINE_ACMDRIVERID p; + + for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p)); +} + +/*********************************************************************** + * MSACM_GetDriverID32() + */ +PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID) +{ + return (PWINE_ACMDRIVERID)hDriverID; +} + +/*********************************************************************** + * MSACM_GetDriver32() + */ +PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver) +{ + return (PWINE_ACMDRIVER)hDriver; +} + +/*********************************************************************** + * MSACM_GetObj32() + */ +PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj) +{ + return (PWINE_ACMOBJ)hObj; +} + + + +/*********************************************************************** + * acmStreamOpen (MSACM32.40) + */ +MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc, + PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback, + DWORD dwInstance, DWORD fdwOpen) +{ + PWINE_ACMSTREAM was; + PWINE_ACMDRIVER wad; + MMRESULT ret; + int wfxSrcSize; + int wfxDstSize; + + TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n", + phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen); + + TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", + pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec, + pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize); + + TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", + pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec, + pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize); + +#define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize)) + wfxSrcSize = SIZEOF_WFX(pwfxSrc); + wfxDstSize = SIZEOF_WFX(pwfxDst); +#undef SIZEOF_WFX + + was = HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0)); + if (was == NULL) + return MMSYSERR_NOMEM; + + was->drvInst.cbStruct = sizeof(was->drvInst); + was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was)); + memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize); + was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize); + memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize); + if (pwfltr) { + was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize); + memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER)); + } else { + was->drvInst.pwfltr = NULL; + } + was->drvInst.dwCallback = dwCallback; + was->drvInst.dwInstance = dwInstance; + was->drvInst.fdwOpen = fdwOpen; + was->drvInst.fdwDriver = 0L; + was->drvInst.dwDriver = 0L; + was->drvInst.has = (HACMSTREAM)was; + + if (had) { + if (!(wad = MSACM_GetDriver(had))) { + ret = MMSYSERR_INVALPARAM; + goto errCleanUp; + } + + was->obj.pACMDriverID = wad->obj.pACMDriverID; + was->pDrv = wad; + was->hAcmDriver = 0; /* not to close it in acmStreamClose */ + + ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); + if (ret != MMSYSERR_NOERROR) + goto errCleanUp; + } else { + PWINE_ACMDRIVERID wadi; + short drv_tag; + ret = ACMERR_NOTPOSSIBLE; +/* if(pwfxSrc->wFormatTag==1)//compression + drv_tag=pwfxDst->wFormatTag; + else + if(pwfxDst->wFormatTag==1)//decompression + drv_tag=pwfxSrc->wFormatTag; + else + goto errCleanUp; + + ret=acmDriverOpen2(drv_tag); + if (ret == MMSYSERR_NOERROR) { + if ((wad = MSACM_GetDriver(had)) != 0) { + was->obj.pACMDriverID = wad->obj.pACMDriverID; + was->pDrv = wad; + was->hAcmDriver = had; + + ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); + if (ret == MMSYSERR_NOERROR) { + if (fdwOpen & ACM_STREAMOPENF_QUERY) { + acmDriverClose(had, 0L); + } + break; + } + } + acmDriverClose(had, 0L);*/ + if(MSACM_pFirstACMDriverID==NULL) + MSACM_RegisterAllDrivers(); + + for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID) { + ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L); + if (ret == MMSYSERR_NOERROR) { + if ((wad = MSACM_GetDriver(had)) != 0) { + was->obj.pACMDriverID = wad->obj.pACMDriverID; + was->pDrv = wad; + was->hAcmDriver = had; + + ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); + if (ret == MMSYSERR_NOERROR) { + if (fdwOpen & ACM_STREAMOPENF_QUERY) { + acmDriverClose(had, 0L); + } + break; + } + } + // no match, close this acm driver and try next one + acmDriverClose(had, 0L); + } + } + if (ret != MMSYSERR_NOERROR) { + ret = ACMERR_NOTPOSSIBLE; + goto errCleanUp; + } + } + ret = MMSYSERR_NOERROR; + if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) { + if (phas) + *phas = (HACMSTREAM)was; + TRACE("=> (%d)\n", ret); + return ret; + } +errCleanUp: + if (phas) + *phas = (HACMSTREAM)0; + HeapFree(MSACM_hHeap, 0, was); + TRACE("=> (%d)\n", ret); + return ret; +} + + +MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose) +{ + PWINE_ACMSTREAM was; + MMRESULT ret; + + TRACE("(0x%08x, %ld)\n", has, fdwClose); + + if ((was = ACM_GetStream(has)) == NULL) { + return MMSYSERR_INVALHANDLE; + } + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0); + if (ret == MMSYSERR_NOERROR) { + if (was->hAcmDriver) + acmDriverClose(was->hAcmDriver, 0L); + HeapFree(MSACM_hHeap, 0, was); + } + TRACE("=> (%d)\n", ret); + return ret; +} + +/*********************************************************************** + * acmStreamConvert (MSACM32.38) + */ +MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash, + DWORD fdwConvert) +{ + PWINE_ACMSTREAM was; + MMRESULT ret = MMSYSERR_NOERROR; + PACMDRVSTREAMHEADER padsh; + + TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert); + + if ((was = ACM_GetStream(has)) == NULL) + return MMSYSERR_INVALHANDLE; + if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) + return MMSYSERR_INVALPARAM; + + if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) + return ACMERR_UNPREPARED; + + /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same + * size. some fields are private to msacm internals, and are exposed + * in ACMSTREAMHEADER in the dwReservedDriver array + */ + padsh = (PACMDRVSTREAMHEADER)pash; + + /* check that pointers have not been modified */ + if (padsh->pbPreparedSrc != padsh->pbSrc || + padsh->cbPreparedSrcLength < padsh->cbSrcLength || + padsh->pbPreparedDst != padsh->pbDst || + padsh->cbPreparedDstLength < padsh->cbDstLength) { + return MMSYSERR_INVALPARAM; + } + + padsh->fdwConvert = fdwConvert; + + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh); + if (ret == MMSYSERR_NOERROR) { + padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE; + } + TRACE("=> (%d)\n", ret); + return ret; +} + + +/*********************************************************************** + * acmStreamPrepareHeader (MSACM32.41) + */ +MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, + DWORD fdwPrepare) +{ + PWINE_ACMSTREAM was; + MMRESULT ret = MMSYSERR_NOERROR; + PACMDRVSTREAMHEADER padsh; + + TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare); + + if ((was = ACM_GetStream(has)) == NULL) + return MMSYSERR_INVALHANDLE; + if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) + return MMSYSERR_INVALPARAM; + if (fdwPrepare) + ret = MMSYSERR_INVALFLAG; + + if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE) + return MMSYSERR_NOERROR; + + /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same + * size. some fields are private to msacm internals, and are exposed + * in ACMSTREAMHEADER in the dwReservedDriver array + */ + padsh = (PACMDRVSTREAMHEADER)pash; + + padsh->fdwConvert = fdwPrepare; + padsh->padshNext = NULL; + padsh->fdwDriver = padsh->dwDriver = 0L; + + padsh->fdwPrepared = 0; + padsh->dwPrepared = 0; + padsh->pbPreparedSrc = 0; + padsh->cbPreparedSrcLength = 0; + padsh->pbPreparedDst = 0; + padsh->cbPreparedDstLength = 0; + + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh); + if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) { + ret = MMSYSERR_NOERROR; + padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE); + padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED; + padsh->fdwPrepared = padsh->fdwStatus; + padsh->dwPrepared = 0; + padsh->pbPreparedSrc = padsh->pbSrc; + padsh->cbPreparedSrcLength = padsh->cbSrcLength; + padsh->pbPreparedDst = padsh->pbDst; + padsh->cbPreparedDstLength = padsh->cbDstLength; + } else { + padsh->fdwPrepared = 0; + padsh->dwPrepared = 0; + padsh->pbPreparedSrc = 0; + padsh->cbPreparedSrcLength = 0; + padsh->pbPreparedDst = 0; + padsh->cbPreparedDstLength = 0; + } + TRACE("=> (%d)\n", ret); + return ret; +} + +/*********************************************************************** + * acmStreamReset (MSACM32.42) + */ +MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset) +{ + PWINE_ACMSTREAM was; + MMRESULT ret = MMSYSERR_NOERROR; + + TRACE("(0x%08x, %ld)\n", has, fdwReset); + + if (fdwReset) { + ret = MMSYSERR_INVALFLAG; + } else if ((was = ACM_GetStream(has)) == NULL) { + return MMSYSERR_INVALHANDLE; + } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) { + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0); + } + TRACE("=> (%d)\n", ret); + return ret; +} + +/*********************************************************************** + * acmStreamSize (MSACM32.43) + */ +MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput, + LPDWORD pdwOutputBytes, DWORD fdwSize) +{ + PWINE_ACMSTREAM was; + ACMDRVSTREAMSIZE adss; + MMRESULT ret; + + TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize); + + if ((was = ACM_GetStream(has)) == NULL) { + return MMSYSERR_INVALHANDLE; + } + if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) { + return MMSYSERR_INVALFLAG; + } + + *pdwOutputBytes = 0L; + + switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) { + case ACM_STREAMSIZEF_DESTINATION: + adss.cbDstLength = cbInput; + adss.cbSrcLength = 0; + break; + case ACM_STREAMSIZEF_SOURCE: + adss.cbSrcLength = cbInput; + adss.cbDstLength = 0; + break; + default: + return MMSYSERR_INVALFLAG; + } + + adss.cbStruct = sizeof(adss); + adss.fdwSize = fdwSize; + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE, + (DWORD)&was->drvInst, (DWORD)&adss); + if (ret == MMSYSERR_NOERROR) { + switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) { + case ACM_STREAMSIZEF_DESTINATION: + *pdwOutputBytes = adss.cbSrcLength; + break; + case ACM_STREAMSIZEF_SOURCE: + *pdwOutputBytes = adss.cbDstLength; + break; + } + } + TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes); + return ret; +} + +/*********************************************************************** + * acmStreamUnprepareHeader (MSACM32.44) + */ +MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, + DWORD fdwUnprepare) +{ + PWINE_ACMSTREAM was; + MMRESULT ret = MMSYSERR_NOERROR; + PACMDRVSTREAMHEADER padsh; + + TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare); + + if ((was = ACM_GetStream(has)) == NULL) + return MMSYSERR_INVALHANDLE; + if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) + return MMSYSERR_INVALPARAM; + + if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) + return ACMERR_UNPREPARED; + + /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same + * size. some fields are private to msacm internals, and are exposed + * in ACMSTREAMHEADER in the dwReservedDriver array + */ + padsh = (PACMDRVSTREAMHEADER)pash; + + /* check that pointers have not been modified */ + if (padsh->pbPreparedSrc != padsh->pbSrc || + padsh->cbPreparedSrcLength < padsh->cbSrcLength || + padsh->pbPreparedDst != padsh->pbDst || + padsh->cbPreparedDstLength < padsh->cbDstLength) { + return MMSYSERR_INVALPARAM; + } + + padsh->fdwConvert = fdwUnprepare; + + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh); + if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) { + ret = MMSYSERR_NOERROR; + padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED); + } + TRACE("=> (%d)\n", ret); + return ret; +} diff --git a/loader/com.h b/loader/com.h new file mode 100644 index 0000000000..fe229cb579 --- /dev/null +++ b/loader/com.h @@ -0,0 +1,66 @@ +/** + * Internal functions and structures for COM emulation code. + */ + +#ifndef COM_H +#define COM_H + +#ifdef __cplusplus +extern "C" { +#endif + +void* CoTaskMemAlloc(unsigned long cb); +void CoTaskMemFree(void* cb); + +typedef struct +{ + long f1; + short f2; + short f3; + char f4[8]; +} GUID; + +extern GUID IID_IUnknown; +extern GUID IID_IClassFactory; + +typedef long (*GETCLASSOBJECT) (GUID* clsid, GUID* iid, void** ppv); +int RegisterComClass(GUID* clsid, GETCLASSOBJECT gcs); + +#ifndef STDCALL +#define STDCALL __attribute__((__stdcall__)) +#endif + +struct IUnknown; +struct IClassFactory; +struct IUnknown_vt +{ + long STDCALL (*QueryInterface)(struct IUnknown* _this, GUID* iid, void** ppv); + long STDCALL (*AddRef)(struct IUnknown* _this) ; + long STDCALL (*Release)(struct IUnknown* _this) ; +} ; +struct IUnknown +{ + struct IUnknown_vt* vt; +}; + +struct IClassFactory_vt +{ + long STDCALL (*QueryInterface)(struct IUnknown* _this, GUID* iid, void** ppv); + long STDCALL (*AddRef)(struct IUnknown* _this) ; + long STDCALL (*Release)(struct IUnknown* _this) ; + long STDCALL (*CreateInstance)(struct IClassFactory* _this, struct IUnknown* pUnkOuter, GUID* riid, void** ppvObject); +}; + +struct IClassFactory +{ + struct IClassFactory_vt* vt; +}; + +long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, + long dwClsContext, GUID* riid, void** ppv); + +#ifdef __cplusplus +}; +#endif + +#endif \ No newline at end of file diff --git a/loader/config.h b/loader/config.h new file mode 100644 index 0000000000..15ff49d602 --- /dev/null +++ b/loader/config.h @@ -0,0 +1,74 @@ + +/* include/config.h. Generated automatically by configure. */ +/* include/config.h.in. Generated automatically from configure.in by autoheader. */ +#define USE_SDL 1 +/* #undef QUIET */ +/* #undef TIMING */ +/* #undef DETAILED_OUT */ +#define MMX 1 +#define HAVE_LIBXXF86DGA 1 +#define HAVE_LIBXXF86VM 1 +#define USE_TSC 1 + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if you have the ftime function. */ +#define HAVE_FTIME 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the dl library (-ldl). */ +#define HAVE_LIBDL 1 + +/* Define if you have the jpeg library (-ljpeg). */ +#define HAVE_LIBJPEG 1 diff --git a/loader/driver.c b/loader/driver.c new file mode 100644 index 0000000000..d682bd295c --- /dev/null +++ b/loader/driver.c @@ -0,0 +1,223 @@ +#include +#include + +#ifdef HAVE_MALLOC_H +#include +#else +#include +#endif + +#include +#include +#include +#include +#include + +//#include "com.h" +//typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**); + + +#ifdef __FreeBSD__ +#include +#endif + + +#define STORE_ALL \ + __asm__ ( \ + "push %%ebx\n\t" \ + "push %%ecx\n\t" \ + "push %%edx\n\t" \ + "push %%esi\n\t" \ + "push %%edi\n\t"::) + +#define REST_ALL \ + __asm__ ( \ + "pop %%edi\n\t" \ + "pop %%esi\n\t" \ + "pop %%edx\n\t" \ + "pop %%ecx\n\t" \ + "pop %%ebx\n\t"::) + + + +typedef struct { + UINT uDriverSignature; + HINSTANCE hDriverModule; + DRIVERPROC DriverProc; + DWORD dwDriverID; +} DRVR; + +typedef DRVR *PDRVR; +typedef DRVR *NPDRVR; +typedef DRVR *LPDRVR; + +static DWORD dwDrvID = 0; + + +LRESULT WINAPI SendDriverMessage( HDRVR hDriver, UINT message, + LPARAM lParam1, LPARAM lParam2 ) +{ + DRVR* module=(DRVR*)hDriver; + int result; +#ifdef DETAILED_OUT + printf("SendDriverMessage: driver %X, message %X, arg1 %X, arg2 %X\n", hDriver, message, lParam1, lParam2); +#endif + if(module==0)return -1; + if(module->hDriverModule==0)return -1; + if(module->DriverProc==0)return -1; + STORE_ALL; + result=module->DriverProc(module->dwDriverID,1,message,lParam1,lParam2); + REST_ALL; +#ifdef DETAILED_OUT + printf("\t\tResult: %X\n", result); +#endif + return result; +} + +static NPDRVR DrvAlloc(HDRVR*lpDriver, LPUINT lpDrvResult) +{ + NPDRVR npDriver; + /* allocate and lock handle */ + if (lpDriver) + { + if ( (*lpDriver = (HDRVR) malloc(sizeof(DRVR))) ) + { + if ((npDriver = (NPDRVR) *lpDriver)) + { + *lpDrvResult = MMSYSERR_NOERROR; + return (npDriver); + } + free((NPDRVR)*lpDriver); + } + return (*lpDrvResult = MMSYSERR_NOMEM, (NPDRVR) 0); + } + return (*lpDrvResult = MMSYSERR_INVALPARAM, (NPDRVR) 0); +} + + +static void DrvFree(HDRVR hDriver) +{ + int i; + if(hDriver) + if(((DRVR*)hDriver)->hDriverModule) + if(((DRVR*)hDriver)->DriverProc) + (((DRVR*)hDriver)->DriverProc)(((DRVR*)hDriver)->dwDriverID, hDriver, DRV_CLOSE, 0, 0); + if(hDriver) { + if(((DRVR*)hDriver)->hDriverModule) + if(((DRVR*)hDriver)->DriverProc) + (((DRVR*)hDriver)->DriverProc)(0, hDriver, DRV_FREE, 0, 0); + FreeLibrary(((DRVR*)hDriver)->hDriverModule); + free((NPDRVR)hDriver); + return; + } +} + +void DrvClose(HDRVR hdrvr) +{ + DrvFree(hdrvr); +} + + +char* def_path=WIN32_PATH; // path to codecs +char* win32_codec_name=NULL; // must be set before calling DrvOpen() !!! + +HDRVR +DrvOpen(LPARAM lParam2) +{ + ICOPEN *icopen=(ICOPEN *) lParam2; + UINT uDrvResult; + HDRVR hDriver; + NPDRVR npDriver; + char unknown[0x24]; +// char* codec_name=icopen->fccHandler; + + if (!(npDriver = DrvAlloc(&hDriver, &uDrvResult))) + return ((HDRVR) 0); + + if (!(npDriver->hDriverModule = expLoadLibraryA(win32_codec_name))) { + printf("Can't open library %s\n", win32_codec_name); + DrvFree(hDriver); + return ((HDRVR) 0); + } + +#if 0 + { + unsigned char *p=((char*)npDriver->hDriverModule); + double *dp; + int i; + p+=0x14c0; + for(i=0;i<16;i++)printf(" %02X",p[i]); printf("\n"); + dp=(double*)p; + printf("divx bitrate = %f\n",(float)(*dp)); +// *(double*)((char*)npDriver->hDriverModule+0x14c0)=bitrate; + } +#endif + + if (!(npDriver->DriverProc = (DRIVERPROC) + GetProcAddress(npDriver->hDriverModule, "DriverProc"))) { +#if 1 + printf("Library %s is not a VfW/ACM valid codec\n", win32_codec_name); +#else + // Try DirectShow... + GETCLASS func=(GETCLASS)GetProcAddress(npDriver->hDriverModule,"DllGetClassObject"); + if(!func) + printf("Library %s is not a valid VfW/ACM/DShow codec\n", win32_codec_name); + else { + HRESULT result; + struct IClassFactory* factory=0; + struct IUnknown* object=0; + GUID CLSID_Voxware={0x73f7a062, 0x8829, 0x11d1, + {0xb5, 0x50, 0x00, 0x60, 0x97, 0x24, 0x2d, 0x8d}}; + GUID* id=&CLSID_Voxware; + + result=func(id, &IID_IClassFactory, (void**)&factory); + if(result || (!factory)) printf("No such class object\n"); + + printf("Calling factory->vt->CreateInstance()\n"); + printf("addr = %X\n",(unsigned int)factory->vt->CreateInstance); + result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); + printf("Calling factory->vt->Release()\n"); + factory->vt->Release((struct IUnknown*)factory); + if(result || (!object)) printf("Class factory failure\n"); + + printf("DirectShow codecs not yet supported...\n"); + } +#endif + + FreeLibrary(npDriver->hDriverModule); + DrvFree(hDriver); + return ((HDRVR) 0); + + } + + //TRACE("DriverProc == %X\n", npDriver->DriverProc); + npDriver->dwDriverID = ++dwDrvID; + + STORE_ALL; + (npDriver->DriverProc)(0, hDriver, DRV_LOAD, 0, 0); + REST_ALL; + //TRACE("DRV_LOAD Ok!\n"); + STORE_ALL; + (npDriver->DriverProc)(0, hDriver, DRV_ENABLE, 0, 0); + REST_ALL; + //TRACE("DRV_ENABLE Ok!\n"); + + // open driver + STORE_ALL; + npDriver->dwDriverID=(npDriver->DriverProc)(npDriver->dwDriverID, hDriver, DRV_OPEN, + (LPARAM) (LPSTR) unknown, lParam2); + REST_ALL; + + //TRACE("DRV_OPEN Ok!(%X)\n", npDriver->dwDriverID); + + if (uDrvResult) + { + DrvFree(hDriver); + hDriver = (HDRVR) 0; + } + + printf("Successfully loaded codec %s\n",win32_codec_name); + + return (hDriver); +} + diff --git a/loader/elfdll.c b/loader/elfdll.c new file mode 100644 index 0000000000..b4cf623995 --- /dev/null +++ b/loader/elfdll.c @@ -0,0 +1,305 @@ +/* + * Elf-dll loader functions + * + * Copyright 1999 Bertho A. Stultiens + */ +#include + +#ifdef HAVE_LIBDL + +#include +#include +#include + +#include +#include +//#include +//#include +#include +#include +#include +#include +#include + +//DEFAULT_DEBUG_CHANNEL(elfdll) + +#include + +struct modref_list_t; + +typedef struct modref_list_t +{ + WINE_MODREF* wm; + struct modref_list_t *next; + struct modref_list_t *prev; +} +modref_list; + + +//WINE_MODREF *local_wm=NULL; +extern modref_list* local_wm; + + +/*------------------ HACKS -----------------*/ +extern DWORD fixup_imports(WINE_MODREF *wm); +extern void dump_exports(HMODULE hModule); +/*---------------- END HACKS ---------------*/ + +//char *extra_ld_library_path = "/usr/lib/win32"; +extern char* def_path; + +struct elfdll_image +{ + HMODULE pe_module_start; + DWORD pe_module_size; +}; + + +/**************************************************************************** + * ELFDLL_dlopen + * + * Wrapper for dlopen to search the EXTRA_LD_LIBRARY_PATH from wine.conf + * manually because libdl.so caches the environment and does not accept our + * changes. + */ +void *ELFDLL_dlopen(const char *libname, int flags) +{ + char buffer[256]; + int namelen; + void *handle; + char *ldpath; + + /* First try the default path search of dlopen() */ + handle = dlopen(libname, flags); + if(handle) + return handle; + + /* Now try to construct searches through our extra search-path */ + namelen = strlen(libname); + ldpath = def_path; + while(ldpath && *ldpath) + { + int len; + char *cptr; + char *from; + + from = ldpath; + cptr = strchr(ldpath, ':'); + if(!cptr) + { + len = strlen(ldpath); + ldpath = NULL; + } + else + { + len = cptr - ldpath; + ldpath = cptr + 1; + } + + if(len + namelen + 1 >= sizeof(buffer)) + { + ERR("Buffer overflow! Check EXTRA_LD_LIBRARY_PATH or increase buffer size.\n"); + return NULL; + } + + strncpy(buffer, from, len); + if(len) + { + buffer[len] = '/'; + strcpy(buffer + len + 1, libname); + } + else + strcpy(buffer + len, libname); + + TRACE("Trying dlopen('%s', %d)\n", buffer, flags); + + handle = dlopen(buffer, flags); + if(handle) + return handle; + } + return NULL; +} + + +/**************************************************************************** + * get_sobasename (internal) + * + */ +static LPSTR get_sobasename(LPCSTR path, LPSTR name) +{ + char *cptr; + + /* Strip the path from the library name */ + if((cptr = strrchr(path, '/'))) + { + char *cp = strrchr(cptr+1, '\\'); + if(cp && cp > cptr) + cptr = cp; + } + else + cptr = strrchr(path, '\\'); + + if(!cptr) + cptr = (char *)path; /* No '/' nor '\\' in path */ + else + cptr++; + + strcpy(name, cptr); + cptr = strrchr(name, '.'); + if(cptr) + *cptr = '\0'; /* Strip extension */ + + /* Convert to lower case. + * This must be done manually because it is not sure that + * other modules are accessible. + */ + for(cptr = name; *cptr; cptr++) + *cptr = tolower(*cptr); + + return name; +} + + +/**************************************************************************** + * ELFDLL_CreateModref (internal) + * + * INPUT + * hModule - the header from the elf-dll's data-segment + * path - requested path from original call + * + * OUTPUT + * A WINE_MODREF pointer to the new object + * + * BUGS + * - Does not handle errors due to dependencies correctly + * - path can be wrong + */ +#define RVA(base, va) (((DWORD)base) + ((DWORD)va)) + +static WINE_MODREF *ELFDLL_CreateModref(HMODULE hModule, LPCSTR path) +{ +// IMAGE_NT_HEADERS *nt = PE_HEADER(hModule); + IMAGE_DATA_DIRECTORY *dir; + IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL; + WINE_MODREF *wm; + int len; + HANDLE procheap = GetProcessHeap(); + + wm = (WINE_MODREF *)HeapAlloc(procheap, HEAP_ZERO_MEMORY, sizeof(*wm)); + if(!wm) + return NULL; + + wm->module = hModule; + wm->type = MODULE32_ELF; /* FIXME */ + +// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT; +// if(dir->Size) +// wm->binfmt.pe.pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(hModule, dir->VirtualAddress); + +// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT; +// if(dir->Size) +// pe_import = wm->binfmt.pe.pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(hModule, dir->VirtualAddress); + +// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE; +// if(dir->Size) +// wm->binfmt.pe.pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(hModule, dir->VirtualAddress); + + + wm->filename = malloc(strlen(path)+1); + strcpy(wm->filename, path); + wm->modname = strrchr( wm->filename, '\\' ); + if (!wm->modname) wm->modname = wm->filename; + else wm->modname++; +/* + len = GetShortPathNameA( wm->filename, NULL, 0 ); + wm->short_filename = (char *)HeapAlloc( procheap, 0, len+1 ); + GetShortPathNameA( wm->filename, wm->short_filename, len+1 ); + wm->short_modname = strrchr( wm->short_filename, '\\' ); + if (!wm->short_modname) wm->short_modname = wm->short_filename; + else wm->short_modname++; +*/ + /* Link MODREF into process list */ + +// EnterCriticalSection( &PROCESS_Current()->crit_section ); + + if(local_wm) + { + local_wm->next=malloc(sizeof(modref_list)); + local_wm->next->prev=local_wm; + local_wm->next->next=NULL; + local_wm->next->wm=wm; + local_wm=local_wm->next; + } + else + { + local_wm=malloc(sizeof(modref_list)); + local_wm->next=local_wm->prev=NULL; + local_wm->wm=wm; + } + +// LeaveCriticalSection( &PROCESS_Current()->crit_section ); + return wm; +} + +/**************************************************************************** + * ELFDLL_LoadLibraryExA (internal) + * + * Implementation of elf-dll loading for PE modules + */ +WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags) +{ + LPVOID dlhandle; + struct elfdll_image *image; + char name[129]; + char soname[129]; + WINE_MODREF *wm; + + get_sobasename(path, name); + strcpy(soname, name); + strcat(soname, ".so"); + + /* Try to open the elf-dll */ + dlhandle = ELFDLL_dlopen(soname, RTLD_LAZY); + if(!dlhandle) + { + WARN("Could not load %s (%s)\n", soname, dlerror()); + SetLastError( ERROR_FILE_NOT_FOUND ); + return NULL; + } + + /* Get the 'dllname_elfdll_image' variable */ +/* strcpy(soname, name); + strcat(soname, "_elfdll_image"); + image = (struct elfdll_image *)dlsym(dlhandle, soname); + if(!image) + { + ERR("Could not get elfdll image descriptor %s (%s)\n", soname, dlerror()); + dlclose(dlhandle); + SetLastError( ERROR_BAD_FORMAT ); + return NULL; + } + +*/ + wm = ELFDLL_CreateModref((int)dlhandle, path); + if(!wm) + { + ERR("Could not create WINE_MODREF for %s\n", path); + dlclose(dlhandle); + SetLastError( ERROR_OUTOFMEMORY ); + return NULL; + } + + return wm; +} + + +/**************************************************************************** + * ELFDLL_UnloadLibrary (internal) + * + * Unload an elf-dll completely from memory and deallocate the modref + */ +void ELFDLL_UnloadLibrary(WINE_MODREF *wm) +{ +} + +#endif /*HAVE_LIBDL*/ diff --git a/loader/ext.c b/loader/ext.c new file mode 100644 index 0000000000..e978fac0c4 --- /dev/null +++ b/loader/ext.c @@ -0,0 +1,565 @@ +/******************************************************** + * + * + * Stub functions for Wine module + * + * + ********************************************************/ +#include +#ifdef HAVE_MALLOC_H +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +//#include +int dbg_header_err( const char *dbg_channel, const char *func ) +{ + return 0; +} +int dbg_header_warn( const char *dbg_channel, const char *func ) +{ + return 0; +} +int dbg_header_fixme( const char *dbg_channel, const char *func ) +{ + return 0; +} +int dbg_header_trace( const char *dbg_channel, const char *func ) +{ + return 0; +} +int dbg_vprintf( const char *format, ... ) +{ + return 0; +} +int __vprintf( const char *format, ... ) +{ +#ifdef DETAILED_OUT + va_list va; + va_start(va, format); + vprintf(format, va); + va_end(va); + fflush(stdout); +#endif + return 0; +} + +int GetProcessHeap() +{ + return 1; +} + +void* HeapAlloc(int heap, int flags, int size) +{ + if(flags & 0x8) + return calloc(size, 1); + else + return malloc(size); +} + +int HeapFree(int heap, int flags, void* mem) +{ + free(mem); + return 1; +} + +static int last_error; + +int GetLastError() +{ + return last_error; +} + +int SetLastError(int error) +{ + return last_error=error; +} + +int ReadFile(int handle, void* mem, unsigned long size, long* result, long flags) +{ + *result=read(handle, mem, size); + return *result; +} +int lstrcmpiA(const char* c1, const char* c2) +{ + return strcasecmp(c1,c2); +} +int lstrcpynA(char* dest, const char* src, int num) +{ + return strncmp(dest,src,num); +} +int lstrlenA(const char* s) +{ + return strlen(s); +} +int lstrlenW(const short* s) +{ + int l; + if(!s) + return 0; + l=0; + while(s[l]) + l++; + return l; +} +int lstrcpynWtoA(char* dest, const char* src, int count) +{ + int moved=0; + if((dest==0) || (src==0)) + return 0; + while(moved0) + { + if(*s1<*s2) + return -1; + else + if(*s1>*s2) + return 1; + else + if(*s1==0) + return 0; + s1++; + s2++; + n--; + } + return 0; +} + + +int IsBadReadPtr(void* data, int size) +{ + if(size==0) + return 0; + if(data==NULL) + return 1; + return 0; +} +char* HEAP_strdupA(const char* string) +{ +// return strdup(string); + char* answ=malloc(strlen(string)+1); + strcpy(answ, string); + return answ; +} +short* HEAP_strdupAtoW(void* heap, void* hz, const char* string) +{ + int size, i; + short* answer; + if(string==0) + return 0; + size=strlen(string); + answer=malloc(size+size+2); + for(i=0; i<=size; i++) + answer[i]=(short)string[i]; + return answer; +} +char* HEAP_strdupWtoA(void* heap, void* hz, const short* string) +{ + int size, i; + char* answer; + if(string==0) + return 0; + size=0; + while(string[size]) + size++; + answer=malloc(size+2); + for(i=0; i<=size; i++) + answer[i]=(char)string[i]; + return answer; +} + +/*********************************************************************** + * FILE_dommap + */ + +//#define MAP_PRIVATE +//#define MAP_SHARED +#undef MAP_ANON +LPVOID FILE_dommap( int unix_handle, LPVOID start, + DWORD size_high, DWORD size_low, + DWORD offset_high, DWORD offset_low, + int prot, int flags ) +{ + int fd = -1; + int pos; + LPVOID ret; + + if (size_high || offset_high) + printf("offsets larger than 4Gb not supported\n"); + + if (unix_handle == -1) + { +#ifdef MAP_ANON +// printf("Anonymous\n"); + flags |= MAP_ANON; +#else + static int fdzero = -1; + + if (fdzero == -1) + { + if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1) + { + perror( "/dev/zero: open" ); + exit(1); + } + } + fd = fdzero; +#endif /* MAP_ANON */ + /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */ +#ifdef MAP_SHARED + flags &= ~MAP_SHARED; +#endif +#ifdef MAP_PRIVATE + flags |= MAP_PRIVATE; +#endif + } + else fd = unix_handle; +// printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot); +// if ((ret = mmap( start, size_low, prot, +// flags, fd, offset_low )) != (LPVOID)-1) + if ((ret = mmap( start, size_low, prot, + MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1) + { +// printf("address %08x\n", *(int*)ret); +// printf("%x\n", ret); + return ret; + } + +// printf("mmap %d\n", errno); + + /* mmap() failed; if this is because the file offset is not */ + /* page-aligned (EINVAL), or because the underlying filesystem */ + /* does not support mmap() (ENOEXEC), we do it by hand. */ + + if (unix_handle == -1) return ret; + if ((errno != ENOEXEC) && (errno != EINVAL)) return ret; + if (prot & PROT_WRITE) + { + /* We cannot fake shared write mappings */ +#ifdef MAP_SHARED + if (flags & MAP_SHARED) return ret; +#endif +#ifdef MAP_PRIVATE + if (!(flags & MAP_PRIVATE)) return ret; +#endif + } +/* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/ + /* Reserve the memory with an anonymous mmap */ + ret = FILE_dommap( -1, start, size_high, size_low, 0, 0, + PROT_READ | PROT_WRITE, flags ); + if (ret == (LPVOID)-1) +// { +// perror( + return ret; + /* Now read in the file */ + if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1) + { + FILE_munmap( ret, size_high, size_low ); +// printf("lseek\n"); + return (LPVOID)-1; + } + read( fd, ret, size_low ); + lseek( fd, pos, SEEK_SET ); /* Restore the file pointer */ + mprotect( ret, size_low, prot ); /* Set the right protection */ +// printf("address %08x\n", *(int*)ret); + return ret; +} + + +/*********************************************************************** + * FILE_munmap + */ +int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low ) +{ + if (size_high) + printf("offsets larger than 4Gb not supported\n"); + return munmap( start, size_low ); +} +static int mapping_size=0; + +struct file_mapping_s; +typedef struct file_mapping_s +{ + int mapping_size; + char* name; + HANDLE handle; + struct file_mapping_s* next; + struct file_mapping_s* prev; +}file_mapping; +static file_mapping* fm=0; + + + +#define PAGE_NOACCESS 0x01 +#define PAGE_READONLY 0x02 +#define PAGE_READWRITE 0x04 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 + +HANDLE CreateFileMappingA(int hFile, void* lpAttr, +DWORD flProtect, DWORD dwMaxHigh, DWORD dwMaxLow, const char* name) +{ + unsigned int len; + HANDLE answer; + int anon=0; + int mmap_access=0; + if(hFile<0) + { + anon=1; + hFile=open("/dev/zero", O_RDWR); + if(hFile<0) + return 0; + } + if(!anon) + { + len=lseek(hFile, 0, SEEK_END); + lseek(hFile, 0, SEEK_SET); + } + else len=dwMaxLow; + + if(flProtect & PAGE_READONLY) + mmap_access |=PROT_READ; + else + mmap_access |=PROT_READ|PROT_WRITE; + + answer=(HANDLE)mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0); + if(anon) + close(hFile); + if(answer!=(HANDLE)-1) + { + if(fm==0) + { + fm=malloc(sizeof(file_mapping)); + fm->prev=NULL; + } + else + { + fm->next=malloc(sizeof(file_mapping)); + fm->next->prev=fm; + fm=fm->next; + } + fm->next=NULL; + fm->handle=answer; + if(name) + { + fm->name=malloc(strlen(name)+1); + strcpy(fm->name, name); + } + else + fm->name=NULL; + fm->mapping_size=len; + + if(anon) + close(hFile); + return answer; + } + return (HANDLE)0; +} +int UnmapViewOfFile(HANDLE handle) +{ + file_mapping* p; + int result; + if(fm==0) + return (HANDLE)0; + for(p=fm; p; p=p->next) + { + if(p->handle==handle) + { + result=munmap((void*)handle, p->mapping_size); + if(p->next)p->next->prev=p->prev; + if(p->prev)p->prev->next=p->next; + if(p->name) + free(p->name); + if(p==fm) + fm=p->prev; + free(p); + return result; + } + } + return 0; +} +//static int va_size=0; +struct virt_alloc_s; +typedef struct virt_alloc_s +{ + int mapping_size; + char* address; + struct virt_alloc_s* next; + struct virt_alloc_s* prev; + int state; +}virt_alloc; +static virt_alloc* vm=0; +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 + +void* VirtualAlloc(void* address, DWORD size, DWORD type, DWORD protection) +{ + void* answer; + int fd=open("/dev/zero", O_RDWR); + size=(size+0xffff)&(~0xffff); +// printf("VirtualAlloc(0x%08X, %d)\n", address + if(address!=0) + { + //check whether we can allow to allocate this + virt_alloc* str=vm; + while(str) + { + if((unsigned)address>=(unsigned)str->address+str->mapping_size) + { + str=str->prev; + continue; + } + if((unsigned)address+size<(unsigned)str->address) + { + str=str->prev; + continue; + } + if(str->state==0) + { +#warning FIXME + if(((unsigned)address+size<(unsigned)str->address+str->mapping_size) && (type & MEM_COMMIT)) + { + close(fd); + return address; //returning previously reserved memory + } + return NULL; + } + close(fd); + return NULL; + } + answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_FIXED | MAP_PRIVATE, fd, 0); + } + else + answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE, fd, 0); +// answer=FILE_dommap(-1, address, 0, size, 0, 0, +// PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); + close(fd); + if(answer==(void*)-1) + { + printf("Error no %d\n", errno); + printf("VirtualAlloc(0x%08X, %d) failed\n", address, size); + return NULL; + } + else + { + virt_alloc *new_vm=malloc(sizeof(virt_alloc)); + new_vm->mapping_size=size; + new_vm->address=answer; + new_vm->prev=vm; + if(type == MEM_RESERVE) + new_vm->state=0; + else + new_vm->state=1; + if(vm) + vm->next=new_vm; + vm=new_vm; + vm->next=0; +// if(va_size!=0) +// printf("Multiple VirtualAlloc!\n"); +// printf("answer=0x%08x\n", answer); + return answer; + } +} +int VirtualFree(void* address, int t1, int t2)//not sure +{ + virt_alloc* str=vm; + int answer; + while(str) + { + if(address!=str->address) + { + str=str->prev; + continue; + } + answer=munmap(str->address, str->mapping_size); + if(str->next)str->next->prev=str->prev; + if(str->prev)str->prev->next=str->next; + if(vm==str)vm=0; + free(str); + return 0; + } + return -1; +} + +int WideCharToMultiByte(unsigned int codepage, long flags, const short* src, + int srclen,char* dest, int destlen, const char* defch, int* used_defch) +{ + int i; + if(src==0) + return 0; + for(i=0; iprev) + { + if(p->name==0) + continue; + if(strcmp(p->name, name)==0) + return p->handle; + } + return 0; +} diff --git a/loader/loader.h b/loader/loader.h new file mode 100644 index 0000000000..f94fe0044d --- /dev/null +++ b/loader/loader.h @@ -0,0 +1,286 @@ +/******************************************************** + + Win32 binary loader interface + Copyright 2000 Eugene Smith (divx@euro.ru) + Shamelessly stolen from Wine project + +*********************************************************/ + +#ifndef _LOADER_H +#define _LOADER_H +#include +#include +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +void SetCodecPath(const char* path); +unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, int default_value, const char* filename); +int _GetPrivateProfileStringA(const char* appname, const char* keyname, + const char* def_val, char* dest, unsigned int len, const char* filename); +int _WritePrivateProfileStringA(const char* appname, const char* keyname, + const char* string, const char* filename); + + +/********************************************** + + MS VFW ( Video For Windows ) interface + +**********************************************/ + +long VFWAPIV ICCompress( + HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData, + LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid, + long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality, + LPBITMAPINFOHEADER lpbiPrev,void* lpPrev +); + +long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits); + +WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo); +LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb); +HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode); +HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler); + +LRESULT VFWAPI ICClose(HIC hic); +LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2); +HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags); + +int VFWAPI ICDoSomething(); + +#define ICCompressGetFormat(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic,ICM_COMPRESS_GET_FORMAT,(long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICCompressGetFormatSize(hic,lpbi) ICCompressGetFormat(hic,lpbi,NULL) + +#define ICGetDefaultKeyFrameRate(hic,lpint) \ + ICSendMessage( \ + hic, ICM_GETDEFAULTKEYFRAMERATE, \ + (long)(void*)(lpint), \ + 0 ) + +#define ICGetDefaultQuality(hic,lpint) \ + ICSendMessage( \ + hic, ICM_GETDEFAULTQUALITY, \ + (long)(void*)(lpint), \ + 0 ) + + +#define ICCompressBegin(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_COMPRESS_BEGIN, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICCompressGetSize(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_COMPRESS_GET_SIZE, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICCompressQuery(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_COMPRESS_QUERY, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + + +#define ICCompressEnd(hic) ICSendMessage(hic, ICM_COMPRESS_END, 0, 0) + + + +#define ICDecompressBegin(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_DECOMPRESS_BEGIN, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICDecompressQuery(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic,ICM_DECOMPRESS_QUERY, (long)(void*)(lpbiInput), \ + (long) (void*)(lpbiOutput) \ + ) + +#define ICDecompressGetFormat(hic, lpbiInput, lpbiOutput) \ + ((long)ICSendMessage( \ + hic,ICM_DECOMPRESS_GET_FORMAT, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + )) + +#define ICDecompressGetFormatSize(hic, lpbi) \ + ICDecompressGetFormat(hic, lpbi, NULL) + +#define ICDecompressGetPalette(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_DECOMPRESS_GET_PALETTE, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICDecompressSetPalette(hic,lpbiPalette) \ + ICSendMessage( \ + hic,ICM_DECOMPRESS_SET_PALETTE, \ + (long)(void*)(lpbiPalette),0 \ + ) + +#define ICDecompressEnd(hic) ICSendMessage(hic, ICM_DECOMPRESS_END, 0, 0) + + +/***************************************************** + + MS ACM ( Audio Compression Manager ) interface + +******************************************************/ + + +MMRESULT WINAPI acmDriverAddA( + PHACMDRIVERID phadid, HINSTANCE hinstModule, + LPARAM lParam, DWORD dwPriority, DWORD fdwAdd +); +MMRESULT WINAPI acmDriverAddW( + PHACMDRIVERID phadid, HINSTANCE hinstModule, + LPARAM lParam, DWORD dwPriority, DWORD fdwAdd +); +MMRESULT WINAPI acmDriverClose( + HACMDRIVER had, DWORD fdwClose +); +MMRESULT WINAPI acmDriverDetailsA( + HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails +); +MMRESULT WINAPI acmDriverDetailsW( + HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails +); +MMRESULT WINAPI acmDriverEnum( + ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmDriverID( + HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID +); +LRESULT WINAPI acmDriverMessage( + HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2 +); +MMRESULT WINAPI acmDriverOpen( + PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen +); +MMRESULT WINAPI acmDriverPriority( + HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority +); +MMRESULT WINAPI acmDriverRemove( + HACMDRIVERID hadid, DWORD fdwRemove +); +MMRESULT WINAPI acmFilterChooseA( + PACMFILTERCHOOSEA pafltrc +); +MMRESULT WINAPI acmFilterChooseW( + PACMFILTERCHOOSEW pafltrc +); +MMRESULT WINAPI acmFilterDetailsA( + HACMDRIVER had, PACMFILTERDETAILSA pafd, DWORD fdwDetails +); +MMRESULT WINAPI acmFilterDetailsW( + HACMDRIVER had, PACMFILTERDETAILSW pafd, DWORD fdwDetails +); +MMRESULT WINAPI acmFilterEnumA( + HACMDRIVER had, PACMFILTERDETAILSA pafd, + ACMFILTERENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmFilterEnumW( + HACMDRIVER had, PACMFILTERDETAILSW pafd, + ACMFILTERENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRE