- Partially sync winmm

- Remove unused code
- Fix function headers

svn path=/trunk/; revision=43747
This commit is contained in:
Johannes Anderwald 2009-10-25 17:54:50 +00:00
parent 8fd3137277
commit acd8b06824
18 changed files with 1249 additions and 8738 deletions

View file

@ -5,8 +5,6 @@
* Copyright 1998 Marcus Meissner
* Copyright 1999 Eric Pouech
*
* Reformatting and additional comments added by Andrew Greenwood.
*
* 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
@ -19,9 +17,12 @@
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <string.h>
#include <stdarg.h>
#include "windef.h"
@ -34,17 +35,41 @@
#include "winemm.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "excpt.h"
#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(driver);
static CRITICAL_SECTION mmdriver_lock;
static CRITICAL_SECTION_DEBUG mmdriver_lock_debug =
{
0, 0, &mmdriver_lock,
{ &mmdriver_lock_debug.ProcessLocksList, &mmdriver_lock_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": mmdriver_lock") }
};
static CRITICAL_SECTION mmdriver_lock = { &mmdriver_lock_debug, -1, 0, 0, 0, 0 };
static LPWINE_DRIVER lpDrvItemList /* = NULL */;
static const WCHAR HKLM_BASE[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s',' ','N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
WINE_MMTHREAD* (*pFnGetMMThread16)(UINT16 h) /* = NULL */;
LPWINE_DRIVER (*pFnOpenDriver16)(LPCWSTR,LPCWSTR,LPARAM) /* = NULL */;
LRESULT (*pFnCloseDriver16)(UINT16,LPARAM,LPARAM) /* = NULL */;
LRESULT (*pFnSendMessage16)(UINT16,UINT,LPARAM,LPARAM) /* = NULL */;
static void DRIVER_Dump(const char *comment)
{
#if 0
LPWINE_DRIVER lpDrv;
TRACE("%s\n", comment);
EnterCriticalSection( &mmdriver_lock );
for (lpDrv = lpDrvItemList; lpDrv != NULL; lpDrv = lpDrv->lpNextItem)
{
TRACE("%p, magic %04lx, id %p, next %p\n", lpDrv, lpDrv->dwMagic, lpDrv->d.d32.dwDriverID, lpDrv->lpNextItem);
}
LeaveCriticalSection( &mmdriver_lock );
#endif
}
/**************************************************************************
* DRIVER_GetNumberOfModuleRefs [internal]
@ -56,15 +81,19 @@ static unsigned DRIVER_GetNumberOfModuleRefs(HMODULE hModule, WINE_DRIVER** foun
LPWINE_DRIVER lpDrv;
unsigned count = 0;
EnterCriticalSection( &mmdriver_lock );
if (found) *found = NULL;
for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem)
{
if (!(lpDrv->dwFlags & WINE_GDF_16BIT) && lpDrv->d.d32.hModule == hModule)
if (lpDrv->hModule == hModule)
{
if (found && !*found) *found = lpDrv;
count++;
}
}
LeaveCriticalSection( &mmdriver_lock );
return count;
}
@ -75,34 +104,39 @@ static unsigned DRIVER_GetNumberOfModuleRefs(HMODULE hModule, WINE_DRIVER** foun
*/
LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr)
{
LPWINE_DRIVER d = (LPWINE_DRIVER)hDrvr;
LPWINE_DRIVER d;
if (hDrvr && HeapValidate(GetProcessHeap(), 0, d) && d->dwMagic == WINE_DI_MAGIC) {
return d;
__TRY
{
d = (LPWINE_DRIVER)hDrvr;
if (d && d->dwMagic != WINE_DI_MAGIC) d = NULL;
}
return NULL;
__EXCEPT_PAGE_FAULT
{
return NULL;
}
__ENDTRY;
if (d) TRACE("%p -> %p, %p\n", hDrvr, d->lpDrvProc, (void *)d->dwDriverID);
else TRACE("%p -> NULL\n", hDrvr);
return d;
}
/**************************************************************************
* DRIVER_SendMessage [internal]
*/
static LRESULT inline DRIVER_SendMessage(LPWINE_DRIVER lpDrv, UINT msg,
static inline LRESULT DRIVER_SendMessage(LPWINE_DRIVER lpDrv, UINT msg,
LPARAM lParam1, LPARAM lParam2)
{
LRESULT ret = 0;
if (lpDrv->dwFlags & WINE_GDF_16BIT) {
/* no need to check mmsystem presence: the driver must have been opened as a 16 bit one,
*/
if (pFnSendMessage16)
ret = pFnSendMessage16(lpDrv->d.d16.hDriver16, msg, lParam1, lParam2);
} else {
TRACE("Before call32 proc=%p drvrID=%08lx hDrv=%p wMsg=%04x p1=%08lx p2=%08lx\n",
lpDrv->d.d32.lpDrvProc, lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
ret = lpDrv->d.d32.lpDrvProc(lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
TRACE("After call32 proc=%p drvrID=%08lx hDrv=%p wMsg=%04x p1=%08lx p2=%08lx => %08lx\n",
lpDrv->d.d32.lpDrvProc, lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2, ret);
}
TRACE("Before call32 proc=%p drvrID=%08lx hDrv=%p wMsg=%04x p1=%08lx p2=%08lx\n",
lpDrv->lpDrvProc, lpDrv->dwDriverID, lpDrv, msg, lParam1, lParam2);
ret = lpDrv->lpDrvProc(lpDrv->dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
TRACE("After call32 proc=%p drvrID=%08lx hDrv=%p wMsg=%04x p1=%08lx p2=%08lx => %08lx\n",
lpDrv->lpDrvProc, lpDrv->dwDriverID, lpDrv, msg, lParam1, lParam2, ret);
return ret;
}
@ -136,14 +170,14 @@ LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT msg, LPARAM lParam1,
*/
static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
{
if (!(lpDrv->dwFlags & WINE_GDF_16BIT)) {
/* last of this driver in list ? */
if (DRIVER_GetNumberOfModuleRefs(lpDrv->d.d32.hModule, NULL) == 1) {
DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L);
DRIVER_SendMessage(lpDrv, DRV_FREE, 0L, 0L);
}
/* last of this driver in list ? */
if (DRIVER_GetNumberOfModuleRefs(lpDrv->hModule, NULL) == 1) {
DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L);
DRIVER_SendMessage(lpDrv, DRV_FREE, 0L, 0L);
}
EnterCriticalSection( &mmdriver_lock );
if (lpDrv->lpPrevItem)
lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem;
else
@ -152,6 +186,10 @@ static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem;
/* trash magic number */
lpDrv->dwMagic ^= 0xa5a5a5a5;
lpDrv->lpDrvProc = NULL;
lpDrv->dwDriverID = 0;
LeaveCriticalSection( &mmdriver_lock );
return TRUE;
}
@ -166,18 +204,27 @@ static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam1, LPARAM lPar
{
lpNewDrv->dwMagic = WINE_DI_MAGIC;
/* First driver to be loaded for this module, need to load correctly the module */
if (!(lpNewDrv->dwFlags & WINE_GDF_16BIT)) {
/* first of this driver in list ? */
if (DRIVER_GetNumberOfModuleRefs(lpNewDrv->d.d32.hModule, NULL) == 0) {
if (DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
TRACE("DRV_LOAD failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
return FALSE;
}
/* returned value is not checked */
DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L);
}
/* first of this driver in list ? */
if (DRIVER_GetNumberOfModuleRefs(lpNewDrv->hModule, NULL) == 0) {
if (DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
TRACE("DRV_LOAD failed on driver %p\n", lpNewDrv);
return FALSE;
}
/* returned value is not checked */
DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L);
}
/* Now just open a new instance of a driver on this module */
lpNewDrv->dwDriverID = DRIVER_SendMessage(lpNewDrv, DRV_OPEN, lParam1, lParam2);
if (lpNewDrv->dwDriverID == 0)
{
TRACE("DRV_OPEN failed on driver %p\n", lpNewDrv);
return FALSE;
}
EnterCriticalSection( &mmdriver_lock );
lpNewDrv->lpNextItem = NULL;
if (lpDrvItemList == NULL) {
lpDrvItemList = lpNewDrv;
@ -191,16 +238,7 @@ static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam1, LPARAM lPar
lpNewDrv->lpPrevItem = lpDrv;
}
if (!(lpNewDrv->dwFlags & WINE_GDF_16BIT)) {
/* Now just open a new instance of a driver on this module */
lpNewDrv->d.d32.dwDriverID = DRIVER_SendMessage(lpNewDrv, DRV_OPEN, lParam1, lParam2);
if (lpNewDrv->d.d32.dwDriverID == 0) {
TRACE("DRV_OPEN failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
DRIVER_RemoveFromList(lpNewDrv);
return FALSE;
}
}
LeaveCriticalSection( &mmdriver_lock );
return TRUE;
}
@ -282,23 +320,23 @@ LPWINE_DRIVER DRIVER_TryOpenDriver32(LPCWSTR fn, LPARAM lParam2)
goto exit;
}
lpDrv->d.d32.lpDrvProc = (DRIVERPROC)GetProcAddress(hModule, "DriverProc");
lpDrv->lpDrvProc = (DRIVERPROC)GetProcAddress(hModule, "DriverProc");
if (lpDrv->d.d32.lpDrvProc == NULL)
if (lpDrv->lpDrvProc == NULL)
{
cause = "no DriverProc";
goto exit;
}
lpDrv->dwFlags = 0;
lpDrv->d.d32.hModule = hModule;
lpDrv->d.d32.dwDriverID = 0;
lpDrv->hModule = hModule;
lpDrv->dwDriverID = 0;
/* Win32 installable drivers must support a two phase opening scheme:
* + first open with NULL as lParam2 (session instance),
* + then do a second open with the real non null lParam2)
*/
if (DRIVER_GetNumberOfModuleRefs(lpDrv->d.d32.hModule, NULL) == 0 && lParam2)
if (DRIVER_GetNumberOfModuleRefs(lpDrv->hModule, NULL) == 0 && lParam2)
{
LPWINE_DRIVER ret;
@ -416,6 +454,7 @@ HDRVR WINAPI OpenDriver(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lPar
* so ensure, we can load our mmsystem, otherwise just fail
*/
WINMM_CheckForMMSystem();
#if 0
if (pFnOpenDriver16 &&
(lpDrv = pFnOpenDriver16(lpDriverName, lpSectionName, lParam)))
{
@ -424,6 +463,7 @@ HDRVR WINAPI OpenDriver(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lPar
}
TRACE("Failed to open driver %s from system.ini file, section %s\n",
debugstr_w(lpDriverName), debugstr_w(lpSectionName));
#endif
return 0;
the_end:
@ -437,44 +477,46 @@ HDRVR WINAPI OpenDriver(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lPar
*/
LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
{
BOOL ret;
LPWINE_DRIVER lpDrv;
TRACE("(%p, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
DRIVER_Dump("BEFORE:");
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL)
{
if (lpDrv->dwFlags & WINE_GDF_16BIT)
{
if (pFnCloseDriver16)
pFnCloseDriver16(lpDrv->d.d16.hDriver16, lParam1, lParam2);
}
else
{
DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2);
lpDrv->d.d32.dwDriverID = 0;
}
if (DRIVER_RemoveFromList(lpDrv)) {
if (!(lpDrv->dwFlags & WINE_GDF_16BIT))
{
LPWINE_DRIVER lpDrv0;
LPWINE_DRIVER lpDrv0;
/* if driver has an opened session instance, we have to close it too */
if (DRIVER_GetNumberOfModuleRefs(lpDrv->d.d32.hModule, &lpDrv0) == 1)
{
DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0L, 0L);
lpDrv0->d.d32.dwDriverID = 0;
DRIVER_RemoveFromList(lpDrv0);
FreeLibrary(lpDrv0->d.d32.hModule);
HeapFree(GetProcessHeap(), 0, lpDrv0);
}
FreeLibrary(lpDrv->d.d32.hModule);
}
HeapFree(GetProcessHeap(), 0, lpDrv);
return TRUE;
DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2);
DRIVER_RemoveFromList(lpDrv);
if (lpDrv->dwFlags & WINE_GDF_SESSION)
FIXME("WINE_GDF_SESSION: Shouldn't happen (%p)\n", lpDrv);
/* if driver has an opened session instance, we have to close it too */
if (DRIVER_GetNumberOfModuleRefs(lpDrv->hModule, &lpDrv0) == 1 &&
(lpDrv0->dwFlags & WINE_GDF_SESSION))
{
DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0, 0);
DRIVER_RemoveFromList(lpDrv0);
FreeLibrary(lpDrv0->hModule);
HeapFree(GetProcessHeap(), 0, lpDrv0);
}
FreeLibrary(lpDrv->hModule);
HeapFree(GetProcessHeap(), 0, lpDrv);
ret = TRUE;
}
WARN("Failed to close driver\n");
return FALSE;
else
{
WARN("Failed to close driver\n");
ret = FALSE;
}
DRIVER_Dump("AFTER:");
return ret;
}
/**************************************************************************
@ -498,7 +540,7 @@ DWORD WINAPI GetDriverFlags(HDRVR hDrvr)
TRACE("(%p)\n", hDrvr);
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
ret = WINE_GDF_EXIST | lpDrv->dwFlags;
ret = WINE_GDF_EXIST | (lpDrv->dwFlags & WINE_GDF_EXTERNAL_MASK);
}
return ret;
}
@ -515,8 +557,7 @@ HMODULE WINAPI GetDriverModuleHandle(HDRVR hDrvr)
TRACE("(%p);\n", hDrvr);
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
if (!(lpDrv->dwFlags & WINE_GDF_16BIT))
hModule = lpDrv->d.d32.hModule;
hModule = lpDrv->hModule;
}
TRACE("=> %p\n", hModule);
return hModule;
@ -546,11 +587,11 @@ LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv,
/**************************************************************************
* DriverCallback [WINMM.@]
*/
BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
UINT wMsg, DWORD dwUser, DWORD dwParam1,
DWORD dwParam2)
BOOL WINAPI DriverCallback(DWORD_PTR dwCallBack, DWORD uFlags, HDRVR hDev,
DWORD wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1,
DWORD_PTR dwParam2)
{
TRACE("(%08lX, %04X, %p, %04X, %08lX, %08lX, %08lX); !\n",
TRACE("(%08lX, %04X, %p, %04X, %08lX, %08lX, %08lX)\n",
dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
switch (uFlags & DCB_TYPEMASK) {
@ -575,6 +616,10 @@ BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
TRACE("Event(%08lx) !\n", dwCallBack);
SetEvent((HANDLE)dwCallBack);
break;
#if 0
/* FIXME: for now only usable in mmsystem.dll16
* If needed, should be enabled back
*/
case 6: /* I would dub it DCB_MMTHREADSIGNAL */
/* this is an undocumented DCB_ value used for mmThreads
* loword of dwCallBack contains the handle of the lpMMThd block
@ -586,11 +631,12 @@ BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
TRACE("mmThread (%04x, %p) !\n", LOWORD(dwCallBack), lpMMThd);
/* same as mmThreadSignal16 */
InterlockedIncrement((PLONG)&lpMMThd->dwSignalCount);
InterlockedIncrement(&lpMMThd->dwSignalCount);
SetEvent(lpMMThd->hEvent);
/* some other stuff on lpMMThd->hVxD */
}
break;
#endif
#if 0
case 4:
/* this is an undocumented DCB_ value for... I don't know */
@ -615,11 +661,25 @@ void DRIVER_UnloadAll(void)
LPWINE_DRIVER lpNextDrv = NULL;
unsigned count = 0;
restart:
EnterCriticalSection( &mmdriver_lock );
for (lpDrv = lpDrvItemList; lpDrv != NULL; lpDrv = lpNextDrv)
{
lpNextDrv = lpDrv->lpNextItem;
CloseDriver((HDRVR)lpDrv, 0, 0);
count++;
/* session instances will be unloaded automatically */
if (!(lpDrv->dwFlags & WINE_GDF_SESSION))
{
LeaveCriticalSection( &mmdriver_lock );
CloseDriver((HDRVR)lpDrv, 0, 0);
count++;
/* restart from the beginning of the list */
goto restart;
}
}
LeaveCriticalSection( &mmdriver_lock );
TRACE("Unloaded %u drivers\n", count);
}

View file

@ -18,7 +18,7 @@
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -35,13 +35,13 @@
#include <sys/ioctl.h>
#endif
#include "winemm.h"
#include "windef.h"
#include "winbase.h"
#include "mmsystem.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "winemm.h"
#include "mmddk.h"
@ -49,7 +49,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
#define MAXJOYSTICK (JOYSTICKID2 + 1)
#define MAXJOYSTICK (JOYSTICKID2 + 30)
#define JOY_PERIOD_MIN (10) /* min Capture time period */
#define JOY_PERIOD_MAX (1000) /* max Capture time period */
@ -74,14 +74,14 @@ static BOOL JOY_LoadDriver(DWORD dwJoyID)
if (JOY_Sticks[dwJoyID].hDriver)
return TRUE;
JOY_Sticks[dwJoyID].hDriver = OpenDriverA("joystick.drv", 0, dwJoyID);
JOY_Sticks[dwJoyID].hDriver = OpenDriverA("winejoystick.drv", 0, dwJoyID);
return (JOY_Sticks[dwJoyID].hDriver != 0);
}
/**************************************************************************
* JOY_Timer [internal]
*/
static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT wTimer, DWORD dwTime)
static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTime)
{
int i;
WINE_JOYSTICK* joy;
@ -121,6 +121,19 @@ static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT wTimer, DWORD dwTime)
}
}
/**************************************************************************
* joyConfigChanged [WINMM.@]
*/
MMRESULT WINAPI joyConfigChanged(DWORD flags)
{
FIXME("(%x) - stub\n", flags);
if (flags)
return JOYERR_PARMS;
return JOYERR_NOERROR;
}
/**************************************************************************
* joyGetNumDevs [WINMM.@]
*/
@ -131,7 +144,7 @@ UINT WINAPI joyGetNumDevs(void)
for (i = 0; i < MAXJOYSTICK; i++) {
if (JOY_LoadDriver(i)) {
ret += SendDriverMessage(JOY_Sticks[i].hDriver, JDD_GETNUMDEVS, 0L, 0L);
ret += SendDriverMessage(JOY_Sticks[i].hDriver, JDD_GETNUMDEVS, 0, 0);
}
}
return ret;
@ -148,7 +161,7 @@ MMRESULT WINAPI joyGetDevCapsW(UINT_PTR wID, LPJOYCAPSW lpCaps, UINT wSize)
lpCaps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */
lpCaps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETDEVCAPS, (DWORD)lpCaps, wSize);
return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETDEVCAPS, (LPARAM)lpCaps, wSize);
}
/**************************************************************************
@ -222,7 +235,7 @@ MMRESULT WINAPI joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo)
lpInfo->dwReserved1 = 0;
lpInfo->dwReserved2 = 0;
return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOSEX, (DWORD)lpInfo, 0L);
return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOSEX, (LPARAM)lpInfo, 0);
}
/**************************************************************************
@ -240,7 +253,7 @@ MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo)
lpInfo->wZpos = 0;
lpInfo->wButtons = 0;
return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOS, (DWORD)lpInfo, 0L);
return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOS, (LPARAM)lpInfo, 0);
}
/**************************************************************************

View file

@ -1,7 +1,7 @@
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*
* MMSYTEM low level drivers handling functions
* MMSYSTEM low level drivers handling functions
*
* Copyright 1999 Eric Pouech
* Modified for use with ReactOS by Andrew Greenwood, 2007
@ -18,9 +18,12 @@
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
@ -28,27 +31,19 @@
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winver.h"
#include "winemm.h"
#include "wine/debug.h"
#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
LRESULT (*pFnCallMMDrvFunc16)(DWORD,WORD,WORD,LONG,LONG,LONG) /* = NULL */;
unsigned (*pFnLoadMMDrvFunc16)(LPCSTR,LPWINE_DRIVER, LPWINE_MM_DRIVER) /* = NULL */;
/* each known type of driver has an instance of this structure */
typedef struct tagWINE_LLTYPE {
/* those attributes depend on the specification of the type */
LPCSTR typestr; /* name (for debugging) */
BOOL bSupportMapper; /* if type is allowed to support mapper */
MMDRV_MAPFUNC Map16To32A; /* those are function pointers to handle */
MMDRV_UNMAPFUNC UnMap16To32A; /* the parameter conversion (16 vs 32 bit) */
MMDRV_MAPFUNC Map32ATo16; /* when hi-func (in mmsystem or winmm) and */
MMDRV_UNMAPFUNC UnMap32ATo16; /* low-func (in .drv) do not match */
LPDRVCALLBACK Callback; /* handles callback for a specified type */
/* those attributes reflect the loaded/current situation for the type */
UINT wMaxId; /* number of loaded devices (sum across all loaded drivers */
UINT wMaxId; /* number of loaded devices (sum across all loaded drivers) */
LPWINE_MLD lpMlds; /* "static" mlds to access the part though device IDs */
int nMapper; /* index to mapper */
} WINE_LLTYPE;
@ -58,7 +53,7 @@ static WINE_MM_DRIVER MMDrvs[8];
static LPWINE_MLD MM_MLDrvs[40];
#define MAX_MM_MLDRVS (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
#define A(_x,_y) {#_y, _x, NULL, NULL, NULL, NULL, NULL, 0, NULL, -1}
#define A(_x,_y) {#_y, _x, 0, NULL, -1}
/* Note: the indices of this array must match the definitions
* of the MMDRV_???? manifest constants
*/
@ -72,96 +67,6 @@ static WINE_LLTYPE llTypes[MMDRV_MAX] = {
};
#undef A
/******************************************************************
* MMDRV_InstallMap
*
*
*/
void MMDRV_InstallMap(unsigned int drv,
MMDRV_MAPFUNC mp1632, MMDRV_UNMAPFUNC um1632,
MMDRV_MAPFUNC mp3216, MMDRV_UNMAPFUNC um3216,
LPDRVCALLBACK cb)
{
assert(drv < MMDRV_MAX);
llTypes[drv].Map16To32A = mp1632;
llTypes[drv].UnMap16To32A = um1632;
llTypes[drv].Map32ATo16 = mp3216;
llTypes[drv].UnMap32ATo16 = um3216;
llTypes[drv].Callback = cb;
}
/******************************************************************
* MMDRV_Is32
*
*/
BOOL MMDRV_Is32(unsigned int idx)
{
TRACE("(%d)\n", idx);
return MMDrvs[idx].bIs32;
}
/**************************************************************************
* MMDRV_GetDescription32 [internal]
*/
static BOOL MMDRV_GetDescription32(const char* fname, char* buf, int buflen)
{
OFSTRUCT ofs;
DWORD h;
LPVOID ptr = 0;
LPVOID val;
DWORD dw;
BOOL ret = FALSE;
UINT u;
FARPROC pGetFileVersionInfoSizeA;
FARPROC pGetFileVersionInfoA;
FARPROC pVerQueryValueA;
HMODULE hmodule = 0;
TRACE("(%p, %p, %d)\n", fname, buf, buflen);
#define E(_x) do {TRACE _x;goto theEnd;} while(0)
if (OpenFile(fname, &ofs, OF_EXIST)==HFILE_ERROR) E(("Can't find file %s\n", fname));
if (!(hmodule = LoadLibraryA( "version.dll" ))) goto theEnd;
if (!(pGetFileVersionInfoSizeA = GetProcAddress( hmodule, "GetFileVersionInfoSizeA" )))
goto theEnd;
if (!(pGetFileVersionInfoA = GetProcAddress( hmodule, "GetFileVersionInfoA" )))
goto theEnd;
if (!(pVerQueryValueA = GetProcAddress( hmodule, "VerQueryValueA" )))
goto theEnd;
if (!(dw = pGetFileVersionInfoSizeA(ofs.szPathName, &h))) E(("Can't get FVIS\n"));
if (!(ptr = HeapAlloc(GetProcessHeap(), 0, dw))) E(("OOM\n"));
if (!pGetFileVersionInfoA(ofs.szPathName, h, dw, ptr)) E(("Can't get FVI\n"));
#define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
A(CompanyName);
A(FileDescription);
A(FileVersion);
A(InternalName);
A(LegalCopyright);
A(OriginalFilename);
A(ProductName);
A(ProductVersion);
A(Comments);
A(LegalTrademarks);
A(PrivateBuild);
A(SpecialBuild);
#undef A
if (!pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\ProductName", &val, &u)) E(("Can't get product name\n"));
lstrcpynA(buf, val, buflen);
#undef E
ret = TRUE;
theEnd:
HeapFree(GetProcessHeap(), 0, ptr);
if (hmodule) FreeLibrary( hmodule );
return ret;
}
/**************************************************************************
* MMDRV_GetNum [internal]
*/
@ -176,18 +81,17 @@ UINT MMDRV_GetNum(UINT type)
* MMDRV_Message [internal]
*/
DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1,
DWORD_PTR dwParam2, BOOL bFrom32)
DWORD_PTR dwParam2)
{
LPWINE_MM_DRIVER lpDrv;
DWORD ret;
WINE_MM_DRIVER_PART* part;
WINE_LLTYPE* llType = &llTypes[mld->type];
WINMM_MapType map;
int devID;
TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)\n",
TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx)\n",
llTypes[mld->type].typestr, mld->uDeviceID, wMsg,
mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
mld->dwDriverInstance, dwParam1, dwParam2);
if (mld->uDeviceID == (UINT16)-1) {
if (!llType->bSupportMapper) {
@ -215,78 +119,13 @@ DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1,
ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
#endif
if (lpDrv->bIs32) {
assert(part->u.fnMessage32);
assert(part->fnMessage32);
if (bFrom32) {
TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx)\n",
mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
TRACE("=> %s\n", WINMM_ErrorToString(ret));
} else {
map = llType->Map16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
switch (map) {
case WINMM_MAP_NOMEM:
ret = MMSYSERR_NOMEM;
break;
case WINMM_MAP_MSGERROR:
FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
ret = MMSYSERR_ERROR;
break;
case WINMM_MAP_OK:
case WINMM_MAP_OKMEM:
TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx)\n",
mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance,
dwParam1, dwParam2);
TRACE("=> %s\n", WINMM_ErrorToString(ret));
if (map == WINMM_MAP_OKMEM)
llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2, ret);
break;
default:
FIXME("NIY\n");
ret = MMSYSERR_NOTSUPPORTED;
break;
}
}
} else {
assert(part->u.fnMessage16 && pFnCallMMDrvFunc16);
TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx)\n",
mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
ret = part->fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
TRACE("=> %s\n", WINMM_ErrorToString(ret));
if (bFrom32) {
map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
switch (map) {
case WINMM_MAP_NOMEM:
ret = MMSYSERR_NOMEM;
break;
case WINMM_MAP_MSGERROR:
FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
ret = MMSYSERR_ERROR;
break;
case WINMM_MAP_OK:
case WINMM_MAP_OKMEM:
TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx)\n",
mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
ret = pFnCallMMDrvFunc16((DWORD)part->u.fnMessage16,
mld->uDeviceID, wMsg, mld->dwDriverInstance,
dwParam1, dwParam2);
TRACE("=> %s\n", WINMM_ErrorToString(ret));
if (map == WINMM_MAP_OKMEM)
llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2, ret);
break;
default:
FIXME("NIY\n");
ret = MMSYSERR_NOTSUPPORTED;
break;
}
} else {
TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx)\n",
mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
ret = pFnCallMMDrvFunc16((DWORD)part->u.fnMessage16,
mld->uDeviceID, wMsg, mld->dwDriverInstance,
dwParam1, dwParam2);
TRACE("=> %s\n", WINMM_ErrorToString(ret));
}
}
return ret;
}
@ -294,12 +133,12 @@ DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1,
* MMDRV_Alloc [internal]
*/
LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
DWORD_PTR* dwCallback, DWORD_PTR* dwInstance)
{
LPWINE_MLD mld;
UINT i;
TRACE("(%d, %04x, %p, %p, %p, %p, %c)\n",
size, type, hndl, dwFlags, dwCallback, dwInstance, bFrom32?'Y':'N');
UINT_PTR i;
TRACE("(%d, %04x, %p, %p, %p, %p)\n",
size, type, hndl, dwFlags, dwCallback, dwInstance);
mld = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
if (!mld) return NULL;
@ -317,7 +156,7 @@ LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
*hndl = (HANDLE)(i | 0x8000);
mld->type = type;
if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
if ((UINT_PTR)*hndl < MMDRV_GetNum(type) || ((UINT_PTR)*hndl >> 16)) {
/* FIXME: those conditions must be fulfilled so that:
* - we can distinguish between device IDs and handles
* - we can use handles as 16 or 32 bit entities
@ -325,18 +164,10 @@ LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
ERR("Shouldn't happen. Bad allocation scheme\n");
}
mld->bFrom32 = bFrom32;
mld->dwFlags = HIWORD(*dwFlags);
mld->dwCallback = *dwCallback;
mld->dwClientInstance = *dwInstance;
if (llTypes[type].Callback)
{
*dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
*dwCallback = (DWORD)llTypes[type].Callback;
*dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
}
return mld;
}
@ -347,8 +178,8 @@ void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
{
TRACE("(%p, %p)\n", hndl, mld);
if ((UINT)hndl & 0x8000) {
unsigned idx = (UINT)hndl & ~0x8000;
if ((UINT_PTR)hndl & 0x8000) {
UINT_PTR idx = (UINT_PTR)hndl & ~0x8000;
if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
MM_MLDrvs[idx] = NULL;
HeapFree(GetProcessHeap(), 0, mld);
@ -361,14 +192,14 @@ void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
/**************************************************************************
* MMDRV_Open [internal]
*/
DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD dwFlags)
{
DWORD dwRet = MMSYSERR_BADDEVICEID;
DWORD dwInstance;
DWORD_PTR dwInstance;
WINE_LLTYPE* llType = &llTypes[mld->type];
TRACE("(%p, %04x, 0x%08lx, 0x%08lx)\n", mld, wMsg, dwParam1, dwFlags);
TRACE("(%p, %04x, 0x%08lx, 0x%08x)\n", mld, wMsg, dwParam1, dwFlags);
mld->dwDriverInstance = (DWORD)&dwInstance;
mld->dwDriverInstance = (DWORD_PTR)&dwInstance;
if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) {
TRACE("MAPPER mode requested !\n");
@ -388,14 +219,14 @@ DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
mld->uDeviceID = (UINT16)-1;
mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags);
}
}
} else {
if (mld->uDeviceID < llType->wMaxId) {
mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags);
}
}
if (dwRet == MMSYSERR_NOERROR)
@ -409,7 +240,7 @@ DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
{
TRACE("(%p, %04x)\n", mld, wMsg);
return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
return MMDRV_Message(mld, wMsg, 0L, 0L);
}
/**************************************************************************
@ -431,7 +262,7 @@ static LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
LPWINE_MLD MMDRV_Get(HANDLE _hndl, UINT type, BOOL bCanBeID)
{
LPWINE_MLD mld = NULL;
UINT hndl = (UINT)_hndl;
UINT_PTR hndl = (UINT_PTR)_hndl;
TRACE("(%p, %04x, %c)\n", _hndl, type, bCanBeID ? 'Y' : 'N');
assert(type < MMDRV_MAX);
@ -439,13 +270,19 @@ LPWINE_MLD MMDRV_Get(HANDLE _hndl, UINT type, BOOL bCanBeID)
if (hndl >= llTypes[type].wMaxId &&
hndl != (UINT16)-1 && hndl != (UINT)-1) {
if (hndl & 0x8000) {
hndl = hndl & ~0x8000;
if (hndl < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
mld = MM_MLDrvs[hndl];
if (!mld || !HeapValidate(GetProcessHeap(), 0, mld) || mld->type != type)
mld = NULL;
UINT idx = hndl & ~0x8000;
if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
__TRY
{
mld = MM_MLDrvs[idx];
if (mld && mld->type != type) mld = NULL;
}
__EXCEPT_PAGE_FAULT
{
mld = NULL;
}
__ENDTRY;
}
hndl = hndl | 0x8000;
}
}
if (mld == NULL && bCanBeID) {
@ -475,8 +312,8 @@ LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
/**************************************************************************
* MMDRV_PhysicalFeatures [internal]
*/
UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
DWORD dwParam2)
UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg,
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
@ -511,11 +348,11 @@ UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
case DRV_QUERYDEVICEINTERFACE:
case DRV_QUERYDEVICEINTERFACESIZE:
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2);
case DRV_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
case DRV_QUERYDSOUNDDESC: /* Wine-specific: Retrieve DirectSound driver description*/
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2);
default:
WARN("Unknown call %04x\n", uMsg);
@ -539,29 +376,16 @@ static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT type, UINT wMsg)
/* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
/* the DRVM_ENABLE is only required when the PnP node is non zero */
if (lpDrv->bIs32 && part->u.fnMessage32) {
ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
TRACE("DRVM_INIT => %s\n", WINMM_ErrorToString(ret));
if (part->fnMessage32) {
ret = part->fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
TRACE("DRVM_INIT => %s\n", WINMM_ErrorToString(ret));
#if 0
ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
TRACE("DRVM_ENABLE => %08lx\n", ret);
ret = part->fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
TRACE("DRVM_ENABLE => %08lx\n", ret);
#endif
count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
} else if (!lpDrv->bIs32 && part->u.fnMessage16 && pFnCallMMDrvFunc16) {
ret = pFnCallMMDrvFunc16((DWORD)part->u.fnMessage16,
0, DRVM_INIT, 0L, 0L, 0L);
TRACE("DRVM_INIT => %s\n", WINMM_ErrorToString(ret));
#if 0
ret = pFnCallMMDrvFunc16((DWORD)part->u.fnMessage16,
0, DRVM_ENABLE, 0L, 0L, 0L);
TRACE("DRVM_ENABLE => %08lx\n", ret);
#endif
count = pFnCallMMDrvFunc16((DWORD)part->u.fnMessage16,
0, wMsg, 0L, 0L, 0L);
} else {
return FALSE;
count = part->fnMessage32(0, wMsg, 0L, 0L, 0L);
}
else return FALSE;
TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->drvname, llTypes[type].typestr);
@ -621,11 +445,12 @@ static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT type, UINT wMsg)
/**************************************************************************
* MMDRV_Install [internal]
*/
BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
{
int i, count = 0;
LPWINE_MM_DRIVER lpDrv = &MMDrvs[MMDrvsHi];
LPWINE_DRIVER d;
WINEMM_msgFunc32 func;
TRACE("('%s', '%s', mapper=%c);\n", drvRegName, drvFileName, bIsMapper ? 'Y' : 'N');
@ -646,26 +471,23 @@ BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
return FALSE;
}
d = DRIVER_FindFromHDrvr(lpDrv->hDriver);
if (!(d = DRIVER_FindFromHDrvr(lpDrv->hDriver))) {
CloseDriver(lpDrv->hDriver, 0, 0);
WARN("Couldn't get the WINE internal structure for driver '%s'\n", drvFileName);
return FALSE;
}
lpDrv->bIs32 = (d->dwFlags & WINE_GDF_16BIT) ? FALSE : TRUE;
/* Then look for xxxMessage functions */
#define AA(_h,_w,_x,_y,_z) \
func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
if (func != NULL) \
{ lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
{ lpDrv->parts[_w].fnMessage##_y = func; count++; \
TRACE("Got %d bit func '%s'\n", _y, #_x); }
if (lpDrv->bIs32) {
WINEMM_msgFunc32 func;
char buffer[128];
if (d->d.d32.hModule) {
#define A(_x,_y) AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
if (d->hModule) {
#define A(_x,_y) AA(d->hModule,_x,_y,32,GetProcAddress)
A(MMDRV_AUX, auxMessage);
A(MMDRV_MIXER, mxdMessage);
A(MMDRV_MIDIIN, midMessage);
@ -673,15 +495,6 @@ BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
A(MMDRV_WAVEIN, widMessage);
A(MMDRV_WAVEOUT, wodMessage);
#undef A
}
if (TRACE_ON(winmm)) {
if (MMDRV_GetDescription32(drvFileName, buffer, sizeof(buffer)))
TRACE("%s => %s\n", drvFileName, buffer);
else
TRACE("%s => No description\n", drvFileName);
}
} else if (WINMM_CheckForMMSystem() && pFnLoadMMDrvFunc16) {
count += pFnLoadMMDrvFunc16(drvFileName, d, lpDrv);
}
#undef AA
@ -730,6 +543,7 @@ BOOL MMDRV_Init(void)
char driver_buffer[256];
char mapper_buffer[256];
char midi_buffer[256];
char* p;
DWORD type, size;
BOOL ret = FALSE;
TRACE("()\n");
@ -746,6 +560,17 @@ BOOL MMDRV_Init(void)
strcpy(driver_buffer, WINE_DEFAULT_WINMM_DRIVER);
}
p = driver_buffer;
while (p)
{
char filename[sizeof(driver_buffer)+10];
char *next = strchr(p, ',');
if (next) *next++ = 0;
sprintf( filename, "wine%s.drv", p );
if ((ret = MMDRV_Install( filename, filename, FALSE ))) break;
p = next;
}
ret |= MMDRV_Install("beepmidi.dll", "beepmidi.dll", FALSE);
ret |= MMDRV_Install("wavemapper", WINE_DEFAULT_WINMM_MAPPER, TRUE);
@ -774,24 +599,13 @@ static BOOL MMDRV_ExitPerType(LPWINE_MM_DRIVER lpDrv, UINT type)
DWORD ret;
TRACE("(%p, %04x)\n", lpDrv, type);
if (lpDrv->bIs32 && part->u.fnMessage32) {
if (part->fnMessage32) {
#if 0
ret = part->u.fnMessage32(0, DRVM_DISABLE, 0L, 0L, 0L);
TRACE("DRVM_DISABLE => %08lx\n", ret);
ret = part->fnMessage32(0, DRVM_DISABLE, 0L, 0L, 0L);
TRACE("DRVM_DISABLE => %08lx\n", ret);
#endif
ret = part->u.fnMessage32(0, DRVM_EXIT, 0L, 0L, 0L);
TRACE("DRVM_EXIT => %s\n", WINMM_ErrorToString(ret));
} else if (!lpDrv->bIs32 && part->u.fnMessage16 && pFnCallMMDrvFunc16) {
#if 0
ret = pFnCallMMDrvFunc16((DWORD)part->u.fnMessage16,
0, DRVM_DISABLE, 0L, 0L, 0L);
TRACE("DRVM_DISABLE => %08lx\n", ret);
#endif
ret = pFnCallMMDrvFunc16((DWORD)part->u.fnMessage16,
0, DRVM_EXIT, 0L, 0L, 0L);
TRACE("DRVM_EXIT => %s\n", WINMM_ErrorToString(ret));
} else {
return FALSE;
ret = part->fnMessage32(0, DRVM_EXIT, 0L, 0L, 0L);
TRACE("DRVM_EXIT => %s\n", WINMM_ErrorToString(ret));
}
return TRUE;
@ -804,7 +618,7 @@ static BOOL MMDRV_ExitPerType(LPWINE_MM_DRIVER lpDrv, UINT type)
*/
void MMDRV_Exit(void)
{
int i;
unsigned int i;
TRACE("()\n");
for (i = 0; i < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]); i++)
@ -820,7 +634,8 @@ void MMDRV_Exit(void)
}
/* unload driver, in reverse order of loading */
for (i = sizeof(MMDrvs) / sizeof(MMDrvs[0]) - 1; i >= 0; i--)
i = sizeof(MMDrvs) / sizeof(MMDrvs[0]);
while (i-- > 0)
{
MMDRV_ExitPerType(&MMDrvs[i], MMDRV_AUX);
MMDRV_ExitPerType(&MMDrvs[i], MMDRV_MIXER);
@ -830,4 +645,16 @@ void MMDRV_Exit(void)
MMDRV_ExitPerType(&MMDrvs[i], MMDRV_WAVEOUT);
CloseDriver(MMDrvs[i].hDriver, 0, 0);
}
if (llTypes[MMDRV_AUX].lpMlds)
HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_AUX].lpMlds - 1);
if (llTypes[MMDRV_MIXER].lpMlds)
HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_MIXER].lpMlds - 1);
if (llTypes[MMDRV_MIDIIN].lpMlds)
HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_MIDIIN].lpMlds - 1);
if (llTypes[MMDRV_MIDIOUT].lpMlds)
HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_MIDIOUT].lpMlds - 1);
if (llTypes[MMDRV_WAVEIN].lpMlds)
HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_WAVEIN].lpMlds - 1);
if (llTypes[MMDRV_WAVEOUT].lpMlds)
HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_WAVEOUT].lpMlds - 1);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
* MMIO functions
*
* Copyright 1998 Andrew Taylor
* Copyright 1998 Ove Kåven
* Copyright 1998 Ove Kåven
* Copyright 2000,2002 Eric Pouech
*
* This library is free software; you can redistribute it and/or
@ -17,7 +17,7 @@
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Still to be done:
@ -45,7 +45,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(mmio);
LRESULT (*pFnMmioCallback16)(DWORD,LPMMIOINFO,UINT,LPARAM,LPARAM) /* = NULL */;
static WINE_MMIO *MMIOList;
/**************************************************************************
* mmioDosIOProc [internal]
@ -227,8 +227,8 @@ static LRESULT CALLBACK mmioMemIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage,
*/
static struct IOProcList defaultProcs[] = {
{&defaultProcs[1], FOURCC_DOS, (LPMMIOPROC)mmioDosIOProc, MMIO_PROC_32A, 0},
{NULL, FOURCC_MEM, (LPMMIOPROC)mmioMemIOProc, MMIO_PROC_32A, 0},
{&defaultProcs[1], FOURCC_DOS, (LPMMIOPROC)mmioDosIOProc, FALSE, 0},
{NULL, FOURCC_MEM, (LPMMIOPROC)mmioMemIOProc, FALSE, 0},
};
static struct IOProcList* pIOProcListAnchor = &defaultProcs[0];
@ -253,14 +253,14 @@ static struct IOProcList* MMIO_FindProcNode(FOURCC fccIOProc)
/****************************************************************
* MMIO_InstallIOProc [INTERNAL]
*/
LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
DWORD dwFlags, enum mmioProcType type)
static LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
DWORD dwFlags, BOOL is_unicode)
{
LPMMIOPROC lpProc = NULL;
struct IOProcList* pListNode;
struct IOProcList** ppListNode;
TRACE("(%08lx, %p, %08lX, %i)\n", fccIOProc, pIOProc, dwFlags, type);
TRACE("(%08x, %p, %08X, %s)\n", fccIOProc, pIOProc, dwFlags, is_unicode ? "unicode" : "ansi");
if (dwFlags & MMIO_GLOBALPROC)
FIXME("Global procedures not implemented\n");
@ -274,7 +274,7 @@ LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
/* Fill in this node */
pListNode->fourCC = fccIOProc;
pListNode->pIOProc = pIOProc;
pListNode->type = type;
pListNode->is_unicode = is_unicode;
pListNode->count = 0;
/* Stick it on the end of the list */
@ -312,7 +312,7 @@ LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
}
/* remove it, but only if it isn't builtin */
if ((*ppListNode) >= defaultProcs &&
(*ppListNode) < defaultProcs + sizeof(defaultProcs)) {
(*ppListNode) < defaultProcs + sizeof(defaultProcs) / sizeof(defaultProcs[0])) {
WARN("Tried to remove built-in mmio proc. Skipping\n");
} else {
/* Okay, nuke it */
@ -339,39 +339,27 @@ LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
*/
static LRESULT send_message(struct IOProcList* ioProc, LPMMIOINFO mmioinfo,
DWORD wMsg, LPARAM lParam1,
LPARAM lParam2, enum mmioProcType type)
LPARAM lParam2, BOOL is_unicode)
{
LRESULT result = MMSYSERR_ERROR;
LPARAM lp1 = lParam1, lp2 = lParam2;
if (!ioProc) {
ERR("brrr\n");
result = MMSYSERR_INVALPARAM;
ERR("ioProc NULL\n");
return MMSYSERR_INVALPARAM;
}
switch (ioProc->type) {
case MMIO_PROC_16:
if (pFnMmioCallback16)
result = pFnMmioCallback16((DWORD)ioProc->pIOProc,
mmioinfo, wMsg, lp1, lp2);
break;
case MMIO_PROC_32A:
case MMIO_PROC_32W:
if (ioProc->type != type) {
/* map (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
FIXME("NIY 32 A<=>W mapping\n");
}
result = (ioProc->pIOProc)((LPSTR)mmioinfo, wMsg, lp1, lp2);
if (ioProc->is_unicode != is_unicode) {
/* map (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
FIXME("NIY 32 A<=>W mapping\n");
}
result = (ioProc->pIOProc)((LPSTR)mmioinfo, wMsg, lp1, lp2);
#if 0
if (ioProc->type != type) {
if (ioProc->is_unicode != is_unicode) {
/* unmap (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
}
#endif
break;
default:
FIXME("Internal error\n");
}
return result;
}
@ -436,16 +424,16 @@ static FOURCC MMIO_ParseExtA(LPCSTR szFileName)
*
* Retrieves the mmio object from current process
*/
LPWINE_MMIO MMIO_Get(HMMIO h)
static LPWINE_MMIO MMIO_Get(HMMIO h)
{
LPWINE_MMIO wm = NULL;
EnterCriticalSection(&WINMM_IData.cs);
for (wm = WINMM_IData.lpMMIO; wm; wm = wm->lpNext) {
EnterCriticalSection(&WINMM_cs);
for (wm = MMIOList; wm; wm = wm->lpNext) {
if (wm->info.hmmio == h)
break;
}
LeaveCriticalSection(&WINMM_IData.cs);
LeaveCriticalSection(&WINMM_cs);
return wm;
}
@ -461,13 +449,13 @@ static LPWINE_MMIO MMIO_Create(void)
wm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MMIO));
if (wm) {
EnterCriticalSection(&WINMM_IData.cs);
EnterCriticalSection(&WINMM_cs);
/* lookup next unallocated WORD handle, with a non NULL value */
while (++MMIO_counter == 0 || MMIO_Get((HMMIO)(ULONG_PTR)MMIO_counter));
wm->info.hmmio = (HMMIO)(ULONG_PTR)MMIO_counter;
wm->lpNext = WINMM_IData.lpMMIO;
WINMM_IData.lpMMIO = wm;
LeaveCriticalSection(&WINMM_IData.cs);
wm->lpNext = MMIOList;
MMIOList = wm;
LeaveCriticalSection(&WINMM_cs);
}
return wm;
}
@ -481,9 +469,9 @@ static BOOL MMIO_Destroy(LPWINE_MMIO wm)
{
LPWINE_MMIO* m;
EnterCriticalSection(&WINMM_IData.cs);
EnterCriticalSection(&WINMM_cs);
/* search for the matching one... */
m = &(WINMM_IData.lpMMIO);
m = &MMIOList;
while (*m && *m != wm) m = &(*m)->lpNext;
/* ...and destroy */
if (*m) {
@ -491,7 +479,7 @@ static BOOL MMIO_Destroy(LPWINE_MMIO wm)
HeapFree(GetProcessHeap(), 0, wm);
wm = NULL;
}
LeaveCriticalSection(&WINMM_IData.cs);
LeaveCriticalSection(&WINMM_cs);
return wm ? FALSE : TRUE;
}
@ -504,11 +492,10 @@ static MMRESULT MMIO_Flush(WINE_MMIO* wm, UINT uFlags)
/* not quite sure what to do here, but I'll guess */
if (wm->info.dwFlags & MMIO_DIRTY) {
/* FIXME: error handling */
send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
wm->info.lBufOffset, SEEK_SET, MMIO_PROC_32A);
send_message(wm->ioProc, &wm->info, MMIOM_SEEK, wm->info.lBufOffset, SEEK_SET, FALSE);
send_message(wm->ioProc, &wm->info, MMIOM_WRITE,
(LPARAM)wm->info.pchBuffer,
wm->info.pchNext - wm->info.pchBuffer, MMIO_PROC_32A);
wm->info.pchNext - wm->info.pchBuffer, FALSE);
}
if (uFlags & MMIO_EMPTYBUF)
wm->info.pchNext = wm->info.pchEndRead = wm->info.pchBuffer;
@ -525,9 +512,9 @@ static LONG MMIO_GrabNextBuffer(LPWINE_MMIO wm, int for_read)
{
LONG size = wm->info.cchBuffer;
TRACE("bo=%lx do=%lx of=%lx\n",
TRACE("bo=%x do=%x of=%lx\n",
wm->info.lBufOffset, wm->info.lDiskOffset,
send_message(wm->ioProc, &wm->info, MMIOM_SEEK, 0, SEEK_CUR, MMIO_PROC_32A));
send_message(wm->ioProc, &wm->info, MMIOM_SEEK, 0, SEEK_CUR, FALSE));
wm->info.lBufOffset = wm->info.lDiskOffset;
wm->info.pchNext = wm->info.pchBuffer;
@ -537,7 +524,7 @@ static LONG MMIO_GrabNextBuffer(LPWINE_MMIO wm, int for_read)
wm->bBufferLoaded = TRUE;
if (for_read) {
size = send_message(wm->ioProc, &wm->info, MMIOM_READ,
(LPARAM)wm->info.pchBuffer, size, MMIO_PROC_32A);
(LPARAM)wm->info.pchBuffer, size, FALSE);
if (size > 0)
wm->info.pchEndRead += size;
else
@ -553,11 +540,10 @@ static LONG MMIO_GrabNextBuffer(LPWINE_MMIO wm, int for_read)
static MMRESULT MMIO_SetBuffer(WINE_MMIO* wm, void* pchBuffer, LONG cchBuffer,
UINT uFlags)
{
TRACE("(%p %p %ld %u)\n", wm, pchBuffer, cchBuffer, uFlags);
TRACE("(%p %p %d %u)\n", wm, pchBuffer, cchBuffer, uFlags);
if (uFlags) return MMSYSERR_INVALPARAM;
if (cchBuffer > 0xFFFF)
WARN("Untested handling of huge mmio buffers (%ld >= 64k)\n", cchBuffer);
WARN("Untested handling of huge mmio buffers (%d >= 64k)\n", cchBuffer);
if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
return MMIOERR_CANNOTWRITE;
@ -583,7 +569,7 @@ static MMRESULT MMIO_SetBuffer(WINE_MMIO* wm, void* pchBuffer, LONG cchBuffer,
wm->info.pchNext = wm->info.pchBuffer;
wm->info.pchEndRead = wm->info.pchBuffer;
wm->info.pchEndWrite = wm->info.pchBuffer + cchBuffer;
wm->info.lBufOffset = 0;
wm->info.lBufOffset = wm->info.lDiskOffset;
wm->bBufferLoaded = FALSE;
return MMSYSERR_NOERROR;
@ -592,13 +578,12 @@ static MMRESULT MMIO_SetBuffer(WINE_MMIO* wm, void* pchBuffer, LONG cchBuffer,
/**************************************************************************
* MMIO_Open [internal]
*/
HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags,
enum mmioProcType type)
static HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags, BOOL is_unicode)
{
LPWINE_MMIO wm;
MMIOINFO mmioinfo;
TRACE("('%s', %p, %08lX, %d);\n", szFileName, refmminfo, dwOpenFlags, type);
TRACE("('%s', %p, %08X, %s);\n", szFileName, refmminfo, dwOpenFlags, is_unicode ? "unicode" : "ansi");
if (!refmminfo) {
refmminfo = &mmioinfo;
@ -607,12 +592,14 @@ HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags,
mmioinfo.pIOProc = NULL;
mmioinfo.pchBuffer = NULL;
mmioinfo.cchBuffer = 0;
type = MMIO_PROC_32A;
is_unicode = FALSE;
}
if (dwOpenFlags & (MMIO_PARSE|MMIO_EXIST)) {
char buffer[MAX_PATH];
if (!szFileName)
return (HMMIO)FALSE;
if (GetFullPathNameA(szFileName, sizeof(buffer), buffer, NULL) >= sizeof(buffer))
return (HMMIO)FALSE;
if ((dwOpenFlags & MMIO_EXIST) && (GetFileAttributesA(buffer) == INVALID_FILE_ATTRIBUTES))
@ -648,32 +635,35 @@ HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags,
else {
wm->info.fccIOProc = refmminfo->fccIOProc;
MMIO_InstallIOProc(wm->info.fccIOProc, refmminfo->pIOProc,
MMIO_INSTALLPROC, type);
MMIO_INSTALLPROC, is_unicode);
if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) goto error2;
assert(wm->ioProc->pIOProc == refmminfo->pIOProc);
wm->bTmpIOProc = TRUE;
}
wm->bBufferLoaded = FALSE;
wm->ioProc->count++;
wm->info.dwFlags = dwOpenFlags;
if (dwOpenFlags & MMIO_ALLOCBUF) {
if ((refmminfo->wErrorRet = MMIO_SetBuffer(wm, NULL, MMIO_DEFAULTBUFFER, 0)))
refmminfo->wErrorRet = MMIO_SetBuffer(wm, refmminfo->pchBuffer,
refmminfo->cchBuffer ? refmminfo->cchBuffer : MMIO_DEFAULTBUFFER, 0);
if (refmminfo->wErrorRet != MMSYSERR_NOERROR)
goto error1;
} else if (wm->info.fccIOProc == FOURCC_MEM) {
} else {
refmminfo->wErrorRet = MMIO_SetBuffer(wm, refmminfo->pchBuffer, refmminfo->cchBuffer, 0);
if (refmminfo->wErrorRet != MMSYSERR_NOERROR)
goto error1;
wm->bBufferLoaded = TRUE;
} /* else => unbuffered, wm->info.pchBuffer == NULL */
}
if (wm->info.fccIOProc == FOURCC_MEM && !(wm->info.dwFlags & MMIO_ALLOCBUF))
wm->bBufferLoaded = TRUE;
/* see mmioDosIOProc for that one */
wm->info.adwInfo[0] = refmminfo->adwInfo[0];
wm->info.dwFlags = dwOpenFlags;
/* call IO proc to actually open file */
refmminfo->wErrorRet = send_message(wm->ioProc, &wm->info, MMIOM_OPEN,
(LPARAM)szFileName, 0, MMIO_PROC_32A);
(LPARAM)szFileName, 0, FALSE);
/* grab file size, when possible */
wm->dwFileSize = GetFileSize((HANDLE)wm->info.adwInfo[0], NULL);
@ -704,7 +694,7 @@ HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO* lpmmioinfo,
WideCharToMultiByte( CP_ACP, 0, szFileName, -1, szFn, len, NULL, NULL );
}
ret = MMIO_Open(szFn, lpmmioinfo, dwOpenFlags, MMIO_PROC_32W);
ret = MMIO_Open(szFn, lpmmioinfo, dwOpenFlags, TRUE);
HeapFree(GetProcessHeap(), 0, szFn);
return ret;
@ -716,7 +706,7 @@ HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO* lpmmioinfo,
HMMIO WINAPI mmioOpenA(LPSTR szFileName, MMIOINFO* lpmmioinfo,
DWORD dwOpenFlags)
{
return MMIO_Open(szFileName, lpmmioinfo, dwOpenFlags, MMIO_PROC_32A);
return MMIO_Open(szFileName, lpmmioinfo, dwOpenFlags, FALSE);
}
/**************************************************************************
@ -735,8 +725,7 @@ MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
if ((result = MMIO_Flush(wm, 0)) != MMSYSERR_NOERROR)
return result;
result = send_message(wm->ioProc, &wm->info, MMIOM_CLOSE,
uFlags, 0, MMIO_PROC_32A);
result = send_message(wm->ioProc, &wm->info, MMIOM_CLOSE, uFlags, 0, FALSE);
MMIO_SetBuffer(wm, NULL, 0, 0);
@ -744,7 +733,7 @@ MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
if (wm->bTmpIOProc)
MMIO_InstallIOProc(wm->info.fccIOProc, wm->ioProc->pIOProc,
MMIO_REMOVEPROC, wm->ioProc->type);
MMIO_REMOVEPROC, wm->ioProc->is_unicode);
MMIO_Destroy(wm);
@ -759,15 +748,14 @@ LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
LPWINE_MMIO wm;
LONG count;
TRACE("(%p, %p, %ld);\n", hmmio, pch, cch);
TRACE("(%p, %p, %d);\n", hmmio, pch, cch);
if ((wm = MMIO_Get(hmmio)) == NULL)
return -1;
/* unbuffered case first */
if (!wm->info.pchBuffer)
return send_message(wm->ioProc, &wm->info, MMIOM_READ,
(LPARAM)pch, cch, MMIO_PROC_32A);
return send_message(wm->ioProc, &wm->info, MMIOM_READ, (LPARAM)pch, cch, FALSE);
/* first try from current buffer */
if (wm->info.pchNext != wm->info.pchEndRead) {
@ -797,7 +785,7 @@ LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
}
}
TRACE("count=%ld\n", count);
TRACE("count=%d\n", count);
return count;
}
@ -809,7 +797,7 @@ LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
LPWINE_MMIO wm;
LONG count;
TRACE("(%p, %p, %ld);\n", hmmio, pch, cch);
TRACE("(%p, %p, %d);\n", hmmio, pch, cch);
if ((wm = MMIO_Get(hmmio)) == NULL)
return -1;
@ -847,12 +835,11 @@ LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
}
count = bytesW;
} else {
count = send_message(wm->ioProc, &wm->info, MMIOM_WRITE,
(LPARAM)pch, cch, MMIO_PROC_32A);
count = send_message(wm->ioProc, &wm->info, MMIOM_WRITE, (LPARAM)pch, cch, FALSE);
wm->info.lBufOffset = wm->info.lDiskOffset;
}
TRACE("bytes written=%ld\n", count);
TRACE("bytes written=%d\n", count);
return count;
}
@ -864,15 +851,14 @@ LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
LPWINE_MMIO wm;
LONG offset;
TRACE("(%p, %08lX, %d);\n", hmmio, lOffset, iOrigin);
TRACE("(%p, %08X, %d);\n", hmmio, lOffset, iOrigin);
if ((wm = MMIO_Get(hmmio)) == NULL)
return MMSYSERR_INVALHANDLE;
/* not buffered, direct seek on file */
if (!wm->info.pchBuffer)
return send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
lOffset, iOrigin, MMIO_PROC_32A);
return send_message(wm->ioProc, &wm->info, MMIOM_SEEK, lOffset, iOrigin, FALSE);
switch (iOrigin) {
case SEEK_SET:
@ -911,14 +897,14 @@ LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
/* this also sets the wm->info.lDiskOffset field */
send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
(offset / wm->info.cchBuffer) * wm->info.cchBuffer,
SEEK_SET, MMIO_PROC_32A) == -1)
SEEK_SET, FALSE) == -1)
return -1;
MMIO_GrabNextBuffer(wm, TRUE);
}
wm->info.pchNext = wm->info.pchBuffer + (offset - wm->info.lBufOffset);
TRACE("=> %ld\n", offset);
TRACE("=> %d\n", offset);
return offset;
}
@ -934,10 +920,7 @@ MMRESULT WINAPI mmioGetInfo(HMMIO hmmio, MMIOINFO* lpmmioinfo, UINT uFlags)
if ((wm = MMIO_Get(hmmio)) == NULL)
return MMSYSERR_INVALHANDLE;
memcpy(lpmmioinfo, &wm->info, sizeof(MMIOINFO));
/* don't expose 16 bit ioproc:s */
if (wm->ioProc->type != MMIO_PROC_16)
lpmmioinfo->pIOProc = wm->ioProc->pIOProc;
*lpmmioinfo = wm->info;
return MMSYSERR_NOERROR;
}
@ -976,7 +959,7 @@ MMRESULT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT
{
LPWINE_MMIO wm;
TRACE("(hmmio=%p, pchBuf=%p, cchBuf=%ld, uFlags=%#08x)\n",
TRACE("(hmmio=%p, pchBuf=%p, cchBuf=%d, uFlags=%#08x)\n",
hmmio, pchBuffer, cchBuffer, uFlags);
if ((wm = MMIO_Get(hmmio)) == NULL)
@ -1023,11 +1006,9 @@ MMRESULT WINAPI mmioAdvance(HMMIO hmmio, MMIOINFO* lpmmioinfo, UINT uFlags)
if (uFlags == MMIO_WRITE && (lpmmioinfo->dwFlags & MMIO_DIRTY))
{
send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
lpmmioinfo->lBufOffset, SEEK_SET, MMIO_PROC_32A);
send_message(wm->ioProc, &wm->info, MMIOM_WRITE,
(LPARAM)lpmmioinfo->pchBuffer,
lpmmioinfo->pchNext - lpmmioinfo->pchBuffer, MMIO_PROC_32A);
send_message(wm->ioProc, &wm->info, MMIOM_SEEK, lpmmioinfo->lBufOffset, SEEK_SET, FALSE);
send_message(wm->ioProc, &wm->info, MMIOM_WRITE, (LPARAM)lpmmioinfo->pchBuffer,
lpmmioinfo->pchNext - lpmmioinfo->pchBuffer, FALSE);
lpmmioinfo->dwFlags &= ~MMIO_DIRTY;
}
if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
@ -1091,7 +1072,7 @@ FOURCC WINAPI mmioStringToFOURCCW(LPCWSTR sz, UINT uFlags)
LPMMIOPROC WINAPI mmioInstallIOProcA(FOURCC fccIOProc,
LPMMIOPROC pIOProc, DWORD dwFlags)
{
return MMIO_InstallIOProc(fccIOProc, pIOProc, dwFlags, MMIO_PROC_32A);
return MMIO_InstallIOProc(fccIOProc, pIOProc, dwFlags, FALSE);
}
/**************************************************************************
@ -1100,7 +1081,7 @@ LPMMIOPROC WINAPI mmioInstallIOProcA(FOURCC fccIOProc,
LPMMIOPROC WINAPI mmioInstallIOProcW(FOURCC fccIOProc,
LPMMIOPROC pIOProc, DWORD dwFlags)
{
return MMIO_InstallIOProc(fccIOProc, pIOProc, dwFlags, MMIO_PROC_32W);
return MMIO_InstallIOProc(fccIOProc, pIOProc, dwFlags, TRUE);
}
/******************************************************************
@ -1108,12 +1089,12 @@ LPMMIOPROC WINAPI mmioInstallIOProcW(FOURCC fccIOProc,
*
*
*/
LRESULT MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
LPARAM lParam2, enum mmioProcType type)
static LRESULT MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
LPARAM lParam2, BOOL is_unicode)
{
LPWINE_MMIO wm;
TRACE("(%p, %u, %ld, %ld, %d)\n", hmmio, uMessage, lParam1, lParam2, type);
TRACE("(%p, %u, %ld, %ld, %s)\n", hmmio, uMessage, lParam1, lParam2, is_unicode ? "unicode" : "ansi");
if (uMessage < MMIOM_USER)
return MMSYSERR_INVALPARAM;
@ -1121,7 +1102,7 @@ LRESULT MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
if ((wm = MMIO_Get(hmmio)) == NULL)
return MMSYSERR_INVALHANDLE;
return send_message(wm->ioProc, &wm->info, uMessage, lParam1, lParam2, type);
return send_message(wm->ioProc, &wm->info, uMessage, lParam1, lParam2, is_unicode);
}
/**************************************************************************
@ -1130,7 +1111,7 @@ LRESULT MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
LRESULT WINAPI mmioSendMessage(HMMIO hmmio, UINT uMessage,
LPARAM lParam1, LPARAM lParam2)
{
return MMIO_SendMessage(hmmio, uMessage, lParam1, lParam2, MMIO_PROC_32A);
return MMIO_SendMessage(hmmio, uMessage, lParam1, lParam2, FALSE);
}
/**************************************************************************
@ -1143,17 +1124,16 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck,
FOURCC srchCkId;
FOURCC srchType;
TRACE("(%p, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags);
if (lpck == NULL)
return MMSYSERR_INVALPARAM;
dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
TRACE("dwOldPos=%ld\n", dwOldPos);
TRACE("dwOldPos=%d\n", dwOldPos);
if (lpckParent != NULL) {
TRACE("seek inside parent at %ld !\n", lpckParent->dwDataOffset);
TRACE("seek inside parent at %d !\n", lpckParent->dwDataOffset);
/* EPP: was dwOldPos = mmioSeek(hmmio,lpckParent->dwDataOffset,SEEK_SET); */
if (dwOldPos < lpckParent->dwDataOffset ||
dwOldPos >= lpckParent->dwDataOffset + lpckParent->cksize) {
@ -1166,62 +1146,54 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck,
* examples disagree -Marcus,990216.
*/
srchCkId = 0;
srchType = 0;
/* find_chunk looks for 'ckid' */
if (uFlags & MMIO_FINDCHUNK)
srchCkId = lpck->ckid;
/* find_riff and find_list look for 'fccType' */
if (uFlags & MMIO_FINDLIST) {
if (uFlags & MMIO_FINDLIST)
{
srchCkId = FOURCC_LIST;
srchType = lpck->fccType;
srchType = lpck->fccType;
}
if (uFlags & MMIO_FINDRIFF) {
if (uFlags & MMIO_FINDRIFF)
{
srchCkId = FOURCC_RIFF;
srchType = lpck->fccType;
srchType = lpck->fccType;
}
if (uFlags & (MMIO_FINDCHUNK|MMIO_FINDLIST|MMIO_FINDRIFF)) {
TRACE("searching for %.4s.%.4s\n",
(LPSTR)&srchCkId,
srchType?(LPSTR)&srchType:"any ");
TRACE("searching for %4.4s.%4.4s\n",
(LPCSTR)&srchCkId, srchType ? (LPCSTR)&srchType : "any");
while (TRUE) {
LONG ix;
while (TRUE)
{
LONG ix;
ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
if (ix < 2*sizeof(DWORD)) {
mmioSeek(hmmio, dwOldPos, SEEK_SET);
WARN("return ChunkNotFound\n");
return MMIOERR_CHUNKNOTFOUND;
}
lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
if (ix < lpck->dwDataOffset - dwOldPos) {
mmioSeek(hmmio, dwOldPos, SEEK_SET);
WARN("return ChunkNotFound\n");
return MMIOERR_CHUNKNOTFOUND;
}
TRACE("ckid=%.4s fcc=%.4s cksize=%08lX !\n",
(LPSTR)&lpck->ckid,
srchType?(LPSTR)&lpck->fccType:"<na>",
lpck->cksize);
if ((srchCkId == lpck->ckid) &&
(!srchType || (srchType == lpck->fccType))
)
break;
ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
if (ix < 2*sizeof(DWORD))
{
mmioSeek(hmmio, dwOldPos, SEEK_SET);
WARN("return ChunkNotFound\n");
return MMIOERR_CHUNKNOTFOUND;
}
dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1);
mmioSeek(hmmio, dwOldPos, SEEK_SET);
}
} else {
/* FIXME: unverified, does it do this? */
/* NB: This part is used by WAVE_mciOpen, among others */
if (mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD)) < 3 * sizeof(DWORD)) {
mmioSeek(hmmio, dwOldPos, SEEK_SET);
WARN("return ChunkNotFound 2nd\n");
return MMIOERR_CHUNKNOTFOUND;
}
lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
TRACE("ckid=%4.4s fcc=%4.4s cksize=%08X !\n",
(LPCSTR)&lpck->ckid,
srchType ? (LPCSTR)&lpck->fccType:"<na>",
lpck->cksize);
if ( (!srchCkId || (srchCkId == lpck->ckid)) &&
(!srchType || (srchType == lpck->fccType)) )
break;
dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1);
mmioSeek(hmmio, dwOldPos, SEEK_SET);
}
lpck->dwFlags = 0;
/* If we were looking for RIFF/LIST chunks, the final file position
* is after the chunkid. If we were just looking for the chunk
@ -1230,8 +1202,11 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck,
if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST)
mmioSeek(hmmio, lpck->dwDataOffset + sizeof(DWORD), SEEK_SET);
else
{
mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
TRACE("lpck: ckid=%.4s, cksize=%ld, dwDataOffset=%ld fccType=%08lX (%.4s)!\n",
lpck->fccType = 0;
}
TRACE("lpck: ckid=%.4s, cksize=%d, dwDataOffset=%d fccType=%08X (%.4s)!\n",
(LPSTR)&lpck->ckid, lpck->cksize, lpck->dwDataOffset,
lpck->fccType, srchType?(LPSTR)&lpck->fccType:"");
return MMSYSERR_NOERROR;
@ -1249,10 +1224,10 @@ MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
TRACE("Chunk is dirty, checking if chunk's size is correct\n");
dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
TRACE("dwOldPos=%ld lpck->dwDataOffset = %ld\n", dwOldPos, lpck->dwDataOffset);
TRACE("dwOldPos=%d lpck->dwDataOffset = %d\n", dwOldPos, lpck->dwDataOffset);
dwNewSize = dwOldPos - lpck->dwDataOffset;
if (dwNewSize != lpck->cksize) {
TRACE("Nope: lpck->cksize=%ld dwNewSize=%ld\n", lpck->cksize, dwNewSize);
TRACE("Nope: lpck->cksize=%d dwNewSize=%d\n", lpck->cksize, dwNewSize);
lpck->cksize = dwNewSize;
/* pad odd size with 0 */
@ -1283,7 +1258,7 @@ MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO* lpck, UINT uFlags)
TRACE("(%p, %p, %04X);\n", hmmio, lpck, uFlags);
dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
TRACE("dwOldPos=%ld\n", dwOldPos);
TRACE("dwOldPos=%d\n", dwOldPos);
if (uFlags == MMIO_CREATELIST)
lpck->ckid = FOURCC_LIST;
@ -1300,7 +1275,7 @@ MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO* lpck, UINT uFlags)
lpck->dwFlags = MMIO_DIRTY;
ix = mmioWrite(hmmio, (LPSTR)lpck, size);
TRACE("after mmioWrite ix = %ld req = %ld, errno = %d\n",ix, size, errno);
TRACE("after mmioWrite ix = %d req = %d, errno = %d\n", ix, size, errno);
if (ix < size) {
mmioSeek(hmmio, dwOldPos, SEEK_SET);
WARN("return CannotWrite\n");
@ -1320,7 +1295,7 @@ MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
struct IOProcList tmp;
FOURCC fcc;
TRACE("('%s', '%s', %p, %08lX);\n",
TRACE("('%s', '%s', %p, %08X);\n",
debugstr_a(szFileName), debugstr_a(szNewFileName), lpmmioinfo, dwFlags);
/* If both params are NULL, then parse the file name */
@ -1341,7 +1316,7 @@ MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
ioProc = &tmp;
tmp.fourCC = lpmmioinfo->fccIOProc;
tmp.pIOProc = lpmmioinfo->pIOProc;
tmp.type = MMIO_PROC_32A;
tmp.is_unicode = FALSE;
tmp.count = 1;
}
@ -1349,7 +1324,7 @@ MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
* or make a copy of it because it's const ???
*/
return send_message(ioProc, (MMIOINFO*)lpmmioinfo, MMIOM_RENAME,
(LPARAM)szFileName, (LPARAM)szNewFileName, MMIO_PROC_32A);
(LPARAM)szFileName, (LPARAM)szNewFileName, FALSE);
}
/**************************************************************************

File diff suppressed because it is too large Load diff

View file

@ -1,176 +0,0 @@
1 pascal WEP(word word word ptr) MMSYSTEM_WEP
2 pascal sndPlaySound(ptr word) sndPlaySound16
3 pascal PlaySound(ptr word long) PlaySound16
4 pascal DllEntryPoint(long word word word long word) MMSYSTEM_LibMain
5 pascal mmsystemGetVersion() mmsystemGetVersion16
6 pascal DriverProc(long word word long long) DriverProc16
8 pascal WMMMidiRunOnce() WMMMidiRunOnce16
30 pascal -ret16 OutputDebugStr(str) OutputDebugStr16
31 pascal DriverCallback(long word word word long long long) DriverCallback16
32 pascal StackEnter() StackEnter16
33 pascal StackLeave() StackLeave16
34 stub MMDRVINSTALL
101 pascal joyGetNumDevs() joyGetNumDevs16
102 pascal joyGetDevCaps(word ptr word) joyGetDevCaps16
103 pascal joyGetPos(word ptr) joyGetPos16
104 pascal joyGetThreshold(word ptr) joyGetThreshold16
105 pascal joyReleaseCapture(word) joyReleaseCapture16
106 pascal joySetCapture(word word word word) joySetCapture16
107 pascal joySetThreshold(word word) joySetThreshold16
109 pascal joySetCalibration(word) joySetCalibration16
110 pascal joyGetPosEx(word ptr) joyGetPosEx16
111 stub JOYCONFIGCHANGED
201 pascal midiOutGetNumDevs() midiOutGetNumDevs16
202 pascal midiOutGetDevCaps(word ptr word) midiOutGetDevCaps16
203 pascal midiOutGetErrorText(word ptr word) midiOutGetErrorText16
204 pascal midiOutOpen(ptr word long long long) midiOutOpen16
205 pascal midiOutClose(word) midiOutClose16
206 pascal midiOutPrepareHeader(word segptr word) midiOutPrepareHeader16
207 pascal midiOutUnprepareHeader(word segptr word) midiOutUnprepareHeader16
208 pascal midiOutShortMsg(word long) midiOutShortMsg16
209 pascal midiOutLongMsg(word segptr word) midiOutLongMsg16
210 pascal midiOutReset(word) midiOutReset16
211 pascal midiOutGetVolume(word ptr) midiOutGetVolume16
212 pascal midiOutSetVolume(word long) midiOutSetVolume16
213 pascal midiOutCachePatches(word word ptr word) midiOutCachePatches16
214 pascal midiOutCacheDrumPatches(word word ptr word) midiOutCacheDrumPatches16
215 pascal midiOutGetID(word ptr) midiOutGetID16
216 pascal midiOutMessage(word word long long) midiOutMessage16
250 pascal midiStreamProperty(word ptr long) midiStreamProperty16
251 pascal midiStreamOpen(ptr ptr long long long long) midiStreamOpen16
252 pascal midiStreamClose(word) midiStreamClose16
253 pascal midiStreamPosition(word ptr word) midiStreamPosition16
254 pascal midiStreamOut(word ptr word) midiStreamOut16
255 pascal midiStreamPause(word) midiStreamPause16
256 pascal midiStreamRestart(word) midiStreamRestart16
257 pascal midiStreamStop(word) midiStreamStop16
301 pascal midiInGetNumDevs() midiInGetNumDevs16
302 pascal midiInGetDevCaps(word ptr word) midiInGetDevCaps16
303 pascal midiInGetErrorText(word ptr word) midiOutGetErrorText16
304 pascal midiInOpen(ptr word long long long) midiInOpen16
305 pascal midiInClose(word) midiInClose16
306 pascal midiInPrepareHeader(word segptr word) midiInPrepareHeader16
307 pascal midiInUnprepareHeader(word segptr word) midiInUnprepareHeader16
308 pascal midiInAddBuffer(word segptr word) midiInAddBuffer16
309 pascal midiInStart(word) midiInStart16
310 pascal midiInStop(word) midiInStop16
311 pascal midiInReset(word) midiInReset16
312 pascal midiInGetID(word ptr) midiInGetID16
313 pascal midiInMessage(word word long long) midiInMessage16
350 pascal auxGetNumDevs() auxGetNumDevs16
351 pascal auxGetDevCaps(word ptr word) auxGetDevCaps16
352 pascal auxGetVolume(word ptr) auxGetVolume16
353 pascal auxSetVolume(word long) auxSetVolume16
354 pascal auxOutMessage(word word long long) auxOutMessage16
401 pascal waveOutGetNumDevs() waveOutGetNumDevs16
402 pascal waveOutGetDevCaps(word ptr word) waveOutGetDevCaps16
403 pascal waveOutGetErrorText(word ptr word) waveOutGetErrorText16
404 pascal waveOutOpen(ptr word ptr long long long) waveOutOpen16
405 pascal waveOutClose(word) waveOutClose16
406 pascal waveOutPrepareHeader(word segptr word) waveOutPrepareHeader16
407 pascal waveOutUnprepareHeader(word segptr word) waveOutUnprepareHeader16
408 pascal waveOutWrite(word segptr word) waveOutWrite16
409 pascal waveOutPause(word) waveOutPause16
410 pascal waveOutRestart(word) waveOutRestart16
411 pascal waveOutReset(word) waveOutReset16
412 pascal waveOutGetPosition(word ptr word) waveOutGetPosition16
413 pascal waveOutGetPitch(word ptr) waveOutGetPitch16
414 pascal waveOutSetPitch(word long) waveOutSetPitch16
415 pascal waveOutGetVolume(word ptr) waveOutGetVolume16
416 pascal waveOutSetVolume(word long) waveOutSetVolume16
417 pascal waveOutGetPlaybackRate(word ptr) waveOutGetPlaybackRate16
418 pascal waveOutSetPlaybackRate(word long) waveOutSetPlaybackRate16
419 pascal waveOutBreakLoop(word) waveOutBreakLoop16
420 pascal waveOutGetID(word ptr) waveOutGetID16
421 pascal waveOutMessage(word word long long) waveOutMessage16
501 pascal waveInGetNumDevs() waveInGetNumDevs16
502 pascal waveInGetDevCaps(word ptr word) waveInGetDevCaps16
503 pascal waveInGetErrorText(word ptr word) waveOutGetErrorText16
504 pascal waveInOpen(ptr word ptr long long long) waveInOpen16
505 pascal waveInClose(word) waveInClose16
506 pascal waveInPrepareHeader(word segptr word) waveInPrepareHeader16
507 pascal waveInUnprepareHeader(word segptr word) waveInUnprepareHeader16
508 pascal waveInAddBuffer(word segptr word) waveInAddBuffer16
509 pascal waveInStart(word) waveInStart16
510 pascal waveInStop(word) waveInStop16
511 pascal waveInReset(word) waveInReset16
512 pascal waveInGetPosition(word ptr word) waveInGetPosition16
513 pascal waveInGetID(word ptr) waveInGetID16
514 pascal waveInMessage(word word long long) waveInMessage16
601 pascal timeGetSystemTime(ptr word) timeGetSystemTime16
602 pascal timeSetEvent(word word segptr long word) timeSetEvent16
603 pascal timeKillEvent(word) timeKillEvent16
604 pascal timeGetDevCaps(ptr word) timeGetDevCaps16
605 pascal timeBeginPeriod(word) timeBeginPeriod16
606 pascal timeEndPeriod(word) timeEndPeriod16
607 pascal timeGetTime() timeGetTime
701 pascal mciSendCommand(word word long long) mciSendCommand16
702 pascal mciSendString(str ptr word word) mciSendString16
703 pascal mciGetDeviceID(ptr) mciGetDeviceID16
705 pascal mciLoadCommandResource(word str word) mciLoadCommandResource16
706 pascal mciGetErrorString(long ptr word) mciGetErrorString16
707 pascal mciSetDriverData(word long) mciSetDriverData16
708 pascal mciGetDriverData(word) mciGetDriverData16
710 pascal mciDriverYield(word) mciDriverYield16
711 pascal mciDriverNotify(word word word) mciDriverNotify16
712 pascal mciExecute(ptr) mciExecute
713 pascal mciFreeCommandResource(word) mciFreeCommandResource16
714 pascal mciSetYieldProc(word ptr long) mciSetYieldProc16
715 pascal mciGetDeviceIDFromElementID(long ptr) mciGetDeviceIDFromElementID16
716 pascal mciGetYieldProc(word ptr) mciGetYieldProc16
717 pascal mciGetCreatorTask(word) mciGetCreatorTask16
800 pascal mixerGetNumDevs() mixerGetNumDevs16
801 pascal mixerGetDevCaps(word ptr word) mixerGetDevCaps16
802 pascal mixerOpen(ptr word long long long) mixerOpen16
803 pascal mixerClose(word) mixerClose16
804 pascal mixerMessage(word word long long) mixerMessage16
805 pascal mixerGetLineInfo(word ptr long) mixerGetLineInfo16
806 pascal mixerGetID(word ptr long) mixerGetID16
807 pascal mixerGetLineControls(word ptr long) mixerGetLineControls16
808 pascal mixerGetControlDetails(word ptr long) mixerGetControlDetails16
809 pascal mixerSetControlDetails(word ptr long) mixerSetControlDetails16
900 pascal mmTaskCreate(long ptr long) mmTaskCreate16
902 pascal mmTaskBlock(word) mmTaskBlock16
903 pascal mmTaskSignal(word) mmTaskSignal16
904 pascal -ret16 mmGetCurrentTask() mmGetCurrentTask16
905 pascal mmTaskYield() mmTaskYield16
1100 pascal DrvOpen(str str long) DrvOpen16
1101 pascal DrvClose(word long long) DrvClose16
1102 pascal DrvSendMessage(word word long long) DrvSendMessage16
1103 pascal DrvGetModuleHandle(word) DrvGetModuleHandle16
1104 pascal DrvDefDriverProc(long word word long long) DrvDefDriverProc16
1120 pascal mmThreadCreate(segptr ptr long long) mmThreadCreate16
1121 pascal mmThreadSignal(word) mmThreadSignal16
1122 pascal mmThreadBlock(word) mmThreadBlock16
1123 pascal mmThreadIsCurrent(word) mmThreadIsCurrent16
1124 pascal mmThreadIsValid(word) mmThreadIsValid16
1125 pascal mmThreadGetTask(word) mmThreadGetTask16
1150 pascal mmShowMMCPLPropertySheet(word str str str) mmShowMMCPLPropertySheet16
1210 pascal mmioOpen(str ptr long) mmioOpen16
1211 pascal mmioClose(word word) mmioClose16
1212 pascal mmioRead(word ptr long) mmioRead16
1213 pascal mmioWrite(word ptr long) mmioWrite16
1214 pascal mmioSeek(word long word) mmioSeek16
1215 pascal mmioGetInfo(word ptr word) mmioGetInfo16
1216 pascal mmioSetInfo(word ptr word) mmioSetInfo16
1217 pascal mmioSetBuffer(word segptr long word) mmioSetBuffer16
1218 pascal mmioFlush(word word) mmioFlush16
1219 pascal mmioAdvance(word ptr word) mmioAdvance16
1220 pascal mmioStringToFOURCC(str word) mmioStringToFOURCC16
1221 pascal mmioInstallIOProc(long ptr long) mmioInstallIOProc16
1222 pascal mmioSendMessage(word word long long) mmioSendMessage16
1223 pascal mmioDescend(word ptr ptr word) mmioDescend16
1224 pascal mmioAscend(word ptr word) mmioAscend16
1225 pascal mmioCreateChunk(word ptr word) mmioCreateChunk16
1226 pascal mmioRename(ptr ptr ptr long) mmioRename16
#2000 stub WINMMF_THUNKDATA16
#2001 stub RING3_DEVLOADER
#2002 stub WINMMTILEBUFFER
#2003 stub WINMMUNTILEBUFFER
#2005 stub MCIGETTHUNKTABLE
#2006 stub WINMMSL_THUNKDATA16
# these are Wine only exported functions. Is there another way to do it ?
2047 pascal __wine_mmThreadEntryPoint(long) WINE_mmThreadEntryPoint

View file

@ -1,7 +1,7 @@
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*
* MMSYTEM functions
* MMSYSTEM functions
*
* Copyright 1993 Martin Ayotte
* 1998-2002 Eric Pouech
@ -18,7 +18,7 @@
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
@ -37,6 +37,20 @@
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
typedef struct tagWINE_PLAYSOUND
{
unsigned bLoop : 1,
bAlloc : 1;
LPCWSTR pszSound;
HMODULE hMod;
DWORD fdwSound;
HANDLE hThread;
HWAVEOUT hWave;
struct tagWINE_PLAYSOUND* lpNext;
} WINE_PLAYSOUND;
static WINE_PLAYSOUND *PlaySoundList;
static HMMIO get_mmioFromFile(LPCWSTR lpszName)
{
HMMIO ret;
@ -133,19 +147,19 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
hmmio = mmioOpenW(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
if (hmmio) return hmmio;
none:
WARN("can't find SystemSound='%s' !\n", debugstr_w(lpszName));
WARN("can't find SystemSound=%s !\n", debugstr_w(lpszName));
return 0;
}
struct playsound_data
{
HANDLE hEvent;
DWORD dwEventCount;
LONG dwEventCount;
};
static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg,
DWORD dwInstance,
DWORD dwParam1, DWORD dwParam2)
DWORD_PTR dwInstance,
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
struct playsound_data* s = (struct playsound_data*)dwInstance;
@ -154,7 +168,7 @@ static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg,
case WOM_CLOSE:
break;
case WOM_DONE:
InterlockedIncrement((PLONG)&s->dwEventCount);
InterlockedIncrement(&s->dwEventCount);
TRACE("Returning waveHdr=%lx\n", dwParam1);
SetEvent(s->hEvent);
break;
@ -167,8 +181,8 @@ static void PlaySound_WaitDone(struct playsound_data* s)
{
for (;;) {
ResetEvent(s->hEvent);
if (InterlockedDecrement((PLONG)&s->dwEventCount) >= 0) break;
InterlockedIncrement((PLONG)&s->dwEventCount);
if (InterlockedDecrement(&s->dwEventCount) >= 0) break;
InterlockedIncrement(&s->dwEventCount);
WaitForSingleObject(s->hEvent, INFINITE);
}
@ -179,11 +193,12 @@ static BOOL PlaySound_IsString(DWORD fdwSound, const void* psz)
/* SND_RESOURCE is 0x40004 while
* SND_MEMORY is 0x00004
*/
switch (fdwSound & (SND_RESOURCE|SND_ALIAS|SND_FILENAME))
switch (fdwSound & (SND_RESOURCE|SND_ALIAS_ID|SND_FILENAME))
{
case SND_RESOURCE: return HIWORD(psz) != 0; /* by name or by ID ? */
case SND_ALIAS_ID:
case SND_MEMORY: return FALSE;
case SND_ALIAS: /* what about ALIAS_ID ??? */
case SND_ALIAS:
case SND_FILENAME:
case 0: return TRUE;
default: FIXME("WTF\n"); return FALSE;
@ -194,11 +209,11 @@ static void PlaySound_Free(WINE_PLAYSOUND* wps)
{
WINE_PLAYSOUND** p;
EnterCriticalSection(&WINMM_IData.cs);
for (p = &WINMM_IData.lpPlaySound; *p && *p != wps; p = &((*p)->lpNext));
EnterCriticalSection(&WINMM_cs);
for (p = &PlaySoundList; *p && *p != wps; p = &((*p)->lpNext));
if (*p) *p = (*p)->lpNext;
if (WINMM_IData.lpPlaySound == NULL) SetEvent(WINMM_IData.psLastEvent);
LeaveCriticalSection(&WINMM_IData.cs);
if (PlaySoundList == NULL) SetEvent(psLastEvent);
LeaveCriticalSection(&WINMM_cs);
if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound);
if (wps->hThread) CloseHandle(wps->hThread);
HeapFree(GetProcessHeap(), 0, wps);
@ -220,10 +235,10 @@ static WINE_PLAYSOUND* PlaySound_Alloc(const void* pszSound, HMODULE hmod,
{
if (fdwSound & SND_ASYNC)
{
wps->pszSound = HeapAlloc(GetProcessHeap(), 0,
(lstrlenW(pszSound)+1) * sizeof(WCHAR));
if (!wps->pszSound) goto oom_error;
lstrcpyW((LPWSTR)wps->pszSound, pszSound);
LPWSTR sound = HeapAlloc(GetProcessHeap(), 0,
(lstrlenW(pszSound)+1) * sizeof(WCHAR));
if (!sound) goto oom_error;
wps->pszSound = lstrcpyW(sound, pszSound);
wps->bAlloc = TRUE;
}
else
@ -249,13 +264,12 @@ static WINE_PLAYSOUND* PlaySound_Alloc(const void* pszSound, HMODULE hmod,
static DWORD WINAPI proc_PlaySound(LPVOID arg)
{
WINE_PLAYSOUND* wps = (WINE_PLAYSOUND*)arg;
WINE_PLAYSOUND* wps = arg;
BOOL bRet = FALSE;
HMMIO hmmio = 0;
MMCKINFO ckMainRIFF;
MMCKINFO mmckInfo;
LPWAVEFORMATEX lpWaveFormat = NULL;
HWAVEOUT hWave = 0;
LPWAVEHDR waveHdr = NULL;
INT count, bufsize, left, index;
struct playsound_data s;
@ -263,7 +277,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
s.hEvent = 0;
TRACE("SoundName='%s' !\n", debugstr_w(wps->pszSound));
TRACE("SoundName=%s !\n", debugstr_w(wps->pszSound));
/* if resource, grab it */
if ((wps->fdwSound & SND_RESOURCE) == SND_RESOURCE) {
@ -289,13 +303,43 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
memset(&mminfo, 0, sizeof(mminfo));
mminfo.fccIOProc = FOURCC_MEM;
mminfo.pchBuffer = (LPSTR)data;
mminfo.pchBuffer = data;
mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */
TRACE("Memory sound %p\n", data);
hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ);
}
else if (wps->fdwSound & SND_ALIAS)
{
if ((wps->fdwSound & SND_ALIAS_ID) == SND_ALIAS_ID)
{
static const WCHAR wszSystemAsterisk[] = {'S','y','s','t','e','m','A','s','t','e','r','i','s','k',0};
static const WCHAR wszSystemDefault[] = {'S','y','s','t','e','m','D','e','f','a','u','l','t',0};
static const WCHAR wszSystemExclamation[] = {'S','y','s','t','e','m','E','x','c','l','a','m','a','t','i','o','n',0};
static const WCHAR wszSystemExit[] = {'S','y','s','t','e','m','E','x','i','t',0};
static const WCHAR wszSystemHand[] = {'S','y','s','t','e','m','H','a','n','d',0};
static const WCHAR wszSystemQuestion[] = {'S','y','s','t','e','m','Q','u','e','s','t','i','o','n',0};
static const WCHAR wszSystemStart[] = {'S','y','s','t','e','m','S','t','a','r','t',0};
static const WCHAR wszSystemWelcome[] = {'S','y','s','t','e','m','W','e','l','c','o','m','e',0};
wps->fdwSound &= ~(SND_ALIAS_ID ^ SND_ALIAS);
if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMASTERISK)
wps->pszSound = wszSystemAsterisk;
else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMDEFAULT)
wps->pszSound = wszSystemDefault;
else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMEXCLAMATION)
wps->pszSound = wszSystemExclamation;
else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMEXIT)
wps->pszSound = wszSystemExit;
else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMHAND)
wps->pszSound = wszSystemHand;
else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMQUESTION)
wps->pszSound = wszSystemQuestion;
else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMSTART)
wps->pszSound = wszSystemStart;
else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMWELCOME)
wps->pszSound = wszSystemWelcome;
else goto errCleanUp;
}
hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
}
else if (wps->fdwSound & SND_FILENAME)
@ -317,7 +361,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0))
goto errCleanUp;
TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n",
(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
@ -328,18 +372,18 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
goto errCleanUp;
TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
(LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(WAVEFORMAT))
if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(PCMWAVEFORMAT))
goto errCleanUp;
TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag);
TRACE("nChannels=%d \n", lpWaveFormat->nChannels);
TRACE("nSamplesPerSec=%ld\n", lpWaveFormat->nSamplesPerSec);
TRACE("nAvgBytesPerSec=%ld\n", lpWaveFormat->nAvgBytesPerSec);
TRACE("nBlockAlign=%d \n", lpWaveFormat->nBlockAlign);
TRACE("nChannels=%d\n", lpWaveFormat->nChannels);
TRACE("nSamplesPerSec=%d\n", lpWaveFormat->nSamplesPerSec);
TRACE("nAvgBytesPerSec=%d\n", lpWaveFormat->nAvgBytesPerSec);
TRACE("nBlockAlign=%d\n", lpWaveFormat->nBlockAlign);
TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample);
/* move to end of 'fmt ' chunk */
@ -349,13 +393,13 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
goto errCleanUp;
TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX\n",
(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
(LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
s.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if (waveOutOpen(&hWave, WAVE_MAPPER, lpWaveFormat, (DWORD)PlaySound_Callback,
(DWORD)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
if (waveOutOpen(&wps->hWave, WAVE_MAPPER, lpWaveFormat, (DWORD_PTR)PlaySound_Callback,
(DWORD_PTR)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
goto errCleanUp;
/* make it so that 3 buffers per second are needed */
@ -368,8 +412,8 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
if (waveOutPrepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
waveOutPrepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR))) {
if (waveOutPrepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
waveOutPrepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
goto errCleanUp;
}
@ -382,7 +426,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
while (left)
{
if (WaitForSingleObject(WINMM_IData.psStopEvent, 0) == WAIT_OBJECT_0)
if (WaitForSingleObject(psStopEvent, 0) == WAIT_OBJECT_0)
{
wps->bLoop = FALSE;
break;
@ -392,7 +436,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
left -= count;
waveHdr[index].dwBufferLength = count;
waveHdr[index].dwFlags &= ~WHDR_DONE;
if (waveOutWrite(hWave, &waveHdr[index], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) {
if (waveOutWrite(wps->hWave, &waveHdr[index], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) {
index ^= 1;
PlaySound_WaitDone(&s);
}
@ -402,17 +446,17 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
} while (wps->bLoop);
PlaySound_WaitDone(&s); /* for last buffer */
waveOutReset(hWave);
waveOutReset(wps->hWave);
waveOutUnprepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR));
waveOutUnprepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR));
waveOutUnprepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR));
waveOutUnprepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR));
errCleanUp:
TRACE("Done playing='%s' => %s!\n", debugstr_w(wps->pszSound), bRet ? "ok" : "ko");
TRACE("Done playing=%s => %s!\n", debugstr_w(wps->pszSound), bRet ? "ok" : "ko");
CloseHandle(s.hEvent);
HeapFree(GetProcessHeap(), 0, waveHdr);
HeapFree(GetProcessHeap(), 0, lpWaveFormat);
if (hWave) while (waveOutClose(hWave) == WAVERR_STILLPLAYING) Sleep(100);
if (wps->hWave) while (waveOutClose(wps->hWave) == WAVERR_STILLPLAYING) Sleep(100);
if (hmmio) mmioClose(hmmio, 0);
PlaySound_Free(wps);
@ -424,13 +468,13 @@ static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSo
{
WINE_PLAYSOUND* wps = NULL;
TRACE("pszSound='%p' hmod=%p fdwSound=%08lX\n",
TRACE("pszSound='%p' hmod=%p fdwSound=%08X\n",
pszSound, hmod, fdwSound);
/* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP !
* there could be one if several sounds can be played at once...
*/
if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && WINMM_IData.lpPlaySound != NULL)
if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && PlaySoundList != NULL)
return FALSE;
/* alloc internal structure, if we need to play something */
@ -440,27 +484,28 @@ static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSo
return FALSE;
}
EnterCriticalSection(&WINMM_IData.cs);
EnterCriticalSection(&WINMM_cs);
/* since several threads can enter PlaySound in parallel, we're not
* sure, at this point, that another thread didn't start a new playsound
*/
while (WINMM_IData.lpPlaySound != NULL)
while (PlaySoundList != NULL)
{
ResetEvent(WINMM_IData.psLastEvent);
ResetEvent(psLastEvent);
/* FIXME: doc says we have to stop all instances of pszSound if it's non
* NULL... as of today, we stop all playing instances */
SetEvent(WINMM_IData.psStopEvent);
SetEvent(psStopEvent);
LeaveCriticalSection(&WINMM_IData.cs);
WaitForSingleObject(WINMM_IData.psLastEvent, INFINITE);
EnterCriticalSection(&WINMM_IData.cs);
waveOutReset(PlaySoundList->hWave);
LeaveCriticalSection(&WINMM_cs);
WaitForSingleObject(psLastEvent, INFINITE);
EnterCriticalSection(&WINMM_cs);
ResetEvent(WINMM_IData.psStopEvent);
ResetEvent(psStopEvent);
}
if (wps) wps->lpNext = WINMM_IData.lpPlaySound;
WINMM_IData.lpPlaySound = wps;
LeaveCriticalSection(&WINMM_IData.cs);
if (wps) wps->lpNext = PlaySoundList;
PlaySoundList = wps;
LeaveCriticalSection(&WINMM_cs);
if (!pszSound || (fdwSound & SND_PURGE)) return TRUE;

View file

@ -1,18 +0,0 @@
1 pascal -ret16 OpenSound() OpenSound16
2 pascal -ret16 CloseSound() CloseSound16
3 pascal -ret16 SetVoiceQueueSize(word word) SetVoiceQueueSize16
4 pascal -ret16 SetVoiceNote(word word word word) SetVoiceNote16
5 pascal -ret16 SetVoiceAccent(word word word word word) SetVoiceAccent16
6 pascal -ret16 SetVoiceEnvelope(word word word) SetVoiceEnvelope16
7 pascal -ret16 SetSoundNoise(word word) SetSoundNoise16
8 pascal -ret16 SetVoiceSound(word long word) SetVoiceSound16
9 pascal -ret16 StartSound() StartSound16
10 pascal -ret16 StopSound() StopSound16
11 pascal -ret16 WaitSoundState(word) WaitSoundState16
12 pascal -ret16 SyncAllVoices() SyncAllVoices16
13 pascal -ret16 CountVoiceNotes(word) CountVoiceNotes16
14 pascal GetThresholdEvent() GetThresholdEvent16
15 pascal -ret16 GetThresholdStatus() GetThresholdStatus16
16 pascal -ret16 SetVoiceThreshold(word word) SetVoiceThreshold16
17 pascal -ret16 DoBeep() DoBeep16
18 stub MYOPENSOUND # W1.1, W2.0

View file

@ -1,184 +0,0 @@
/*
* 16-bit sound support
*
* Copyright Robert J. Amstadt, 1993
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdarg.h>
#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "wine/windef16.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(sound);
/***********************************************************************
* OpenSound (SOUND.1)
*/
INT16 WINAPI OpenSound16(void)
{
FIXME("(void): stub\n");
return -1;
}
/***********************************************************************
* CloseSound (SOUND.2)
*/
void WINAPI CloseSound16(void)
{
FIXME("(void): stub\n");
}
/***********************************************************************
* SetVoiceQueueSize (SOUND.3)
*/
INT16 WINAPI SetVoiceQueueSize16(INT16 nVoice, INT16 nBytes)
{
FIXME("(%d,%d): stub\n",nVoice,nBytes);
return 0;
}
/***********************************************************************
* SetVoiceNote (SOUND.4)
*/
INT16 WINAPI SetVoiceNote16(INT16 nVoice, INT16 nValue, INT16 nLength,
INT16 nCdots)
{
FIXME("(%d,%d,%d,%d): stub\n",nVoice,nValue,nLength,nCdots);
return 0;
}
/***********************************************************************
* SetVoiceAccent (SOUND.5)
*/
INT16 WINAPI SetVoiceAccent16(INT16 nVoice, INT16 nTempo, INT16 nVolume,
INT16 nMode, INT16 nPitch)
{
FIXME("(%d,%d,%d,%d,%d): stub\n", nVoice, nTempo,
nVolume, nMode, nPitch);
return 0;
}
/***********************************************************************
* SetVoiceEnvelope (SOUND.6)
*/
INT16 WINAPI SetVoiceEnvelope16(INT16 nVoice, INT16 nShape, INT16 nRepeat)
{
FIXME("(%d,%d,%d): stub\n",nVoice,nShape,nRepeat);
return 0;
}
/***********************************************************************
* SetSoundNoise (SOUND.7)
*/
INT16 WINAPI SetSoundNoise16(INT16 nSource, INT16 nDuration)
{
FIXME("(%d,%d): stub\n",nSource,nDuration);
return 0;
}
/***********************************************************************
* SetVoiceSound (SOUND.8)
*/
INT16 WINAPI SetVoiceSound16(INT16 nVoice, DWORD lFrequency, INT16 nDuration)
{
FIXME("(%d, %ld, %d): stub\n",nVoice,lFrequency, nDuration);
return 0;
}
/***********************************************************************
* StartSound (SOUND.9)
*/
INT16 WINAPI StartSound16(void)
{
return 0;
}
/***********************************************************************
* StopSound (SOUND.10)
*/
INT16 WINAPI StopSound16(void)
{
return 0;
}
/***********************************************************************
* WaitSoundState (SOUND.11)
*/
INT16 WINAPI WaitSoundState16(INT16 x)
{
FIXME("(%d): stub\n", x);
return 0;
}
/***********************************************************************
* SyncAllVoices (SOUND.12)
*/
INT16 WINAPI SyncAllVoices16(void)
{
FIXME("(void): stub\n");
return 0;
}
/***********************************************************************
* CountVoiceNotes (SOUND.13)
*/
INT16 WINAPI CountVoiceNotes16(INT16 x)
{
FIXME("(%d): stub\n", x);
return 0;
}
/***********************************************************************
* GetThresholdEvent (SOUND.14)
*/
LPINT16 WINAPI GetThresholdEvent16(void)
{
FIXME("(void): stub\n");
return NULL;
}
/***********************************************************************
* GetThresholdStatus (SOUND.15)
*/
INT16 WINAPI GetThresholdStatus16(void)
{
FIXME("(void): stub\n");
return 0;
}
/***********************************************************************
* SetVoiceThreshold (SOUND.16)
*/
INT16 WINAPI SetVoiceThreshold16(INT16 a, INT16 b)
{
FIXME("(%d,%d): stub\n", a, b);
return 0;
}
/***********************************************************************
* DoBeep (SOUND.17)
*/
void WINAPI DoBeep16(void)
{
FIXME("(void): stub!\n");
}

View file

@ -17,13 +17,14 @@
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <errno.h>
#include <time.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
@ -31,6 +32,12 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
#include "windef.h"
#include "winbase.h"
@ -38,15 +45,47 @@
#include "winemm.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(mmtime);
typedef struct tagWINE_TIMERENTRY {
struct list entry;
UINT wDelay;
UINT wResol;
LPTIMECALLBACK lpFunc; /* can be lots of things */
DWORD_PTR dwUser;
UINT16 wFlags;
UINT16 wTimerID;
DWORD dwTriggerTime;
} WINE_TIMERENTRY, *LPWINE_TIMERENTRY;
static struct list timer_list = LIST_INIT(timer_list);
static CRITICAL_SECTION TIME_cbcrst;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &TIME_cbcrst,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": TIME_cbcrst") }
};
static CRITICAL_SECTION TIME_cbcrst = { &critsect_debug, -1, 0, 0, 0, 0 };
static HANDLE TIME_hMMTimer;
static LPWINE_TIMERENTRY TIME_TimersList;
static HANDLE TIME_hKillEvent;
static HANDLE TIME_hWakeEvent;
static BOOL TIME_TimeToDie = TRUE;
static int TIME_fdWake[2] = { -1, -1 };
/* link timer at the appropriate spot in the list */
static inline void link_timer( WINE_TIMERENTRY *timer )
{
WINE_TIMERENTRY *next;
LIST_FOR_EACH_ENTRY( next, &timer_list, WINE_TIMERENTRY, entry )
if ((int)(next->dwTriggerTime - timer->dwTriggerTime) >= 0) break;
list_add_before( &next->entry, &timer->entry );
}
/*
* Some observations on the behavior of winmm on Windows.
@ -77,58 +116,15 @@ static BOOL TIME_TimeToDie = TRUE;
#define MMSYSTIME_MININTERVAL (1)
#define MMSYSTIME_MAXINTERVAL (65535)
static void TIME_TriggerCallBack(LPWINE_TIMERENTRY lpTimer)
{
TRACE("%04lx:CallBack => lpFunc=%p wTimerID=%04X dwUser=%08lX dwTriggerTime %ld(delta %ld)\n",
GetCurrentThreadId(), lpTimer->lpFunc, lpTimer->wTimerID, lpTimer->dwUser,
lpTimer->dwTriggerTime, GetTickCount() - lpTimer->dwTriggerTime);
/* - TimeProc callback that is called here is something strange, under Windows 3.1x it is called
* during interrupt time, is allowed to execute very limited number of API calls (like
* PostMessage), and must reside in DLL (therefore uses stack of active application). So I
* guess current implementation via SetTimer has to be improved upon.
*/
switch (lpTimer->wFlags & 0x30) {
case TIME_CALLBACK_FUNCTION:
if (lpTimer->wFlags & WINE_TIMER_IS32)
(lpTimer->lpFunc)(lpTimer->wTimerID, 0, lpTimer->dwUser, 0, 0);
else if (pFnCallMMDrvFunc16)
pFnCallMMDrvFunc16((DWORD)lpTimer->lpFunc, lpTimer->wTimerID, 0,
lpTimer->dwUser, 0, 0);
break;
case TIME_CALLBACK_EVENT_SET:
SetEvent((HANDLE)lpTimer->lpFunc);
break;
case TIME_CALLBACK_EVENT_PULSE:
PulseEvent((HANDLE)lpTimer->lpFunc);
break;
default:
FIXME("Unknown callback type 0x%04x for mmtime callback (%p), ignored.\n",
lpTimer->wFlags, lpTimer->lpFunc);
break;
}
}
#ifdef HAVE_POLL
/**************************************************************************
* TIME_MMSysTimeCallback
*/
static DWORD CALLBACK TIME_MMSysTimeCallback(LPWINE_MM_IDATA iData)
static int TIME_MMSysTimeCallback(void)
{
static int nSizeLpTimers;
static LPWINE_TIMERENTRY lpTimers;
LPWINE_TIMERENTRY timer, *ptimer, *next_ptimer;
int idx;
DWORD cur_time;
DWORD delta_time;
DWORD ret_time = INFINITE;
DWORD adjust_time;
/* optimize for the most frequent case - no events */
if (! TIME_TimersList)
return(ret_time);
WINE_TIMERENTRY *timer, *to_free;
int delta_time;
/* since timeSetEvent() and timeKillEvent() can be called
* from 16 bit code, there are cases where win16 lock is
@ -140,84 +136,60 @@ static LPWINE_TIMERENTRY lpTimers;
* To cope with that, we just copy the WINE_TIMERENTRY struct
* that need to trigger the callback, and call it without the
* mm timer crit sect locked.
* the hKillTimeEvent is used to mark the section where we
* handle the callbacks so we can do synchronous kills.
* EPP 99/07/13, updated 04/01/10
*/
idx = 0;
cur_time = GetTickCount();
EnterCriticalSection(&iData->cs);
for (ptimer = &TIME_TimersList; *ptimer != NULL; ) {
timer = *ptimer;
next_ptimer = &timer->lpNext;
if (cur_time >= timer->dwTriggerTime)
EnterCriticalSection(&WINMM_cs);
for (;;)
{
struct list *ptr = list_head( &timer_list );
if (!ptr)
{
if (timer->lpFunc) {
if (idx == nSizeLpTimers) {
if (lpTimers)
lpTimers = (LPWINE_TIMERENTRY)
HeapReAlloc(GetProcessHeap(), 0, lpTimers,
++nSizeLpTimers * sizeof(WINE_TIMERENTRY));
else
lpTimers = (LPWINE_TIMERENTRY)
HeapAlloc(GetProcessHeap(), 0,
++nSizeLpTimers * sizeof(WINE_TIMERENTRY));
}
lpTimers[idx++] = *timer;
}
/* Update the time after we make the copy to preserve
the original trigger time */
timer->dwTriggerTime += timer->wDelay;
/* TIME_ONESHOT is defined as 0 */
if (!(timer->wFlags & TIME_PERIODIC))
{
/* unlink timer from timers list */
*ptimer = *next_ptimer;
HeapFree(GetProcessHeap(), 0, timer);
/* We don't need to trigger oneshots again */
delta_time = INFINITE;
}
else
{
/* Compute when this event needs this function
to be called again */
if (timer->dwTriggerTime <= cur_time)
delta_time = 0;
else
delta_time = timer->dwTriggerTime - cur_time;
}
delta_time = -1;
break;
}
else
delta_time = timer->dwTriggerTime - cur_time;
/* Determine when we need to return to this function */
ret_time = min(ret_time, delta_time);
timer = LIST_ENTRY( ptr, WINE_TIMERENTRY, entry );
delta_time = timer->dwTriggerTime - GetTickCount();
if (delta_time > 0) break;
ptimer = next_ptimer;
list_remove( &timer->entry );
if (timer->wFlags & TIME_PERIODIC)
{
timer->dwTriggerTime += timer->wDelay;
link_timer( timer ); /* restart it */
to_free = NULL;
}
else to_free = timer;
switch(timer->wFlags & (TIME_CALLBACK_EVENT_SET|TIME_CALLBACK_EVENT_PULSE))
{
case TIME_CALLBACK_EVENT_SET:
SetEvent(timer->lpFunc);
break;
case TIME_CALLBACK_EVENT_PULSE:
PulseEvent(timer->lpFunc);
break;
case TIME_CALLBACK_FUNCTION:
{
DWORD_PTR user = timer->dwUser;
UINT16 id = timer->wTimerID;
UINT16 flags = timer->wFlags;
LPTIMECALLBACK func = timer->lpFunc;
if (flags & TIME_KILL_SYNCHRONOUS) EnterCriticalSection(&TIME_cbcrst);
LeaveCriticalSection(&WINMM_cs);
func(id, 0, user, 0, 0);
EnterCriticalSection(&WINMM_cs);
if (flags & TIME_KILL_SYNCHRONOUS) LeaveCriticalSection(&TIME_cbcrst);
}
break;
}
HeapFree( GetProcessHeap(), 0, to_free );
}
if (TIME_hKillEvent) ResetEvent(TIME_hKillEvent);
LeaveCriticalSection(&iData->cs);
while (idx > 0) TIME_TriggerCallBack(&lpTimers[--idx]);
if (TIME_hKillEvent) SetEvent(TIME_hKillEvent);
/* Finally, adjust the recommended wait time downward
by the amount of time the processing routines
actually took */
adjust_time = GetTickCount() - cur_time;
if (adjust_time > ret_time)
ret_time = 0;
else
ret_time -= adjust_time;
/* We return the amount of time our caller should sleep
before needing to check in on us again */
return(ret_time);
LeaveCriticalSection(&WINMM_cs);
return delta_time;
}
/**************************************************************************
@ -225,9 +197,12 @@ static LPWINE_TIMERENTRY lpTimers;
*/
static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
{
LPWINE_MM_IDATA iData = (LPWINE_MM_IDATA)arg;
DWORD sleep_time;
DWORD rc;
int sleep_time, ret;
char readme[16];
struct pollfd pfd;
pfd.fd = TIME_fdWake[0];
pfd.events = POLLIN;
TRACE("Starting main winmm thread\n");
@ -239,17 +214,21 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
while (! TIME_TimeToDie)
{
sleep_time = TIME_MMSysTimeCallback(iData);
sleep_time = TIME_MMSysTimeCallback();
if (sleep_time == 0)
continue;
rc = WaitForSingleObject(TIME_hWakeEvent, sleep_time);
if (rc != WAIT_TIMEOUT && rc != WAIT_OBJECT_0)
if ((ret = poll(&pfd, 1, sleep_time)) < 0)
{
FIXME("Unexpected error %ld(%ld) in timer thread\n", rc, GetLastError());
break;
}
if (errno != EINTR && errno != EAGAIN)
{
ERR("Unexpected error in poll: %s(%d)\n", strerror(errno), errno);
break;
}
}
while (ret > 0) ret = read(TIME_fdWake[0], readme, sizeof(readme));
}
TRACE("Exiting main winmm thread\n");
return 0;
@ -258,34 +237,50 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
/**************************************************************************
* TIME_MMTimeStart
*/
void TIME_MMTimeStart(void)
static void TIME_MMTimeStart(void)
{
if (!TIME_hMMTimer) {
TIME_TimersList = NULL;
TIME_hWakeEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if (pipe(TIME_fdWake) < 0)
{
TIME_fdWake[0] = TIME_fdWake[1] = -1;
ERR("Cannot create pipe: %s\n", strerror(errno));
} else {
fcntl(TIME_fdWake[0], F_SETFL, O_NONBLOCK);
fcntl(TIME_fdWake[1], F_SETFL, O_NONBLOCK);
}
TIME_TimeToDie = FALSE;
TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, &WINMM_IData, 0, NULL);
TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, NULL, 0, NULL);
SetThreadPriority(TIME_hMMTimer, THREAD_PRIORITY_TIME_CRITICAL);
}
}
#else /* HAVE_POLL */
static void TIME_MMTimeStart(void)
{
FIXME( "not starting system thread\n" );
}
#endif /* HAVE_POLL */
/**************************************************************************
* TIME_MMTimeStop
*/
void TIME_MMTimeStop(void)
{
if (TIME_hMMTimer) {
const char a='a';
TIME_TimeToDie = TRUE;
SetEvent(TIME_hWakeEvent);
write(TIME_fdWake[1], &a, sizeof(a));
/* FIXME: in the worst case, we're going to wait 65 seconds here :-( */
WaitForSingleObject(TIME_hMMTimer, INFINITE);
CloseHandle(TIME_hMMTimer);
CloseHandle(TIME_hWakeEvent);
TIME_hMMTimer = 0;
TIME_TimersList = NULL;
WaitForSingleObject(TIME_hMMTimer, INFINITE);
close(TIME_fdWake[0]);
close(TIME_fdWake[1]);
TIME_fdWake[0] = TIME_fdWake[1] = -1;
CloseHandle(TIME_hMMTimer);
TIME_hMMTimer = 0;
DeleteCriticalSection(&TIME_cbcrst);
}
}
@ -305,14 +300,15 @@ MMRESULT WINAPI timeGetSystemTime(LPMMTIME lpTime, UINT wSize)
}
/**************************************************************************
* TIME_SetEventInternal [internal]
* timeSetEvent [WINMM.@]
*/
WORD TIME_SetEventInternal(UINT wDelay, UINT wResol,
LPTIMECALLBACK lpFunc, DWORD dwUser, UINT wFlags)
MMRESULT WINAPI timeSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc,
DWORD_PTR dwUser, UINT wFlags)
{
WORD wNewID = 0;
LPWINE_TIMERENTRY lpNewTimer;
LPWINE_TIMERENTRY lpTimer;
const char c = 'c';
TRACE("(%u, %u, %p, %08lX, %04X);\n", wDelay, wResol, lpFunc, dwUser, wFlags);
@ -323,8 +319,6 @@ WORD TIME_SetEventInternal(UINT wDelay, UINT wResol,
if (lpNewTimer == NULL)
return 0;
TIME_MMTimeStart();
lpNewTimer->wDelay = wDelay;
lpNewTimer->dwTriggerTime = GetTickCount() + wDelay;
@ -335,70 +329,58 @@ WORD TIME_SetEventInternal(UINT wDelay, UINT wResol,
lpNewTimer->dwUser = dwUser;
lpNewTimer->wFlags = wFlags;
EnterCriticalSection(&WINMM_IData.cs);
EnterCriticalSection(&WINMM_cs);
if ((wFlags & TIME_KILL_SYNCHRONOUS) && !TIME_hKillEvent)
TIME_hKillEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
LIST_FOR_EACH_ENTRY( lpTimer, &timer_list, WINE_TIMERENTRY, entry )
wNewID = max(wNewID, lpTimer->wTimerID);
for (lpTimer = TIME_TimersList; lpTimer != NULL; lpTimer = lpTimer->lpNext) {
wNewID = max(wNewID, lpTimer->wTimerID);
}
lpNewTimer->lpNext = TIME_TimersList;
TIME_TimersList = lpNewTimer;
link_timer( lpNewTimer );
lpNewTimer->wTimerID = wNewID + 1;
LeaveCriticalSection(&WINMM_IData.cs);
TIME_MMTimeStart();
LeaveCriticalSection(&WINMM_cs);
/* Wake the service thread in case there is work to be done */
SetEvent(TIME_hWakeEvent);
write(TIME_fdWake[1], &c, sizeof(c));
TRACE("=> %u\n", wNewID + 1);
return wNewID + 1;
}
/**************************************************************************
* timeSetEvent [WINMM.@]
*/
MMRESULT WINAPI timeSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc,
DWORD_PTR dwUser, UINT wFlags)
{
if (wFlags & WINE_TIMER_IS32)
WARN("Unknown windows flag... wine internally used.. ooch\n");
return TIME_SetEventInternal(wDelay, wResol, lpFunc,
dwUser, wFlags|WINE_TIMER_IS32);
}
/**************************************************************************
* timeKillEvent [WINMM.@]
*/
MMRESULT WINAPI timeKillEvent(UINT wID)
{
LPWINE_TIMERENTRY lpSelf = NULL, *lpTimer;
WINE_TIMERENTRY *lpSelf = NULL, *lpTimer;
DWORD wFlags;
TRACE("(%u)\n", wID);
EnterCriticalSection(&WINMM_IData.cs);
EnterCriticalSection(&WINMM_cs);
/* remove WINE_TIMERENTRY from list */
for (lpTimer = &TIME_TimersList; *lpTimer; lpTimer = &(*lpTimer)->lpNext) {
if (wID == (*lpTimer)->wTimerID) {
lpSelf = *lpTimer;
/* unlink timer of id 'wID' */
*lpTimer = (*lpTimer)->lpNext;
LIST_FOR_EACH_ENTRY( lpTimer, &timer_list, WINE_TIMERENTRY, entry )
{
if (wID == lpTimer->wTimerID) {
lpSelf = lpTimer;
list_remove( &lpTimer->entry );
break;
}
}
LeaveCriticalSection(&WINMM_IData.cs);
LeaveCriticalSection(&WINMM_cs);
if (!lpSelf)
{
WARN("wID=%u is not a valid timer ID\n", wID);
return MMSYSERR_INVALPARAM;
}
if (lpSelf->wFlags & TIME_KILL_SYNCHRONOUS)
WaitForSingleObject(TIME_hKillEvent, INFINITE);
wFlags = lpSelf->wFlags;
if (wFlags & TIME_KILL_SYNCHRONOUS)
EnterCriticalSection(&TIME_cbcrst);
HeapFree(GetProcessHeap(), 0, lpSelf);
if (wFlags & TIME_KILL_SYNCHRONOUS)
LeaveCriticalSection(&TIME_cbcrst);
return TIMERR_NOERROR;
}
@ -456,7 +438,6 @@ MMRESULT WINAPI timeEndPeriod(UINT wPeriod)
}
/**************************************************************************
* timeGetTime [MMSYSTEM.607]
* timeGetTime [WINMM.@]
*/
DWORD WINAPI timeGetTime(void)
@ -465,7 +446,7 @@ DWORD WINAPI timeGetTime(void)
DWORD count;
/* FIXME: releasing the win16 lock here is a temporary hack (I hope)
* that lets mciavi.drv run correctly
* that lets mciavi32.dll run correctly
*/
if (pFnReleaseThunkLock) pFnReleaseThunkLock(&count);
if (pFnRestoreThunkLock) pFnRestoreThunkLock(count);

View file

@ -1,6 +1,4 @@
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*****************************************************************************
/*
* Copyright 1998, Luiz Otavio L. Zorzella
* 1999, Eric Pouech
*
@ -18,8 +16,7 @@
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
@ -28,20 +25,10 @@
#include "winbase.h"
#include "mmddk.h"
#define WINE_DEFAULT_WINMM_DRIVER "oss"
#define WINE_DEFAULT_WINMM_MAPPER "msacm.drv"
#define WINE_DEFAULT_WINMM_DRIVER "alsa,oss,coreaudio,esd"
#define WINE_DEFAULT_WINMM_MAPPER "msacm32.drv"
#define WINE_DEFAULT_WINMM_MIDI "midimap.dll"
typedef DWORD (WINAPI *MessageProc16)(UINT16 wDevID, UINT16 wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
typedef DWORD (WINAPI *MessageProc32)(UINT wDevID, UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
typedef enum {
WINMM_MAP_NOMEM, /* ko, memory problem */
WINMM_MAP_MSGERROR, /* ko, unknown message */
WINMM_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
WINMM_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
} WINMM_MapType;
/* Who said goofy boy ? */
#define WINE_DI_MAGIC 0x900F1B01
@ -50,22 +37,14 @@ typedef struct tagWINE_DRIVER
DWORD dwMagic;
/* as usual LPWINE_DRIVER == hDriver32 */
DWORD dwFlags;
union {
struct {
HMODULE hModule;
DRIVERPROC lpDrvProc;
DWORD dwDriverID;
} d32;
struct {
UINT16 hDriver16;
} d16;
} d;
HMODULE hModule;
DRIVERPROC lpDrvProc;
DWORD_PTR dwDriverID;
struct tagWINE_DRIVER* lpPrevItem;
struct tagWINE_DRIVER* lpNextItem;
} WINE_DRIVER, *LPWINE_DRIVER;
typedef DWORD (CALLBACK *WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
typedef DWORD (CALLBACK *WINEMM_msgFunc32)(UINT , UINT, DWORD, DWORD, DWORD);
typedef DWORD (CALLBACK *WINEMM_msgFunc32)(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR);
/* for each loaded driver and each known type of driver, this structure contains
* the information needed to access it
@ -73,10 +52,7 @@ typedef DWORD (CALLBACK *WINEMM_msgFunc32)(UINT , UINT, DWORD, DWORD, DWORD);
typedef struct tagWINE_MM_DRIVER_PART {
int nIDMin; /* lower bound of global indexes for this type */
int nIDMax; /* hhigher bound of global indexes for this type */
union {
WINEMM_msgFunc32 fnMessage32; /* pointer to function */
WINEMM_msgFunc16 fnMessage16;
} u;
WINEMM_msgFunc32 fnMessage32; /* pointer to function */
} WINE_MM_DRIVER_PART;
#define MMDRV_AUX 0
@ -91,8 +67,7 @@ typedef struct tagWINE_MM_DRIVER_PART {
typedef struct tagWINE_MM_DRIVER {
HDRVR hDriver;
LPSTR drvname; /* name of the driver */
unsigned bIs32 : 1, /* TRUE if 32 bit driver, FALSE for 16 */
bIsMapper : 1; /* TRUE if mapper */
unsigned bIsMapper : 1; /* TRUE if mapper */
WINE_MM_DRIVER_PART parts[MMDRV_MAX];/* Information for all known types */
} WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
@ -101,12 +76,11 @@ typedef struct tagWINE_MLD {
UINT uDeviceID;
UINT type;
UINT mmdIndex; /* index to low-level driver in MMDrvs table */
DWORD dwDriverInstance; /* this value is driver related, as opposed to
DWORD_PTR dwDriverInstance; /* this value is driver related, as opposed to
* opendesc.dwInstance which is client (callback) related */
WORD bFrom32;
WORD dwFlags;
DWORD dwCallback;
DWORD dwClientInstance;
DWORD_PTR dwCallback;
DWORD_PTR dwClientInstance;
} WINE_MLD, *LPWINE_MLD;
typedef struct {
@ -122,24 +96,6 @@ typedef struct {
WINE_MLD mld;
} WINE_MIXER, *LPWINE_MIXER;
#define WINE_MMTHREAD_CREATED 0x4153494C /* "BSIL" */
#define WINE_MMTHREAD_DELETED 0xDEADDEAD
typedef struct {
DWORD dwSignature; /* 00 "BSIL" when ok, 0xDEADDEAD when being deleted */
DWORD dwCounter; /* 04 > 1 when in mmThread functions */
HANDLE hThread; /* 08 hThread */
DWORD dwThreadID; /* 0C */
DWORD fpThread; /* 10 address of thread proc (segptr or lin depending on dwFlags) */
DWORD dwThreadPmt; /* 14 parameter to be passed upon thread creation to fpThread */
DWORD dwSignalCount; /* 18 counter used for signaling */
HANDLE hEvent; /* 1C event */
HANDLE hVxD; /* 20 return from OpenVxDHandle */
DWORD dwStatus; /* 24 0x00, 0x10, 0x20, 0x30 */
DWORD dwFlags; /* 28 dwFlags upon creation */
UINT16 hTask; /* 2C handle to created task */
} WINE_MMTHREAD;
typedef struct tagWINE_MCIDRIVER {
UINT wDeviceID;
UINT wType;
@ -147,37 +103,21 @@ typedef struct tagWINE_MCIDRIVER {
LPWSTR lpstrDeviceType;
LPWSTR lpstrAlias;
HDRVR hDriver;
DWORD dwPrivate;
DWORD_PTR dwPrivate;
YIELDPROC lpfnYieldProc;
DWORD dwYieldData;
BOOL bIs32;
DWORD CreatorThread;
UINT uTypeCmdTable;
UINT uSpecificCmdTable;
struct tagWINE_MCIDRIVER*lpNext;
} WINE_MCIDRIVER, *LPWINE_MCIDRIVER;
#define WINE_TIMER_IS32 0x80
typedef struct tagWINE_TIMERENTRY {
UINT wDelay;
UINT wResol;
LPTIMECALLBACK lpFunc; /* can be lots of things */
DWORD dwUser;
UINT16 wFlags;
UINT16 wTimerID;
DWORD dwTriggerTime;
struct tagWINE_TIMERENTRY* lpNext;
} WINE_TIMERENTRY, *LPWINE_TIMERENTRY;
enum mmioProcType {MMIO_PROC_16,MMIO_PROC_32A,MMIO_PROC_32W};
struct IOProcList
{
struct IOProcList*pNext; /* Next item in linked list */
FOURCC fourCC; /* four-character code identifying IOProc */
LPMMIOPROC pIOProc; /* pointer to IProc */
enum mmioProcType type; /* 16, 32A or 32W */
BOOL is_unicode; /* 32A or 32W */
int count; /* number of objects linked to it */
};
@ -187,134 +127,53 @@ typedef struct tagWINE_MMIO {
struct IOProcList* ioProc;
unsigned bTmpIOProc : 1,
bBufferLoaded : 1;
DWORD segBuffer16;
DWORD dwFileSize;
} WINE_MMIO, *LPWINE_MMIO;
typedef struct tagWINE_PLAYSOUND {
unsigned bLoop : 1,
bAlloc : 1;
LPCWSTR pszSound;
HMODULE hMod;
DWORD fdwSound;
HANDLE hThread;
struct tagWINE_PLAYSOUND* lpNext;
} WINE_PLAYSOUND, *LPWINE_PLAYSOUND;
typedef struct tagWINE_MM_IDATA {
/* winmm part */
HANDLE hWinMM32Instance;
HANDLE hWinMM16Instance;
CRITICAL_SECTION cs;
/* mci part */
LPWINE_MCIDRIVER lpMciDrvs;
/* low level drivers (unused yet) */
/* LPWINE_WAVE lpWave; */
/* LPWINE_MIDI lpMidi; */
/* LPWINE_MIXER lpMixer; */
/* mmio part */
LPWINE_MMIO lpMMIO;
/* playsound and sndPlaySound */
WINE_PLAYSOUND* lpPlaySound;
HANDLE psLastEvent;
HANDLE psStopEvent;
} WINE_MM_IDATA, *LPWINE_MM_IDATA;
/* function prototypes */
typedef LONG (*MCIPROC)(DWORD, HDRVR, DWORD, DWORD, DWORD);
typedef WINMM_MapType (*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
typedef WINMM_MapType (*MMDRV_UNMAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT ret);
HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2);
BOOL WINMM_CheckForMMSystem(void);
LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr);
BOOL DRIVER_GetLibName(LPCWSTR keyName, LPCWSTR sectName, LPWSTR buf, int sz);
LPWINE_DRIVER DRIVER_TryOpenDriver32(LPCWSTR fn, LPARAM lParam2);
void DRIVER_UnloadAll(void);
HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam);
BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper);
BOOL LoadRegistryMMEDrivers(char* key);
BOOL MMDRV_Init(void);
void MMDRV_Exit(void);
UINT MMDRV_GetNum(UINT);
LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32);
DWORD_PTR* dwCallback, DWORD_PTR* dwInstance);
void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld);
DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwParam2);
DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD dwParam2);
DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg);
LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID);
LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType, BOOL bSrcCanBeID, UINT dstTyped);
DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2, BOOL bFrom32);
UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1, DWORD dwParam2);
BOOL MMDRV_Is32(unsigned int);
void MMDRV_InstallMap(unsigned int, MMDRV_MAPFUNC, MMDRV_UNMAPFUNC,
MMDRV_MAPFUNC, MMDRV_UNMAPFUNC, LPDRVCALLBACK);
DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
WINE_MCIDRIVER* MCI_GetDriver(UINT16 uDevID);
UINT MCI_GetDriverFromString(LPCWSTR str);
DWORD MCI_WriteString(LPWSTR lpDstStr, DWORD dstSize, LPCWSTR lpSrcStr);
const char* MCI_MessageToString(UINT wMsg);
UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data);
LRESULT MCI_CleanUp(LRESULT dwRet, UINT wMsg, DWORD dwParam2);
DWORD MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2, BOOL bFrom32);
DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
DWORD MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
UINT MCI_SetCommandTable(void *table, UINT uDevType);
BOOL MCI_DeleteCommandTable(UINT uTbl, BOOL delete);
DWORD MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
LPWSTR MCI_strdupAtoW(LPCSTR str);
LPSTR MCI_strdupWtoA(LPCWSTR str);
BOOL WINMM_CheckForMMSystem(void);
const char* WINMM_ErrorToString(MMRESULT error);
UINT MIXER_Open(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback,
DWORD_PTR dwInstance, DWORD fdwOpen, BOOL bFrom32);
UINT MIDI_OutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID, DWORD_PTR dwCallback,
DWORD_PTR dwInstance, DWORD dwFlags, BOOL bFrom32);
UINT MIDI_InOpen(HMIDIIN* lphMidiIn, UINT uDeviceID, DWORD_PTR dwCallback,
DWORD_PTR dwInstance, DWORD dwFlags, BOOL bFrom32);
MMRESULT MIDI_StreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
DWORD cMidi, DWORD_PTR dwCallback,
DWORD_PTR dwInstance, DWORD fdwOpen, BOOL bFrom32);
UINT WAVE_Open(HANDLE* lphndl, UINT uDeviceID, UINT uType,
LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback,
DWORD_PTR dwInstance, DWORD dwFlags, BOOL bFrom32);
HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo,
DWORD dwOpenFlags, enum mmioProcType type);
LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
DWORD dwFlags, enum mmioProcType type);
LRESULT MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
LPARAM lParam2, enum mmioProcType type);
LPWINE_MMIO MMIO_Get(HMMIO h);
WORD TIME_SetEventInternal(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc,
DWORD dwUser, UINT wFlags);
void TIME_MMTimeStart(void);
void TIME_MMTimeStop(void);
/* Global variables */
extern WINE_MM_IDATA WINMM_IData;
extern CRITICAL_SECTION WINMM_cs;
extern HINSTANCE hWinMM32Instance;
extern HANDLE psLastEvent;
extern HANDLE psStopEvent;
/* pointers to 16 bit functions (if sibling MMSYSTEM.DLL is loaded
* NULL otherwise
*/
extern WINE_MMTHREAD* (*pFnGetMMThread16)(UINT16);
extern LPWINE_DRIVER (*pFnOpenDriver16)(LPCWSTR,LPCWSTR,LPARAM);
extern LRESULT (*pFnCloseDriver16)(UINT16,LPARAM,LPARAM);
extern LRESULT (*pFnSendMessage16)(UINT16,UINT,LPARAM,LPARAM);
extern WINMM_MapType (*pFnMciMapMsg16To32W)(WORD,WORD,DWORD,DWORD*);
extern WINMM_MapType (*pFnMciUnMapMsg16To32W)(WORD,WORD,DWORD,DWORD);
extern WINMM_MapType (*pFnMciMapMsg32WTo16)(WORD,WORD,DWORD,DWORD*);
extern WINMM_MapType (*pFnMciUnMapMsg32WTo16)(WORD,WORD,DWORD,DWORD);
extern LRESULT (*pFnCallMMDrvFunc16)(DWORD /* in fact FARPROC16 */,WORD,WORD,LONG,LONG,LONG);
extern unsigned (*pFnLoadMMDrvFunc16)(LPCSTR,LPWINE_DRIVER, LPWINE_MM_DRIVER);
extern LRESULT (*pFnMmioCallback16)(DWORD,LPMMIOINFO,UINT,LPARAM,LPARAM);
extern void (WINAPI *pFnReleaseThunkLock)(DWORD*);
extern void (WINAPI *pFnRestoreThunkLock)(DWORD);
/* GetDriverFlags() returned bits is not documented (nor the call itself)
* Here are Wine only definitions of the bits
*/
#define WINE_GDF_EXIST 0x80000000
#define WINE_GDF_16BIT 0x10000000
#define WINE_GDF_EXIST 0x80000000
#define WINE_GDF_EXTERNAL_MASK 0xF0000000
#define WINE_GDF_SESSION 0x00000001
/* Modification to take into account Windows NT's registry format */
@ -325,4 +184,3 @@ extern void (WINAPI *pFnRestoreThunkLock)(DWORD);
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers"
INT LoadRegistryMMEDrivers(char* key);
BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper);

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@
<library>kernel32</library>
<library>advapi32</library>
<library>user32</library>
<library>pseh</library>
<file>driver.c</file>
<file>joystick.c</file>
<file>lolvldrv.c</file>

View file

@ -26,7 +26,7 @@
@ stdcall auxGetVolume(long ptr)
@ stdcall auxOutMessage(long long long long)
@ stdcall auxSetVolume(long long)
@ stub joyConfigChanged
@ stdcall joyConfigChanged(long)
@ stdcall joyGetDevCapsA(long ptr long)
@ stdcall joyGetDevCapsW(long ptr long)
@ stdcall joyGetNumDevs()
@ -56,8 +56,8 @@
@ stdcall mciSendStringW(wstr ptr long long)
@ stdcall mciSetDriverData(long long)
@ stdcall mciSetYieldProc(long ptr long)
@ stub midiConnect
@ stub midiDisconnect
@ stdcall midiConnect(long long ptr)
@ stdcall midiDisconnect(long long ptr)
@ stdcall midiInAddBuffer(long ptr long)
@ stdcall midiInClose(long)
@ stdcall midiInGetDevCapsA(long ptr long)

View file

@ -452,18 +452,18 @@ BOOL WINAPI mciFreeCommandResource(UINT uTable);
#define DCB_TYPEMASK 0x0007
#define DCB_NOSWITCH 0x0008 /* don't switch stacks for callback */
BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
BOOL APIENTRY DriverCallback(DWORD_PTR dwCallBack, DWORD uFlags, HDRVR hDev,
DWORD wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
typedef void (*LPTASKCALLBACK)(DWORD dwInst);
#define TASKERR_NOTASKSUPPORT 1
#define TASKERR_OUTOFMEMORY 2
MMRESULT WINAPI mmTaskCreate(LPTASKCALLBACK, HANDLE*, DWORD);
void WINAPI mmTaskBlock(HANDLE);
BOOL WINAPI mmTaskSignal(HANDLE);
void WINAPI mmTaskBlock(DWORD);
BOOL WINAPI mmTaskSignal(DWORD);
void WINAPI mmTaskYield(void);
HANDLE WINAPI mmGetCurrentTask(void);
DWORD WINAPI mmGetCurrentTask(void);
#define WAVE_DIRECTSOUND 0x0080

View file

@ -159,7 +159,7 @@ extern "C" {
#define SND_PURGE 0x40
#define SND_APPLICATION 0x80
#define SND_ALIAS_START 0
#define sndAlias(c0,c1) (SND_ALIAS_START+(DWORD)(BYTE)(c0)|((DWORD)(BYTE)(c1)<<8))
#define sndAlias(c0,c1) (SND_ALIAS_START+((DWORD)(BYTE)(c0)|((DWORD)(BYTE)(c1)<<8)))
#define SND_ALIAS_SYSTEMASTERISK sndAlias('S','*')
#define SND_ALIAS_SYSTEMQUESTION sndAlias('S','?')
#define SND_ALIAS_SYSTEMHAND sndAlias('S','H')