mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 00:03:22 +00:00
- Partially sync winmm
- Remove unused code - Fix function headers svn path=/trunk/; revision=43747
This commit is contained in:
parent
8fd3137277
commit
acd8b06824
18 changed files with 1249 additions and 8738 deletions
|
@ -5,8 +5,6 @@
|
||||||
* Copyright 1998 Marcus Meissner
|
* Copyright 1998 Marcus Meissner
|
||||||
* Copyright 1999 Eric Pouech
|
* Copyright 1999 Eric Pouech
|
||||||
*
|
*
|
||||||
* Reformatting and additional comments added by Andrew Greenwood.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* License as published by the Free Software Foundation; either
|
* 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
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* 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 <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
@ -34,17 +35,41 @@
|
||||||
#include "winemm.h"
|
#include "winemm.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
|
#include "excpt.h"
|
||||||
|
#include "wine/exception.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(driver);
|
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 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','\\',
|
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};
|
'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 */;
|
static void DRIVER_Dump(const char *comment)
|
||||||
LPWINE_DRIVER (*pFnOpenDriver16)(LPCWSTR,LPCWSTR,LPARAM) /* = NULL */;
|
{
|
||||||
LRESULT (*pFnCloseDriver16)(UINT16,LPARAM,LPARAM) /* = NULL */;
|
#if 0
|
||||||
LRESULT (*pFnSendMessage16)(UINT16,UINT,LPARAM,LPARAM) /* = NULL */;
|
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]
|
* DRIVER_GetNumberOfModuleRefs [internal]
|
||||||
|
@ -56,15 +81,19 @@ static unsigned DRIVER_GetNumberOfModuleRefs(HMODULE hModule, WINE_DRIVER** foun
|
||||||
LPWINE_DRIVER lpDrv;
|
LPWINE_DRIVER lpDrv;
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
|
|
||||||
|
EnterCriticalSection( &mmdriver_lock );
|
||||||
|
|
||||||
if (found) *found = NULL;
|
if (found) *found = NULL;
|
||||||
for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem)
|
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;
|
if (found && !*found) *found = lpDrv;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &mmdriver_lock );
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,34 +104,39 @@ static unsigned DRIVER_GetNumberOfModuleRefs(HMODULE hModule, WINE_DRIVER** foun
|
||||||
*/
|
*/
|
||||||
LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr)
|
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) {
|
__TRY
|
||||||
return d;
|
{
|
||||||
|
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]
|
* 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)
|
LPARAM lParam1, LPARAM lParam2)
|
||||||
{
|
{
|
||||||
LRESULT ret = 0;
|
LRESULT ret = 0;
|
||||||
|
|
||||||
if (lpDrv->dwFlags & WINE_GDF_16BIT) {
|
TRACE("Before call32 proc=%p drvrID=%08lx hDrv=%p wMsg=%04x p1=%08lx p2=%08lx\n",
|
||||||
/* no need to check mmsystem presence: the driver must have been opened as a 16 bit one,
|
lpDrv->lpDrvProc, lpDrv->dwDriverID, lpDrv, msg, lParam1, lParam2);
|
||||||
*/
|
ret = lpDrv->lpDrvProc(lpDrv->dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
|
||||||
if (pFnSendMessage16)
|
TRACE("After call32 proc=%p drvrID=%08lx hDrv=%p wMsg=%04x p1=%08lx p2=%08lx => %08lx\n",
|
||||||
ret = pFnSendMessage16(lpDrv->d.d16.hDriver16, msg, lParam1, lParam2);
|
lpDrv->lpDrvProc, lpDrv->dwDriverID, lpDrv, msg, lParam1, lParam2, ret);
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,14 +170,14 @@ LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT msg, LPARAM lParam1,
|
||||||
*/
|
*/
|
||||||
static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
|
static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
|
||||||
{
|
{
|
||||||
if (!(lpDrv->dwFlags & WINE_GDF_16BIT)) {
|
/* last of this driver in list ? */
|
||||||
/* last of this driver in list ? */
|
if (DRIVER_GetNumberOfModuleRefs(lpDrv->hModule, NULL) == 1) {
|
||||||
if (DRIVER_GetNumberOfModuleRefs(lpDrv->d.d32.hModule, NULL) == 1) {
|
DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L);
|
||||||
DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L);
|
DRIVER_SendMessage(lpDrv, DRV_FREE, 0L, 0L);
|
||||||
DRIVER_SendMessage(lpDrv, DRV_FREE, 0L, 0L);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection( &mmdriver_lock );
|
||||||
|
|
||||||
if (lpDrv->lpPrevItem)
|
if (lpDrv->lpPrevItem)
|
||||||
lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem;
|
lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem;
|
||||||
else
|
else
|
||||||
|
@ -152,6 +186,10 @@ static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
|
||||||
lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem;
|
lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem;
|
||||||
/* trash magic number */
|
/* trash magic number */
|
||||||
lpDrv->dwMagic ^= 0xa5a5a5a5;
|
lpDrv->dwMagic ^= 0xa5a5a5a5;
|
||||||
|
lpDrv->lpDrvProc = NULL;
|
||||||
|
lpDrv->dwDriverID = 0;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &mmdriver_lock );
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -166,18 +204,27 @@ static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam1, LPARAM lPar
|
||||||
{
|
{
|
||||||
lpNewDrv->dwMagic = WINE_DI_MAGIC;
|
lpNewDrv->dwMagic = WINE_DI_MAGIC;
|
||||||
/* First driver to be loaded for this module, need to load correctly the module */
|
/* 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 ? */
|
||||||
/* first of this driver in list ? */
|
if (DRIVER_GetNumberOfModuleRefs(lpNewDrv->hModule, NULL) == 0) {
|
||||||
if (DRIVER_GetNumberOfModuleRefs(lpNewDrv->d.d32.hModule, NULL) == 0) {
|
if (DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
|
||||||
if (DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
|
TRACE("DRV_LOAD failed on driver %p\n", lpNewDrv);
|
||||||
TRACE("DRV_LOAD failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
/* returned value is not checked */
|
||||||
/* returned value is not checked */
|
DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L);
|
||||||
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;
|
lpNewDrv->lpNextItem = NULL;
|
||||||
if (lpDrvItemList == NULL) {
|
if (lpDrvItemList == NULL) {
|
||||||
lpDrvItemList = lpNewDrv;
|
lpDrvItemList = lpNewDrv;
|
||||||
|
@ -191,16 +238,7 @@ static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam1, LPARAM lPar
|
||||||
lpNewDrv->lpPrevItem = lpDrv;
|
lpNewDrv->lpPrevItem = lpDrv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(lpNewDrv->dwFlags & WINE_GDF_16BIT)) {
|
LeaveCriticalSection( &mmdriver_lock );
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,23 +320,23 @@ LPWINE_DRIVER DRIVER_TryOpenDriver32(LPCWSTR fn, LPARAM lParam2)
|
||||||
goto exit;
|
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";
|
cause = "no DriverProc";
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpDrv->dwFlags = 0;
|
lpDrv->dwFlags = 0;
|
||||||
lpDrv->d.d32.hModule = hModule;
|
lpDrv->hModule = hModule;
|
||||||
lpDrv->d.d32.dwDriverID = 0;
|
lpDrv->dwDriverID = 0;
|
||||||
|
|
||||||
/* Win32 installable drivers must support a two phase opening scheme:
|
/* Win32 installable drivers must support a two phase opening scheme:
|
||||||
* + first open with NULL as lParam2 (session instance),
|
* + first open with NULL as lParam2 (session instance),
|
||||||
* + then do a second open with the real non null lParam2)
|
* + 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;
|
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
|
* so ensure, we can load our mmsystem, otherwise just fail
|
||||||
*/
|
*/
|
||||||
WINMM_CheckForMMSystem();
|
WINMM_CheckForMMSystem();
|
||||||
|
#if 0
|
||||||
if (pFnOpenDriver16 &&
|
if (pFnOpenDriver16 &&
|
||||||
(lpDrv = pFnOpenDriver16(lpDriverName, lpSectionName, lParam)))
|
(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",
|
TRACE("Failed to open driver %s from system.ini file, section %s\n",
|
||||||
debugstr_w(lpDriverName), debugstr_w(lpSectionName));
|
debugstr_w(lpDriverName), debugstr_w(lpSectionName));
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
the_end:
|
the_end:
|
||||||
|
@ -437,44 +477,46 @@ HDRVR WINAPI OpenDriver(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lPar
|
||||||
*/
|
*/
|
||||||
LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
|
LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
|
||||||
{
|
{
|
||||||
|
BOOL ret;
|
||||||
LPWINE_DRIVER lpDrv;
|
LPWINE_DRIVER lpDrv;
|
||||||
|
|
||||||
TRACE("(%p, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
|
TRACE("(%p, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
|
||||||
|
|
||||||
|
DRIVER_Dump("BEFORE:");
|
||||||
|
|
||||||
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL)
|
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL)
|
||||||
{
|
{
|
||||||
if (lpDrv->dwFlags & WINE_GDF_16BIT)
|
LPWINE_DRIVER lpDrv0;
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* if driver has an opened session instance, we have to close it too */
|
DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2);
|
||||||
if (DRIVER_GetNumberOfModuleRefs(lpDrv->d.d32.hModule, &lpDrv0) == 1)
|
|
||||||
{
|
DRIVER_RemoveFromList(lpDrv);
|
||||||
DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0L, 0L);
|
|
||||||
lpDrv0->d.d32.dwDriverID = 0;
|
if (lpDrv->dwFlags & WINE_GDF_SESSION)
|
||||||
DRIVER_RemoveFromList(lpDrv0);
|
FIXME("WINE_GDF_SESSION: Shouldn't happen (%p)\n", lpDrv);
|
||||||
FreeLibrary(lpDrv0->d.d32.hModule);
|
/* if driver has an opened session instance, we have to close it too */
|
||||||
HeapFree(GetProcessHeap(), 0, lpDrv0);
|
if (DRIVER_GetNumberOfModuleRefs(lpDrv->hModule, &lpDrv0) == 1 &&
|
||||||
}
|
(lpDrv0->dwFlags & WINE_GDF_SESSION))
|
||||||
FreeLibrary(lpDrv->d.d32.hModule);
|
{
|
||||||
}
|
DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0, 0);
|
||||||
HeapFree(GetProcessHeap(), 0, lpDrv);
|
DRIVER_RemoveFromList(lpDrv0);
|
||||||
return TRUE;
|
FreeLibrary(lpDrv0->hModule);
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpDrv0);
|
||||||
}
|
}
|
||||||
|
FreeLibrary(lpDrv->hModule);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpDrv);
|
||||||
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
WARN("Failed to close driver\n");
|
else
|
||||||
return FALSE;
|
{
|
||||||
|
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);
|
TRACE("(%p)\n", hDrvr);
|
||||||
|
|
||||||
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
|
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
|
||||||
ret = WINE_GDF_EXIST | lpDrv->dwFlags;
|
ret = WINE_GDF_EXIST | (lpDrv->dwFlags & WINE_GDF_EXTERNAL_MASK);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -515,8 +557,7 @@ HMODULE WINAPI GetDriverModuleHandle(HDRVR hDrvr)
|
||||||
TRACE("(%p);\n", hDrvr);
|
TRACE("(%p);\n", hDrvr);
|
||||||
|
|
||||||
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
|
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
|
||||||
if (!(lpDrv->dwFlags & WINE_GDF_16BIT))
|
hModule = lpDrv->hModule;
|
||||||
hModule = lpDrv->d.d32.hModule;
|
|
||||||
}
|
}
|
||||||
TRACE("=> %p\n", hModule);
|
TRACE("=> %p\n", hModule);
|
||||||
return hModule;
|
return hModule;
|
||||||
|
@ -546,11 +587,11 @@ LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv,
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* DriverCallback [WINMM.@]
|
* DriverCallback [WINMM.@]
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
|
BOOL WINAPI DriverCallback(DWORD_PTR dwCallBack, DWORD uFlags, HDRVR hDev,
|
||||||
UINT wMsg, DWORD dwUser, DWORD dwParam1,
|
DWORD wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1,
|
||||||
DWORD dwParam2)
|
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);
|
dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
|
||||||
|
|
||||||
switch (uFlags & DCB_TYPEMASK) {
|
switch (uFlags & DCB_TYPEMASK) {
|
||||||
|
@ -575,6 +616,10 @@ BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
|
||||||
TRACE("Event(%08lx) !\n", dwCallBack);
|
TRACE("Event(%08lx) !\n", dwCallBack);
|
||||||
SetEvent((HANDLE)dwCallBack);
|
SetEvent((HANDLE)dwCallBack);
|
||||||
break;
|
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 */
|
case 6: /* I would dub it DCB_MMTHREADSIGNAL */
|
||||||
/* this is an undocumented DCB_ value used for mmThreads
|
/* this is an undocumented DCB_ value used for mmThreads
|
||||||
* loword of dwCallBack contains the handle of the lpMMThd block
|
* 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);
|
TRACE("mmThread (%04x, %p) !\n", LOWORD(dwCallBack), lpMMThd);
|
||||||
/* same as mmThreadSignal16 */
|
/* same as mmThreadSignal16 */
|
||||||
InterlockedIncrement((PLONG)&lpMMThd->dwSignalCount);
|
InterlockedIncrement(&lpMMThd->dwSignalCount);
|
||||||
SetEvent(lpMMThd->hEvent);
|
SetEvent(lpMMThd->hEvent);
|
||||||
/* some other stuff on lpMMThd->hVxD */
|
/* some other stuff on lpMMThd->hVxD */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
case 4:
|
case 4:
|
||||||
/* this is an undocumented DCB_ value for... I don't know */
|
/* this is an undocumented DCB_ value for... I don't know */
|
||||||
|
@ -615,11 +661,25 @@ void DRIVER_UnloadAll(void)
|
||||||
LPWINE_DRIVER lpNextDrv = NULL;
|
LPWINE_DRIVER lpNextDrv = NULL;
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
|
|
||||||
|
restart:
|
||||||
|
EnterCriticalSection( &mmdriver_lock );
|
||||||
|
|
||||||
for (lpDrv = lpDrvItemList; lpDrv != NULL; lpDrv = lpNextDrv)
|
for (lpDrv = lpDrvItemList; lpDrv != NULL; lpDrv = lpNextDrv)
|
||||||
{
|
{
|
||||||
lpNextDrv = lpDrv->lpNextItem;
|
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);
|
TRACE("Unloaded %u drivers\n", count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* 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 "config.h"
|
||||||
|
@ -35,13 +35,13 @@
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "winemm.h"
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "mmsystem.h"
|
#include "mmsystem.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
#include "winemm.h"
|
|
||||||
|
|
||||||
#include "mmddk.h"
|
#include "mmddk.h"
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
|
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_MIN (10) /* min Capture time period */
|
||||||
#define JOY_PERIOD_MAX (1000) /* max 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)
|
if (JOY_Sticks[dwJoyID].hDriver)
|
||||||
return TRUE;
|
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);
|
return (JOY_Sticks[dwJoyID].hDriver != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* JOY_Timer [internal]
|
* 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;
|
int i;
|
||||||
WINE_JOYSTICK* joy;
|
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.@]
|
* joyGetNumDevs [WINMM.@]
|
||||||
*/
|
*/
|
||||||
|
@ -131,7 +144,7 @@ UINT WINAPI joyGetNumDevs(void)
|
||||||
|
|
||||||
for (i = 0; i < MAXJOYSTICK; i++) {
|
for (i = 0; i < MAXJOYSTICK; i++) {
|
||||||
if (JOY_LoadDriver(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;
|
return ret;
|
||||||
|
@ -148,7 +161,7 @@ MMRESULT WINAPI joyGetDevCapsW(UINT_PTR wID, LPJOYCAPSW lpCaps, UINT wSize)
|
||||||
lpCaps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */
|
lpCaps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */
|
||||||
lpCaps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
|
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->dwReserved1 = 0;
|
||||||
lpInfo->dwReserved2 = 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->wZpos = 0;
|
||||||
lpInfo->wButtons = 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMSYTEM low level drivers handling functions
|
* MMSYSTEM low level drivers handling functions
|
||||||
*
|
*
|
||||||
* Copyright 1999 Eric Pouech
|
* Copyright 1999 Eric Pouech
|
||||||
* Modified for use with ReactOS by Andrew Greenwood, 2007
|
* 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
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* 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 <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -28,27 +31,19 @@
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "winver.h"
|
|
||||||
#include "winemm.h"
|
#include "winemm.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "wine/exception.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
|
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 */
|
/* each known type of driver has an instance of this structure */
|
||||||
typedef struct tagWINE_LLTYPE {
|
typedef struct tagWINE_LLTYPE {
|
||||||
/* those attributes depend on the specification of the type */
|
/* those attributes depend on the specification of the type */
|
||||||
LPCSTR typestr; /* name (for debugging) */
|
LPCSTR typestr; /* name (for debugging) */
|
||||||
BOOL bSupportMapper; /* if type is allowed to support mapper */
|
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 */
|
/* 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 */
|
LPWINE_MLD lpMlds; /* "static" mlds to access the part though device IDs */
|
||||||
int nMapper; /* index to mapper */
|
int nMapper; /* index to mapper */
|
||||||
} WINE_LLTYPE;
|
} WINE_LLTYPE;
|
||||||
|
@ -58,7 +53,7 @@ static WINE_MM_DRIVER MMDrvs[8];
|
||||||
static LPWINE_MLD MM_MLDrvs[40];
|
static LPWINE_MLD MM_MLDrvs[40];
|
||||||
#define MAX_MM_MLDRVS (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
|
#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
|
/* Note: the indices of this array must match the definitions
|
||||||
* of the MMDRV_???? manifest constants
|
* of the MMDRV_???? manifest constants
|
||||||
*/
|
*/
|
||||||
|
@ -72,96 +67,6 @@ static WINE_LLTYPE llTypes[MMDRV_MAX] = {
|
||||||
};
|
};
|
||||||
#undef A
|
#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]
|
* MMDRV_GetNum [internal]
|
||||||
*/
|
*/
|
||||||
|
@ -176,18 +81,17 @@ UINT MMDRV_GetNum(UINT type)
|
||||||
* MMDRV_Message [internal]
|
* MMDRV_Message [internal]
|
||||||
*/
|
*/
|
||||||
DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1,
|
DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1,
|
||||||
DWORD_PTR dwParam2, BOOL bFrom32)
|
DWORD_PTR dwParam2)
|
||||||
{
|
{
|
||||||
LPWINE_MM_DRIVER lpDrv;
|
LPWINE_MM_DRIVER lpDrv;
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
WINE_MM_DRIVER_PART* part;
|
WINE_MM_DRIVER_PART* part;
|
||||||
WINE_LLTYPE* llType = &llTypes[mld->type];
|
WINE_LLTYPE* llType = &llTypes[mld->type];
|
||||||
WINMM_MapType map;
|
|
||||||
int devID;
|
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,
|
llTypes[mld->type].typestr, mld->uDeviceID, wMsg,
|
||||||
mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
|
mld->dwDriverInstance, dwParam1, dwParam2);
|
||||||
|
|
||||||
if (mld->uDeviceID == (UINT16)-1) {
|
if (mld->uDeviceID == (UINT16)-1) {
|
||||||
if (!llType->bSupportMapper) {
|
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);
|
ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (lpDrv->bIs32) {
|
assert(part->fnMessage32);
|
||||||
assert(part->u.fnMessage32);
|
|
||||||
|
|
||||||
if (bFrom32) {
|
TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx)\n",
|
||||||
TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx)\n",
|
mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
|
||||||
mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
|
ret = part->fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
|
||||||
ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
|
TRACE("=> %s\n", WINMM_ErrorToString(ret));
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,12 +133,12 @@ DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1,
|
||||||
* MMDRV_Alloc [internal]
|
* MMDRV_Alloc [internal]
|
||||||
*/
|
*/
|
||||||
LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
|
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;
|
LPWINE_MLD mld;
|
||||||
UINT i;
|
UINT_PTR i;
|
||||||
TRACE("(%d, %04x, %p, %p, %p, %p, %c)\n",
|
TRACE("(%d, %04x, %p, %p, %p, %p)\n",
|
||||||
size, type, hndl, dwFlags, dwCallback, dwInstance, bFrom32?'Y':'N');
|
size, type, hndl, dwFlags, dwCallback, dwInstance);
|
||||||
|
|
||||||
mld = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
|
mld = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
|
||||||
if (!mld) return NULL;
|
if (!mld) return NULL;
|
||||||
|
@ -317,7 +156,7 @@ LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
|
||||||
*hndl = (HANDLE)(i | 0x8000);
|
*hndl = (HANDLE)(i | 0x8000);
|
||||||
|
|
||||||
mld->type = type;
|
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:
|
/* FIXME: those conditions must be fulfilled so that:
|
||||||
* - we can distinguish between device IDs and handles
|
* - we can distinguish between device IDs and handles
|
||||||
* - we can use handles as 16 or 32 bit entities
|
* - 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");
|
ERR("Shouldn't happen. Bad allocation scheme\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
mld->bFrom32 = bFrom32;
|
|
||||||
mld->dwFlags = HIWORD(*dwFlags);
|
mld->dwFlags = HIWORD(*dwFlags);
|
||||||
mld->dwCallback = *dwCallback;
|
mld->dwCallback = *dwCallback;
|
||||||
mld->dwClientInstance = *dwInstance;
|
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;
|
return mld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,8 +178,8 @@ void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
|
||||||
{
|
{
|
||||||
TRACE("(%p, %p)\n", hndl, mld);
|
TRACE("(%p, %p)\n", hndl, mld);
|
||||||
|
|
||||||
if ((UINT)hndl & 0x8000) {
|
if ((UINT_PTR)hndl & 0x8000) {
|
||||||
unsigned idx = (UINT)hndl & ~0x8000;
|
UINT_PTR idx = (UINT_PTR)hndl & ~0x8000;
|
||||||
if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
|
if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
|
||||||
MM_MLDrvs[idx] = NULL;
|
MM_MLDrvs[idx] = NULL;
|
||||||
HeapFree(GetProcessHeap(), 0, mld);
|
HeapFree(GetProcessHeap(), 0, mld);
|
||||||
|
@ -361,14 +192,14 @@ void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* MMDRV_Open [internal]
|
* 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 dwRet = MMSYSERR_BADDEVICEID;
|
||||||
DWORD dwInstance;
|
DWORD_PTR dwInstance;
|
||||||
WINE_LLTYPE* llType = &llTypes[mld->type];
|
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) {
|
if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) {
|
||||||
TRACE("MAPPER mode requested !\n");
|
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->uDeviceID = (UINT16)-1;
|
||||||
mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
|
mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
|
||||||
TRACE("Setting mmdIndex to %u\n", mld->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 {
|
} else {
|
||||||
if (mld->uDeviceID < llType->wMaxId) {
|
if (mld->uDeviceID < llType->wMaxId) {
|
||||||
mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
|
mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
|
||||||
TRACE("Setting mmdIndex to %u\n", mld->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)
|
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)
|
DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
|
||||||
{
|
{
|
||||||
TRACE("(%p, %04x)\n", mld, 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 MMDRV_Get(HANDLE _hndl, UINT type, BOOL bCanBeID)
|
||||||
{
|
{
|
||||||
LPWINE_MLD mld = NULL;
|
LPWINE_MLD mld = NULL;
|
||||||
UINT hndl = (UINT)_hndl;
|
UINT_PTR hndl = (UINT_PTR)_hndl;
|
||||||
TRACE("(%p, %04x, %c)\n", _hndl, type, bCanBeID ? 'Y' : 'N');
|
TRACE("(%p, %04x, %c)\n", _hndl, type, bCanBeID ? 'Y' : 'N');
|
||||||
|
|
||||||
assert(type < MMDRV_MAX);
|
assert(type < MMDRV_MAX);
|
||||||
|
@ -439,13 +270,19 @@ LPWINE_MLD MMDRV_Get(HANDLE _hndl, UINT type, BOOL bCanBeID)
|
||||||
if (hndl >= llTypes[type].wMaxId &&
|
if (hndl >= llTypes[type].wMaxId &&
|
||||||
hndl != (UINT16)-1 && hndl != (UINT)-1) {
|
hndl != (UINT16)-1 && hndl != (UINT)-1) {
|
||||||
if (hndl & 0x8000) {
|
if (hndl & 0x8000) {
|
||||||
hndl = hndl & ~0x8000;
|
UINT idx = hndl & ~0x8000;
|
||||||
if (hndl < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
|
if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
|
||||||
mld = MM_MLDrvs[hndl];
|
__TRY
|
||||||
if (!mld || !HeapValidate(GetProcessHeap(), 0, mld) || mld->type != type)
|
{
|
||||||
mld = NULL;
|
mld = MM_MLDrvs[idx];
|
||||||
|
if (mld && mld->type != type) mld = NULL;
|
||||||
|
}
|
||||||
|
__EXCEPT_PAGE_FAULT
|
||||||
|
{
|
||||||
|
mld = NULL;
|
||||||
|
}
|
||||||
|
__ENDTRY;
|
||||||
}
|
}
|
||||||
hndl = hndl | 0x8000;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mld == NULL && bCanBeID) {
|
if (mld == NULL && bCanBeID) {
|
||||||
|
@ -475,8 +312,8 @@ LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* MMDRV_PhysicalFeatures [internal]
|
* MMDRV_PhysicalFeatures [internal]
|
||||||
*/
|
*/
|
||||||
UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
|
UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg,
|
||||||
DWORD dwParam2)
|
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||||
{
|
{
|
||||||
WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
|
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_QUERYDEVICEINTERFACE:
|
||||||
case DRV_QUERYDEVICEINTERFACESIZE:
|
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_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
|
||||||
case DRV_QUERYDSOUNDDESC: /* Wine-specific: Retrieve DirectSound driver description*/
|
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:
|
default:
|
||||||
WARN("Unknown call %04x\n", uMsg);
|
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 */
|
/* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
|
||||||
/* the DRVM_ENABLE is only required when the PnP node is non zero */
|
/* the DRVM_ENABLE is only required when the PnP node is non zero */
|
||||||
|
if (part->fnMessage32) {
|
||||||
if (lpDrv->bIs32 && part->u.fnMessage32) {
|
ret = part->fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
|
||||||
ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
|
TRACE("DRVM_INIT => %s\n", WINMM_ErrorToString(ret));
|
||||||
TRACE("DRVM_INIT => %s\n", WINMM_ErrorToString(ret));
|
|
||||||
#if 0
|
#if 0
|
||||||
ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
|
ret = part->fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
|
||||||
TRACE("DRVM_ENABLE => %08lx\n", ret);
|
TRACE("DRVM_ENABLE => %08lx\n", ret);
|
||||||
#endif
|
#endif
|
||||||
count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
|
count = part->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;
|
|
||||||
}
|
}
|
||||||
|
else return FALSE;
|
||||||
|
|
||||||
TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->drvname, llTypes[type].typestr);
|
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]
|
* 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;
|
int i, count = 0;
|
||||||
LPWINE_MM_DRIVER lpDrv = &MMDrvs[MMDrvsHi];
|
LPWINE_MM_DRIVER lpDrv = &MMDrvs[MMDrvsHi];
|
||||||
LPWINE_DRIVER d;
|
LPWINE_DRIVER d;
|
||||||
|
WINEMM_msgFunc32 func;
|
||||||
|
|
||||||
TRACE("('%s', '%s', mapper=%c);\n", drvRegName, drvFileName, bIsMapper ? 'Y' : 'N');
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d = DRIVER_FindFromHDrvr(lpDrv->hDriver);
|
||||||
|
|
||||||
if (!(d = DRIVER_FindFromHDrvr(lpDrv->hDriver))) {
|
if (!(d = DRIVER_FindFromHDrvr(lpDrv->hDriver))) {
|
||||||
CloseDriver(lpDrv->hDriver, 0, 0);
|
CloseDriver(lpDrv->hDriver, 0, 0);
|
||||||
WARN("Couldn't get the WINE internal structure for driver '%s'\n", drvFileName);
|
WARN("Couldn't get the WINE internal structure for driver '%s'\n", drvFileName);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
lpDrv->bIs32 = (d->dwFlags & WINE_GDF_16BIT) ? FALSE : TRUE;
|
|
||||||
|
|
||||||
/* Then look for xxxMessage functions */
|
/* Then look for xxxMessage functions */
|
||||||
#define AA(_h,_w,_x,_y,_z) \
|
#define AA(_h,_w,_x,_y,_z) \
|
||||||
func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
|
func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
|
||||||
if (func != NULL) \
|
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); }
|
TRACE("Got %d bit func '%s'\n", _y, #_x); }
|
||||||
|
|
||||||
if (lpDrv->bIs32) {
|
if (d->hModule) {
|
||||||
WINEMM_msgFunc32 func;
|
#define A(_x,_y) AA(d->hModule,_x,_y,32,GetProcAddress)
|
||||||
char buffer[128];
|
|
||||||
|
|
||||||
if (d->d.d32.hModule) {
|
|
||||||
#define A(_x,_y) AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
|
|
||||||
A(MMDRV_AUX, auxMessage);
|
A(MMDRV_AUX, auxMessage);
|
||||||
A(MMDRV_MIXER, mxdMessage);
|
A(MMDRV_MIXER, mxdMessage);
|
||||||
A(MMDRV_MIDIIN, midMessage);
|
A(MMDRV_MIDIIN, midMessage);
|
||||||
|
@ -673,15 +495,6 @@ BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
|
||||||
A(MMDRV_WAVEIN, widMessage);
|
A(MMDRV_WAVEIN, widMessage);
|
||||||
A(MMDRV_WAVEOUT, wodMessage);
|
A(MMDRV_WAVEOUT, wodMessage);
|
||||||
#undef A
|
#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
|
#undef AA
|
||||||
|
|
||||||
|
@ -730,6 +543,7 @@ BOOL MMDRV_Init(void)
|
||||||
char driver_buffer[256];
|
char driver_buffer[256];
|
||||||
char mapper_buffer[256];
|
char mapper_buffer[256];
|
||||||
char midi_buffer[256];
|
char midi_buffer[256];
|
||||||
|
char* p;
|
||||||
DWORD type, size;
|
DWORD type, size;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
|
@ -746,6 +560,17 @@ BOOL MMDRV_Init(void)
|
||||||
strcpy(driver_buffer, WINE_DEFAULT_WINMM_DRIVER);
|
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("beepmidi.dll", "beepmidi.dll", FALSE);
|
||||||
|
|
||||||
ret |= MMDRV_Install("wavemapper", WINE_DEFAULT_WINMM_MAPPER, TRUE);
|
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;
|
DWORD ret;
|
||||||
TRACE("(%p, %04x)\n", lpDrv, type);
|
TRACE("(%p, %04x)\n", lpDrv, type);
|
||||||
|
|
||||||
if (lpDrv->bIs32 && part->u.fnMessage32) {
|
if (part->fnMessage32) {
|
||||||
#if 0
|
#if 0
|
||||||
ret = part->u.fnMessage32(0, DRVM_DISABLE, 0L, 0L, 0L);
|
ret = part->fnMessage32(0, DRVM_DISABLE, 0L, 0L, 0L);
|
||||||
TRACE("DRVM_DISABLE => %08lx\n", ret);
|
TRACE("DRVM_DISABLE => %08lx\n", ret);
|
||||||
#endif
|
#endif
|
||||||
ret = part->u.fnMessage32(0, DRVM_EXIT, 0L, 0L, 0L);
|
ret = part->fnMessage32(0, DRVM_EXIT, 0L, 0L, 0L);
|
||||||
TRACE("DRVM_EXIT => %s\n", WINMM_ErrorToString(ret));
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -804,7 +618,7 @@ static BOOL MMDRV_ExitPerType(LPWINE_MM_DRIVER lpDrv, UINT type)
|
||||||
*/
|
*/
|
||||||
void MMDRV_Exit(void)
|
void MMDRV_Exit(void)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
|
|
||||||
for (i = 0; i < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]); i++)
|
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 */
|
/* 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_AUX);
|
||||||
MMDRV_ExitPerType(&MMDrvs[i], MMDRV_MIXER);
|
MMDRV_ExitPerType(&MMDrvs[i], MMDRV_MIXER);
|
||||||
|
@ -830,4 +645,16 @@ void MMDRV_Exit(void)
|
||||||
MMDRV_ExitPerType(&MMDrvs[i], MMDRV_WAVEOUT);
|
MMDRV_ExitPerType(&MMDrvs[i], MMDRV_WAVEOUT);
|
||||||
CloseDriver(MMDrvs[i].hDriver, 0, 0);
|
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
|
@ -2,7 +2,7 @@
|
||||||
* MMIO functions
|
* MMIO functions
|
||||||
*
|
*
|
||||||
* Copyright 1998 Andrew Taylor
|
* Copyright 1998 Andrew Taylor
|
||||||
* Copyright 1998 Ove Kåven
|
* Copyright 1998 Ove Kåven
|
||||||
* Copyright 2000,2002 Eric Pouech
|
* Copyright 2000,2002 Eric Pouech
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* 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
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* 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:
|
/* Still to be done:
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(mmio);
|
WINE_DEFAULT_DEBUG_CHANNEL(mmio);
|
||||||
|
|
||||||
LRESULT (*pFnMmioCallback16)(DWORD,LPMMIOINFO,UINT,LPARAM,LPARAM) /* = NULL */;
|
static WINE_MMIO *MMIOList;
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* mmioDosIOProc [internal]
|
* mmioDosIOProc [internal]
|
||||||
|
@ -227,8 +227,8 @@ static LRESULT CALLBACK mmioMemIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct IOProcList defaultProcs[] = {
|
static struct IOProcList defaultProcs[] = {
|
||||||
{&defaultProcs[1], FOURCC_DOS, (LPMMIOPROC)mmioDosIOProc, MMIO_PROC_32A, 0},
|
{&defaultProcs[1], FOURCC_DOS, (LPMMIOPROC)mmioDosIOProc, FALSE, 0},
|
||||||
{NULL, FOURCC_MEM, (LPMMIOPROC)mmioMemIOProc, MMIO_PROC_32A, 0},
|
{NULL, FOURCC_MEM, (LPMMIOPROC)mmioMemIOProc, FALSE, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct IOProcList* pIOProcListAnchor = &defaultProcs[0];
|
static struct IOProcList* pIOProcListAnchor = &defaultProcs[0];
|
||||||
|
@ -253,14 +253,14 @@ static struct IOProcList* MMIO_FindProcNode(FOURCC fccIOProc)
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* MMIO_InstallIOProc [INTERNAL]
|
* MMIO_InstallIOProc [INTERNAL]
|
||||||
*/
|
*/
|
||||||
LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
|
static LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
|
||||||
DWORD dwFlags, enum mmioProcType type)
|
DWORD dwFlags, BOOL is_unicode)
|
||||||
{
|
{
|
||||||
LPMMIOPROC lpProc = NULL;
|
LPMMIOPROC lpProc = NULL;
|
||||||
struct IOProcList* pListNode;
|
struct IOProcList* pListNode;
|
||||||
struct IOProcList** ppListNode;
|
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)
|
if (dwFlags & MMIO_GLOBALPROC)
|
||||||
FIXME("Global procedures not implemented\n");
|
FIXME("Global procedures not implemented\n");
|
||||||
|
@ -274,7 +274,7 @@ LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
|
||||||
/* Fill in this node */
|
/* Fill in this node */
|
||||||
pListNode->fourCC = fccIOProc;
|
pListNode->fourCC = fccIOProc;
|
||||||
pListNode->pIOProc = pIOProc;
|
pListNode->pIOProc = pIOProc;
|
||||||
pListNode->type = type;
|
pListNode->is_unicode = is_unicode;
|
||||||
pListNode->count = 0;
|
pListNode->count = 0;
|
||||||
|
|
||||||
/* Stick it on the end of the list */
|
/* 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 */
|
/* remove it, but only if it isn't builtin */
|
||||||
if ((*ppListNode) >= defaultProcs &&
|
if ((*ppListNode) >= defaultProcs &&
|
||||||
(*ppListNode) < defaultProcs + sizeof(defaultProcs)) {
|
(*ppListNode) < defaultProcs + sizeof(defaultProcs) / sizeof(defaultProcs[0])) {
|
||||||
WARN("Tried to remove built-in mmio proc. Skipping\n");
|
WARN("Tried to remove built-in mmio proc. Skipping\n");
|
||||||
} else {
|
} else {
|
||||||
/* Okay, nuke it */
|
/* Okay, nuke it */
|
||||||
|
@ -339,39 +339,27 @@ LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
|
||||||
*/
|
*/
|
||||||
static LRESULT send_message(struct IOProcList* ioProc, LPMMIOINFO mmioinfo,
|
static LRESULT send_message(struct IOProcList* ioProc, LPMMIOINFO mmioinfo,
|
||||||
DWORD wMsg, LPARAM lParam1,
|
DWORD wMsg, LPARAM lParam1,
|
||||||
LPARAM lParam2, enum mmioProcType type)
|
LPARAM lParam2, BOOL is_unicode)
|
||||||
{
|
{
|
||||||
LRESULT result = MMSYSERR_ERROR;
|
LRESULT result = MMSYSERR_ERROR;
|
||||||
LPARAM lp1 = lParam1, lp2 = lParam2;
|
LPARAM lp1 = lParam1, lp2 = lParam2;
|
||||||
|
|
||||||
if (!ioProc) {
|
if (!ioProc) {
|
||||||
ERR("brrr\n");
|
ERR("ioProc NULL\n");
|
||||||
result = MMSYSERR_INVALPARAM;
|
return MMSYSERR_INVALPARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ioProc->type) {
|
if (ioProc->is_unicode != is_unicode) {
|
||||||
case MMIO_PROC_16:
|
/* map (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
|
||||||
if (pFnMmioCallback16)
|
FIXME("NIY 32 A<=>W mapping\n");
|
||||||
result = pFnMmioCallback16((DWORD)ioProc->pIOProc,
|
}
|
||||||
mmioinfo, wMsg, lp1, lp2);
|
result = (ioProc->pIOProc)((LPSTR)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 0
|
#if 0
|
||||||
if (ioProc->type != type) {
|
if (ioProc->is_unicode != is_unicode) {
|
||||||
/* unmap (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
|
/* unmap (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FIXME("Internal error\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -436,16 +424,16 @@ static FOURCC MMIO_ParseExtA(LPCSTR szFileName)
|
||||||
*
|
*
|
||||||
* Retrieves the mmio object from current process
|
* Retrieves the mmio object from current process
|
||||||
*/
|
*/
|
||||||
LPWINE_MMIO MMIO_Get(HMMIO h)
|
static LPWINE_MMIO MMIO_Get(HMMIO h)
|
||||||
{
|
{
|
||||||
LPWINE_MMIO wm = NULL;
|
LPWINE_MMIO wm = NULL;
|
||||||
|
|
||||||
EnterCriticalSection(&WINMM_IData.cs);
|
EnterCriticalSection(&WINMM_cs);
|
||||||
for (wm = WINMM_IData.lpMMIO; wm; wm = wm->lpNext) {
|
for (wm = MMIOList; wm; wm = wm->lpNext) {
|
||||||
if (wm->info.hmmio == h)
|
if (wm->info.hmmio == h)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&WINMM_IData.cs);
|
LeaveCriticalSection(&WINMM_cs);
|
||||||
return wm;
|
return wm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,13 +449,13 @@ static LPWINE_MMIO MMIO_Create(void)
|
||||||
|
|
||||||
wm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MMIO));
|
wm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MMIO));
|
||||||
if (wm) {
|
if (wm) {
|
||||||
EnterCriticalSection(&WINMM_IData.cs);
|
EnterCriticalSection(&WINMM_cs);
|
||||||
/* lookup next unallocated WORD handle, with a non NULL value */
|
/* lookup next unallocated WORD handle, with a non NULL value */
|
||||||
while (++MMIO_counter == 0 || MMIO_Get((HMMIO)(ULONG_PTR)MMIO_counter));
|
while (++MMIO_counter == 0 || MMIO_Get((HMMIO)(ULONG_PTR)MMIO_counter));
|
||||||
wm->info.hmmio = (HMMIO)(ULONG_PTR)MMIO_counter;
|
wm->info.hmmio = (HMMIO)(ULONG_PTR)MMIO_counter;
|
||||||
wm->lpNext = WINMM_IData.lpMMIO;
|
wm->lpNext = MMIOList;
|
||||||
WINMM_IData.lpMMIO = wm;
|
MMIOList = wm;
|
||||||
LeaveCriticalSection(&WINMM_IData.cs);
|
LeaveCriticalSection(&WINMM_cs);
|
||||||
}
|
}
|
||||||
return wm;
|
return wm;
|
||||||
}
|
}
|
||||||
|
@ -481,9 +469,9 @@ static BOOL MMIO_Destroy(LPWINE_MMIO wm)
|
||||||
{
|
{
|
||||||
LPWINE_MMIO* m;
|
LPWINE_MMIO* m;
|
||||||
|
|
||||||
EnterCriticalSection(&WINMM_IData.cs);
|
EnterCriticalSection(&WINMM_cs);
|
||||||
/* search for the matching one... */
|
/* search for the matching one... */
|
||||||
m = &(WINMM_IData.lpMMIO);
|
m = &MMIOList;
|
||||||
while (*m && *m != wm) m = &(*m)->lpNext;
|
while (*m && *m != wm) m = &(*m)->lpNext;
|
||||||
/* ...and destroy */
|
/* ...and destroy */
|
||||||
if (*m) {
|
if (*m) {
|
||||||
|
@ -491,7 +479,7 @@ static BOOL MMIO_Destroy(LPWINE_MMIO wm)
|
||||||
HeapFree(GetProcessHeap(), 0, wm);
|
HeapFree(GetProcessHeap(), 0, wm);
|
||||||
wm = NULL;
|
wm = NULL;
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&WINMM_IData.cs);
|
LeaveCriticalSection(&WINMM_cs);
|
||||||
return wm ? FALSE : TRUE;
|
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 */
|
/* not quite sure what to do here, but I'll guess */
|
||||||
if (wm->info.dwFlags & MMIO_DIRTY) {
|
if (wm->info.dwFlags & MMIO_DIRTY) {
|
||||||
/* FIXME: error handling */
|
/* FIXME: error handling */
|
||||||
send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
|
send_message(wm->ioProc, &wm->info, MMIOM_SEEK, wm->info.lBufOffset, SEEK_SET, FALSE);
|
||||||
wm->info.lBufOffset, SEEK_SET, MMIO_PROC_32A);
|
|
||||||
send_message(wm->ioProc, &wm->info, MMIOM_WRITE,
|
send_message(wm->ioProc, &wm->info, MMIOM_WRITE,
|
||||||
(LPARAM)wm->info.pchBuffer,
|
(LPARAM)wm->info.pchBuffer,
|
||||||
wm->info.pchNext - wm->info.pchBuffer, MMIO_PROC_32A);
|
wm->info.pchNext - wm->info.pchBuffer, FALSE);
|
||||||
}
|
}
|
||||||
if (uFlags & MMIO_EMPTYBUF)
|
if (uFlags & MMIO_EMPTYBUF)
|
||||||
wm->info.pchNext = wm->info.pchEndRead = wm->info.pchBuffer;
|
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;
|
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,
|
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.lBufOffset = wm->info.lDiskOffset;
|
||||||
wm->info.pchNext = wm->info.pchBuffer;
|
wm->info.pchNext = wm->info.pchBuffer;
|
||||||
|
@ -537,7 +524,7 @@ static LONG MMIO_GrabNextBuffer(LPWINE_MMIO wm, int for_read)
|
||||||
wm->bBufferLoaded = TRUE;
|
wm->bBufferLoaded = TRUE;
|
||||||
if (for_read) {
|
if (for_read) {
|
||||||
size = send_message(wm->ioProc, &wm->info, MMIOM_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)
|
if (size > 0)
|
||||||
wm->info.pchEndRead += size;
|
wm->info.pchEndRead += size;
|
||||||
else
|
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,
|
static MMRESULT MMIO_SetBuffer(WINE_MMIO* wm, void* pchBuffer, LONG cchBuffer,
|
||||||
UINT uFlags)
|
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)
|
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)
|
if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
|
||||||
return MMIOERR_CANNOTWRITE;
|
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.pchNext = wm->info.pchBuffer;
|
||||||
wm->info.pchEndRead = wm->info.pchBuffer;
|
wm->info.pchEndRead = wm->info.pchBuffer;
|
||||||
wm->info.pchEndWrite = wm->info.pchBuffer + cchBuffer;
|
wm->info.pchEndWrite = wm->info.pchBuffer + cchBuffer;
|
||||||
wm->info.lBufOffset = 0;
|
wm->info.lBufOffset = wm->info.lDiskOffset;
|
||||||
wm->bBufferLoaded = FALSE;
|
wm->bBufferLoaded = FALSE;
|
||||||
|
|
||||||
return MMSYSERR_NOERROR;
|
return MMSYSERR_NOERROR;
|
||||||
|
@ -592,13 +578,12 @@ static MMRESULT MMIO_SetBuffer(WINE_MMIO* wm, void* pchBuffer, LONG cchBuffer,
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* MMIO_Open [internal]
|
* MMIO_Open [internal]
|
||||||
*/
|
*/
|
||||||
HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags,
|
static HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags, BOOL is_unicode)
|
||||||
enum mmioProcType type)
|
|
||||||
{
|
{
|
||||||
LPWINE_MMIO wm;
|
LPWINE_MMIO wm;
|
||||||
MMIOINFO mmioinfo;
|
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) {
|
if (!refmminfo) {
|
||||||
refmminfo = &mmioinfo;
|
refmminfo = &mmioinfo;
|
||||||
|
@ -607,12 +592,14 @@ HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags,
|
||||||
mmioinfo.pIOProc = NULL;
|
mmioinfo.pIOProc = NULL;
|
||||||
mmioinfo.pchBuffer = NULL;
|
mmioinfo.pchBuffer = NULL;
|
||||||
mmioinfo.cchBuffer = 0;
|
mmioinfo.cchBuffer = 0;
|
||||||
type = MMIO_PROC_32A;
|
is_unicode = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwOpenFlags & (MMIO_PARSE|MMIO_EXIST)) {
|
if (dwOpenFlags & (MMIO_PARSE|MMIO_EXIST)) {
|
||||||
char buffer[MAX_PATH];
|
char buffer[MAX_PATH];
|
||||||
|
|
||||||
|
if (!szFileName)
|
||||||
|
return (HMMIO)FALSE;
|
||||||
if (GetFullPathNameA(szFileName, sizeof(buffer), buffer, NULL) >= sizeof(buffer))
|
if (GetFullPathNameA(szFileName, sizeof(buffer), buffer, NULL) >= sizeof(buffer))
|
||||||
return (HMMIO)FALSE;
|
return (HMMIO)FALSE;
|
||||||
if ((dwOpenFlags & MMIO_EXIST) && (GetFileAttributesA(buffer) == INVALID_FILE_ATTRIBUTES))
|
if ((dwOpenFlags & MMIO_EXIST) && (GetFileAttributesA(buffer) == INVALID_FILE_ATTRIBUTES))
|
||||||
|
@ -648,32 +635,35 @@ HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags,
|
||||||
else {
|
else {
|
||||||
wm->info.fccIOProc = refmminfo->fccIOProc;
|
wm->info.fccIOProc = refmminfo->fccIOProc;
|
||||||
MMIO_InstallIOProc(wm->info.fccIOProc, refmminfo->pIOProc,
|
MMIO_InstallIOProc(wm->info.fccIOProc, refmminfo->pIOProc,
|
||||||
MMIO_INSTALLPROC, type);
|
MMIO_INSTALLPROC, is_unicode);
|
||||||
if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) goto error2;
|
if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) goto error2;
|
||||||
assert(wm->ioProc->pIOProc == refmminfo->pIOProc);
|
assert(wm->ioProc->pIOProc == refmminfo->pIOProc);
|
||||||
wm->bTmpIOProc = TRUE;
|
wm->bTmpIOProc = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wm->bBufferLoaded = FALSE;
|
|
||||||
wm->ioProc->count++;
|
wm->ioProc->count++;
|
||||||
|
wm->info.dwFlags = dwOpenFlags;
|
||||||
|
|
||||||
if (dwOpenFlags & MMIO_ALLOCBUF) {
|
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;
|
goto error1;
|
||||||
} else if (wm->info.fccIOProc == FOURCC_MEM) {
|
} else {
|
||||||
refmminfo->wErrorRet = MMIO_SetBuffer(wm, refmminfo->pchBuffer, refmminfo->cchBuffer, 0);
|
refmminfo->wErrorRet = MMIO_SetBuffer(wm, refmminfo->pchBuffer, refmminfo->cchBuffer, 0);
|
||||||
if (refmminfo->wErrorRet != MMSYSERR_NOERROR)
|
if (refmminfo->wErrorRet != MMSYSERR_NOERROR)
|
||||||
goto error1;
|
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 */
|
/* see mmioDosIOProc for that one */
|
||||||
wm->info.adwInfo[0] = refmminfo->adwInfo[0];
|
wm->info.adwInfo[0] = refmminfo->adwInfo[0];
|
||||||
wm->info.dwFlags = dwOpenFlags;
|
|
||||||
|
|
||||||
/* call IO proc to actually open file */
|
/* call IO proc to actually open file */
|
||||||
refmminfo->wErrorRet = send_message(wm->ioProc, &wm->info, MMIOM_OPEN,
|
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 */
|
/* grab file size, when possible */
|
||||||
wm->dwFileSize = GetFileSize((HANDLE)wm->info.adwInfo[0], NULL);
|
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 );
|
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);
|
HeapFree(GetProcessHeap(), 0, szFn);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -716,7 +706,7 @@ HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO* lpmmioinfo,
|
||||||
HMMIO WINAPI mmioOpenA(LPSTR szFileName, MMIOINFO* lpmmioinfo,
|
HMMIO WINAPI mmioOpenA(LPSTR szFileName, MMIOINFO* lpmmioinfo,
|
||||||
DWORD dwOpenFlags)
|
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)
|
if ((result = MMIO_Flush(wm, 0)) != MMSYSERR_NOERROR)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
result = send_message(wm->ioProc, &wm->info, MMIOM_CLOSE,
|
result = send_message(wm->ioProc, &wm->info, MMIOM_CLOSE, uFlags, 0, FALSE);
|
||||||
uFlags, 0, MMIO_PROC_32A);
|
|
||||||
|
|
||||||
MMIO_SetBuffer(wm, NULL, 0, 0);
|
MMIO_SetBuffer(wm, NULL, 0, 0);
|
||||||
|
|
||||||
|
@ -744,7 +733,7 @@ MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
|
||||||
|
|
||||||
if (wm->bTmpIOProc)
|
if (wm->bTmpIOProc)
|
||||||
MMIO_InstallIOProc(wm->info.fccIOProc, wm->ioProc->pIOProc,
|
MMIO_InstallIOProc(wm->info.fccIOProc, wm->ioProc->pIOProc,
|
||||||
MMIO_REMOVEPROC, wm->ioProc->type);
|
MMIO_REMOVEPROC, wm->ioProc->is_unicode);
|
||||||
|
|
||||||
MMIO_Destroy(wm);
|
MMIO_Destroy(wm);
|
||||||
|
|
||||||
|
@ -759,15 +748,14 @@ LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
|
||||||
LPWINE_MMIO wm;
|
LPWINE_MMIO wm;
|
||||||
LONG count;
|
LONG count;
|
||||||
|
|
||||||
TRACE("(%p, %p, %ld);\n", hmmio, pch, cch);
|
TRACE("(%p, %p, %d);\n", hmmio, pch, cch);
|
||||||
|
|
||||||
if ((wm = MMIO_Get(hmmio)) == NULL)
|
if ((wm = MMIO_Get(hmmio)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* unbuffered case first */
|
/* unbuffered case first */
|
||||||
if (!wm->info.pchBuffer)
|
if (!wm->info.pchBuffer)
|
||||||
return send_message(wm->ioProc, &wm->info, MMIOM_READ,
|
return send_message(wm->ioProc, &wm->info, MMIOM_READ, (LPARAM)pch, cch, FALSE);
|
||||||
(LPARAM)pch, cch, MMIO_PROC_32A);
|
|
||||||
|
|
||||||
/* first try from current buffer */
|
/* first try from current buffer */
|
||||||
if (wm->info.pchNext != wm->info.pchEndRead) {
|
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;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -809,7 +797,7 @@ LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
|
||||||
LPWINE_MMIO wm;
|
LPWINE_MMIO wm;
|
||||||
LONG count;
|
LONG count;
|
||||||
|
|
||||||
TRACE("(%p, %p, %ld);\n", hmmio, pch, cch);
|
TRACE("(%p, %p, %d);\n", hmmio, pch, cch);
|
||||||
|
|
||||||
if ((wm = MMIO_Get(hmmio)) == NULL)
|
if ((wm = MMIO_Get(hmmio)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -847,12 +835,11 @@ LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
|
||||||
}
|
}
|
||||||
count = bytesW;
|
count = bytesW;
|
||||||
} else {
|
} else {
|
||||||
count = send_message(wm->ioProc, &wm->info, MMIOM_WRITE,
|
count = send_message(wm->ioProc, &wm->info, MMIOM_WRITE, (LPARAM)pch, cch, FALSE);
|
||||||
(LPARAM)pch, cch, MMIO_PROC_32A);
|
|
||||||
wm->info.lBufOffset = wm->info.lDiskOffset;
|
wm->info.lBufOffset = wm->info.lDiskOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("bytes written=%ld\n", count);
|
TRACE("bytes written=%d\n", count);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -864,15 +851,14 @@ LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
|
||||||
LPWINE_MMIO wm;
|
LPWINE_MMIO wm;
|
||||||
LONG offset;
|
LONG offset;
|
||||||
|
|
||||||
TRACE("(%p, %08lX, %d);\n", hmmio, lOffset, iOrigin);
|
TRACE("(%p, %08X, %d);\n", hmmio, lOffset, iOrigin);
|
||||||
|
|
||||||
if ((wm = MMIO_Get(hmmio)) == NULL)
|
if ((wm = MMIO_Get(hmmio)) == NULL)
|
||||||
return MMSYSERR_INVALHANDLE;
|
return MMSYSERR_INVALHANDLE;
|
||||||
|
|
||||||
/* not buffered, direct seek on file */
|
/* not buffered, direct seek on file */
|
||||||
if (!wm->info.pchBuffer)
|
if (!wm->info.pchBuffer)
|
||||||
return send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
|
return send_message(wm->ioProc, &wm->info, MMIOM_SEEK, lOffset, iOrigin, FALSE);
|
||||||
lOffset, iOrigin, MMIO_PROC_32A);
|
|
||||||
|
|
||||||
switch (iOrigin) {
|
switch (iOrigin) {
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
|
@ -911,14 +897,14 @@ LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
|
||||||
/* this also sets the wm->info.lDiskOffset field */
|
/* this also sets the wm->info.lDiskOffset field */
|
||||||
send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
|
send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
|
||||||
(offset / wm->info.cchBuffer) * wm->info.cchBuffer,
|
(offset / wm->info.cchBuffer) * wm->info.cchBuffer,
|
||||||
SEEK_SET, MMIO_PROC_32A) == -1)
|
SEEK_SET, FALSE) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
MMIO_GrabNextBuffer(wm, TRUE);
|
MMIO_GrabNextBuffer(wm, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
wm->info.pchNext = wm->info.pchBuffer + (offset - wm->info.lBufOffset);
|
wm->info.pchNext = wm->info.pchBuffer + (offset - wm->info.lBufOffset);
|
||||||
|
|
||||||
TRACE("=> %ld\n", offset);
|
TRACE("=> %d\n", offset);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -934,10 +920,7 @@ MMRESULT WINAPI mmioGetInfo(HMMIO hmmio, MMIOINFO* lpmmioinfo, UINT uFlags)
|
||||||
if ((wm = MMIO_Get(hmmio)) == NULL)
|
if ((wm = MMIO_Get(hmmio)) == NULL)
|
||||||
return MMSYSERR_INVALHANDLE;
|
return MMSYSERR_INVALHANDLE;
|
||||||
|
|
||||||
memcpy(lpmmioinfo, &wm->info, sizeof(MMIOINFO));
|
*lpmmioinfo = wm->info;
|
||||||
/* don't expose 16 bit ioproc:s */
|
|
||||||
if (wm->ioProc->type != MMIO_PROC_16)
|
|
||||||
lpmmioinfo->pIOProc = wm->ioProc->pIOProc;
|
|
||||||
|
|
||||||
return MMSYSERR_NOERROR;
|
return MMSYSERR_NOERROR;
|
||||||
}
|
}
|
||||||
|
@ -976,7 +959,7 @@ MMRESULT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT
|
||||||
{
|
{
|
||||||
LPWINE_MMIO wm;
|
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);
|
hmmio, pchBuffer, cchBuffer, uFlags);
|
||||||
|
|
||||||
if ((wm = MMIO_Get(hmmio)) == NULL)
|
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))
|
if (uFlags == MMIO_WRITE && (lpmmioinfo->dwFlags & MMIO_DIRTY))
|
||||||
{
|
{
|
||||||
send_message(wm->ioProc, &wm->info, MMIOM_SEEK,
|
send_message(wm->ioProc, &wm->info, MMIOM_SEEK, lpmmioinfo->lBufOffset, SEEK_SET, FALSE);
|
||||||
lpmmioinfo->lBufOffset, SEEK_SET, MMIO_PROC_32A);
|
send_message(wm->ioProc, &wm->info, MMIOM_WRITE, (LPARAM)lpmmioinfo->pchBuffer,
|
||||||
send_message(wm->ioProc, &wm->info, MMIOM_WRITE,
|
lpmmioinfo->pchNext - lpmmioinfo->pchBuffer, FALSE);
|
||||||
(LPARAM)lpmmioinfo->pchBuffer,
|
|
||||||
lpmmioinfo->pchNext - lpmmioinfo->pchBuffer, MMIO_PROC_32A);
|
|
||||||
lpmmioinfo->dwFlags &= ~MMIO_DIRTY;
|
lpmmioinfo->dwFlags &= ~MMIO_DIRTY;
|
||||||
}
|
}
|
||||||
if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
|
if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
|
||||||
|
@ -1091,7 +1072,7 @@ FOURCC WINAPI mmioStringToFOURCCW(LPCWSTR sz, UINT uFlags)
|
||||||
LPMMIOPROC WINAPI mmioInstallIOProcA(FOURCC fccIOProc,
|
LPMMIOPROC WINAPI mmioInstallIOProcA(FOURCC fccIOProc,
|
||||||
LPMMIOPROC pIOProc, DWORD dwFlags)
|
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 WINAPI mmioInstallIOProcW(FOURCC fccIOProc,
|
||||||
LPMMIOPROC pIOProc, DWORD dwFlags)
|
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,
|
static LRESULT MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
|
||||||
LPARAM lParam2, enum mmioProcType type)
|
LPARAM lParam2, BOOL is_unicode)
|
||||||
{
|
{
|
||||||
LPWINE_MMIO wm;
|
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)
|
if (uMessage < MMIOM_USER)
|
||||||
return MMSYSERR_INVALPARAM;
|
return MMSYSERR_INVALPARAM;
|
||||||
|
@ -1121,7 +1102,7 @@ LRESULT MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
|
||||||
if ((wm = MMIO_Get(hmmio)) == NULL)
|
if ((wm = MMIO_Get(hmmio)) == NULL)
|
||||||
return MMSYSERR_INVALHANDLE;
|
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,
|
LRESULT WINAPI mmioSendMessage(HMMIO hmmio, UINT uMessage,
|
||||||
LPARAM lParam1, LPARAM lParam2)
|
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 srchCkId;
|
||||||
FOURCC srchType;
|
FOURCC srchType;
|
||||||
|
|
||||||
|
|
||||||
TRACE("(%p, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags);
|
TRACE("(%p, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags);
|
||||||
|
|
||||||
if (lpck == NULL)
|
if (lpck == NULL)
|
||||||
return MMSYSERR_INVALPARAM;
|
return MMSYSERR_INVALPARAM;
|
||||||
|
|
||||||
dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
|
dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
|
||||||
TRACE("dwOldPos=%ld\n", dwOldPos);
|
TRACE("dwOldPos=%d\n", dwOldPos);
|
||||||
|
|
||||||
if (lpckParent != NULL) {
|
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); */
|
/* EPP: was dwOldPos = mmioSeek(hmmio,lpckParent->dwDataOffset,SEEK_SET); */
|
||||||
if (dwOldPos < lpckParent->dwDataOffset ||
|
if (dwOldPos < lpckParent->dwDataOffset ||
|
||||||
dwOldPos >= lpckParent->dwDataOffset + lpckParent->cksize) {
|
dwOldPos >= lpckParent->dwDataOffset + lpckParent->cksize) {
|
||||||
|
@ -1166,62 +1146,54 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck,
|
||||||
* examples disagree -Marcus,990216.
|
* examples disagree -Marcus,990216.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
srchCkId = 0;
|
||||||
srchType = 0;
|
srchType = 0;
|
||||||
|
|
||||||
/* find_chunk looks for 'ckid' */
|
/* find_chunk looks for 'ckid' */
|
||||||
if (uFlags & MMIO_FINDCHUNK)
|
if (uFlags & MMIO_FINDCHUNK)
|
||||||
srchCkId = lpck->ckid;
|
srchCkId = lpck->ckid;
|
||||||
|
|
||||||
/* find_riff and find_list look for 'fccType' */
|
/* find_riff and find_list look for 'fccType' */
|
||||||
if (uFlags & MMIO_FINDLIST) {
|
if (uFlags & MMIO_FINDLIST)
|
||||||
|
{
|
||||||
srchCkId = FOURCC_LIST;
|
srchCkId = FOURCC_LIST;
|
||||||
srchType = lpck->fccType;
|
srchType = lpck->fccType;
|
||||||
}
|
}
|
||||||
if (uFlags & MMIO_FINDRIFF) {
|
|
||||||
|
if (uFlags & MMIO_FINDRIFF)
|
||||||
|
{
|
||||||
srchCkId = FOURCC_RIFF;
|
srchCkId = FOURCC_RIFF;
|
||||||
srchType = lpck->fccType;
|
srchType = lpck->fccType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uFlags & (MMIO_FINDCHUNK|MMIO_FINDLIST|MMIO_FINDRIFF)) {
|
TRACE("searching for %4.4s.%4.4s\n",
|
||||||
TRACE("searching for %.4s.%.4s\n",
|
(LPCSTR)&srchCkId, srchType ? (LPCSTR)&srchType : "any");
|
||||||
(LPSTR)&srchCkId,
|
|
||||||
srchType?(LPSTR)&srchType:"any ");
|
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE)
|
||||||
LONG ix;
|
{
|
||||||
|
LONG ix;
|
||||||
|
|
||||||
ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
|
ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
|
||||||
if (ix < 2*sizeof(DWORD)) {
|
if (ix < 2*sizeof(DWORD))
|
||||||
mmioSeek(hmmio, dwOldPos, SEEK_SET);
|
{
|
||||||
WARN("return ChunkNotFound\n");
|
mmioSeek(hmmio, dwOldPos, SEEK_SET);
|
||||||
return MMIOERR_CHUNKNOTFOUND;
|
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;
|
|
||||||
|
|
||||||
dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1);
|
lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
|
||||||
mmioSeek(hmmio, dwOldPos, SEEK_SET);
|
TRACE("ckid=%4.4s fcc=%4.4s cksize=%08X !\n",
|
||||||
}
|
(LPCSTR)&lpck->ckid,
|
||||||
} else {
|
srchType ? (LPCSTR)&lpck->fccType:"<na>",
|
||||||
/* FIXME: unverified, does it do this? */
|
lpck->cksize);
|
||||||
/* NB: This part is used by WAVE_mciOpen, among others */
|
if ( (!srchCkId || (srchCkId == lpck->ckid)) &&
|
||||||
if (mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD)) < 3 * sizeof(DWORD)) {
|
(!srchType || (srchType == lpck->fccType)) )
|
||||||
mmioSeek(hmmio, dwOldPos, SEEK_SET);
|
break;
|
||||||
WARN("return ChunkNotFound 2nd\n");
|
|
||||||
return MMIOERR_CHUNKNOTFOUND;
|
dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1);
|
||||||
}
|
mmioSeek(hmmio, dwOldPos, SEEK_SET);
|
||||||
lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lpck->dwFlags = 0;
|
lpck->dwFlags = 0;
|
||||||
/* If we were looking for RIFF/LIST chunks, the final file position
|
/* If we were looking for RIFF/LIST chunks, the final file position
|
||||||
* is after the chunkid. If we were just looking for the chunk
|
* 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)
|
if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST)
|
||||||
mmioSeek(hmmio, lpck->dwDataOffset + sizeof(DWORD), SEEK_SET);
|
mmioSeek(hmmio, lpck->dwDataOffset + sizeof(DWORD), SEEK_SET);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
|
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,
|
(LPSTR)&lpck->ckid, lpck->cksize, lpck->dwDataOffset,
|
||||||
lpck->fccType, srchType?(LPSTR)&lpck->fccType:"");
|
lpck->fccType, srchType?(LPSTR)&lpck->fccType:"");
|
||||||
return MMSYSERR_NOERROR;
|
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");
|
TRACE("Chunk is dirty, checking if chunk's size is correct\n");
|
||||||
dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
|
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;
|
dwNewSize = dwOldPos - lpck->dwDataOffset;
|
||||||
if (dwNewSize != lpck->cksize) {
|
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;
|
lpck->cksize = dwNewSize;
|
||||||
|
|
||||||
/* pad odd size with 0 */
|
/* 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);
|
TRACE("(%p, %p, %04X);\n", hmmio, lpck, uFlags);
|
||||||
|
|
||||||
dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
|
dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
|
||||||
TRACE("dwOldPos=%ld\n", dwOldPos);
|
TRACE("dwOldPos=%d\n", dwOldPos);
|
||||||
|
|
||||||
if (uFlags == MMIO_CREATELIST)
|
if (uFlags == MMIO_CREATELIST)
|
||||||
lpck->ckid = FOURCC_LIST;
|
lpck->ckid = FOURCC_LIST;
|
||||||
|
@ -1300,7 +1275,7 @@ MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO* lpck, UINT uFlags)
|
||||||
lpck->dwFlags = MMIO_DIRTY;
|
lpck->dwFlags = MMIO_DIRTY;
|
||||||
|
|
||||||
ix = mmioWrite(hmmio, (LPSTR)lpck, size);
|
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) {
|
if (ix < size) {
|
||||||
mmioSeek(hmmio, dwOldPos, SEEK_SET);
|
mmioSeek(hmmio, dwOldPos, SEEK_SET);
|
||||||
WARN("return CannotWrite\n");
|
WARN("return CannotWrite\n");
|
||||||
|
@ -1320,7 +1295,7 @@ MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
|
||||||
struct IOProcList tmp;
|
struct IOProcList tmp;
|
||||||
FOURCC fcc;
|
FOURCC fcc;
|
||||||
|
|
||||||
TRACE("('%s', '%s', %p, %08lX);\n",
|
TRACE("('%s', '%s', %p, %08X);\n",
|
||||||
debugstr_a(szFileName), debugstr_a(szNewFileName), lpmmioinfo, dwFlags);
|
debugstr_a(szFileName), debugstr_a(szNewFileName), lpmmioinfo, dwFlags);
|
||||||
|
|
||||||
/* If both params are NULL, then parse the file name */
|
/* If both params are NULL, then parse the file name */
|
||||||
|
@ -1341,7 +1316,7 @@ MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
|
||||||
ioProc = &tmp;
|
ioProc = &tmp;
|
||||||
tmp.fourCC = lpmmioinfo->fccIOProc;
|
tmp.fourCC = lpmmioinfo->fccIOProc;
|
||||||
tmp.pIOProc = lpmmioinfo->pIOProc;
|
tmp.pIOProc = lpmmioinfo->pIOProc;
|
||||||
tmp.type = MMIO_PROC_32A;
|
tmp.is_unicode = FALSE;
|
||||||
tmp.count = 1;
|
tmp.count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1349,7 +1324,7 @@ MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
|
||||||
* or make a copy of it because it's const ???
|
* or make a copy of it because it's const ???
|
||||||
*/
|
*/
|
||||||
return send_message(ioProc, (MMIOINFO*)lpmmioinfo, MMIOM_RENAME,
|
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
|
@ -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
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMSYTEM functions
|
* MMSYSTEM functions
|
||||||
*
|
*
|
||||||
* Copyright 1993 Martin Ayotte
|
* Copyright 1993 Martin Ayotte
|
||||||
* 1998-2002 Eric Pouech
|
* 1998-2002 Eric Pouech
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* 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>
|
#include <stdarg.h>
|
||||||
|
@ -37,6 +37,20 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
|
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)
|
static HMMIO get_mmioFromFile(LPCWSTR lpszName)
|
||||||
{
|
{
|
||||||
HMMIO ret;
|
HMMIO ret;
|
||||||
|
@ -133,19 +147,19 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
|
||||||
hmmio = mmioOpenW(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
|
hmmio = mmioOpenW(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
|
||||||
if (hmmio) return hmmio;
|
if (hmmio) return hmmio;
|
||||||
none:
|
none:
|
||||||
WARN("can't find SystemSound='%s' !\n", debugstr_w(lpszName));
|
WARN("can't find SystemSound=%s !\n", debugstr_w(lpszName));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct playsound_data
|
struct playsound_data
|
||||||
{
|
{
|
||||||
HANDLE hEvent;
|
HANDLE hEvent;
|
||||||
DWORD dwEventCount;
|
LONG dwEventCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg,
|
static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg,
|
||||||
DWORD dwInstance,
|
DWORD_PTR dwInstance,
|
||||||
DWORD dwParam1, DWORD dwParam2)
|
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||||
{
|
{
|
||||||
struct playsound_data* s = (struct playsound_data*)dwInstance;
|
struct playsound_data* s = (struct playsound_data*)dwInstance;
|
||||||
|
|
||||||
|
@ -154,7 +168,7 @@ static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg,
|
||||||
case WOM_CLOSE:
|
case WOM_CLOSE:
|
||||||
break;
|
break;
|
||||||
case WOM_DONE:
|
case WOM_DONE:
|
||||||
InterlockedIncrement((PLONG)&s->dwEventCount);
|
InterlockedIncrement(&s->dwEventCount);
|
||||||
TRACE("Returning waveHdr=%lx\n", dwParam1);
|
TRACE("Returning waveHdr=%lx\n", dwParam1);
|
||||||
SetEvent(s->hEvent);
|
SetEvent(s->hEvent);
|
||||||
break;
|
break;
|
||||||
|
@ -167,8 +181,8 @@ static void PlaySound_WaitDone(struct playsound_data* s)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ResetEvent(s->hEvent);
|
ResetEvent(s->hEvent);
|
||||||
if (InterlockedDecrement((PLONG)&s->dwEventCount) >= 0) break;
|
if (InterlockedDecrement(&s->dwEventCount) >= 0) break;
|
||||||
InterlockedIncrement((PLONG)&s->dwEventCount);
|
InterlockedIncrement(&s->dwEventCount);
|
||||||
|
|
||||||
WaitForSingleObject(s->hEvent, INFINITE);
|
WaitForSingleObject(s->hEvent, INFINITE);
|
||||||
}
|
}
|
||||||
|
@ -179,11 +193,12 @@ static BOOL PlaySound_IsString(DWORD fdwSound, const void* psz)
|
||||||
/* SND_RESOURCE is 0x40004 while
|
/* SND_RESOURCE is 0x40004 while
|
||||||
* SND_MEMORY is 0x00004
|
* 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_RESOURCE: return HIWORD(psz) != 0; /* by name or by ID ? */
|
||||||
|
case SND_ALIAS_ID:
|
||||||
case SND_MEMORY: return FALSE;
|
case SND_MEMORY: return FALSE;
|
||||||
case SND_ALIAS: /* what about ALIAS_ID ??? */
|
case SND_ALIAS:
|
||||||
case SND_FILENAME:
|
case SND_FILENAME:
|
||||||
case 0: return TRUE;
|
case 0: return TRUE;
|
||||||
default: FIXME("WTF\n"); return FALSE;
|
default: FIXME("WTF\n"); return FALSE;
|
||||||
|
@ -194,11 +209,11 @@ static void PlaySound_Free(WINE_PLAYSOUND* wps)
|
||||||
{
|
{
|
||||||
WINE_PLAYSOUND** p;
|
WINE_PLAYSOUND** p;
|
||||||
|
|
||||||
EnterCriticalSection(&WINMM_IData.cs);
|
EnterCriticalSection(&WINMM_cs);
|
||||||
for (p = &WINMM_IData.lpPlaySound; *p && *p != wps; p = &((*p)->lpNext));
|
for (p = &PlaySoundList; *p && *p != wps; p = &((*p)->lpNext));
|
||||||
if (*p) *p = (*p)->lpNext;
|
if (*p) *p = (*p)->lpNext;
|
||||||
if (WINMM_IData.lpPlaySound == NULL) SetEvent(WINMM_IData.psLastEvent);
|
if (PlaySoundList == NULL) SetEvent(psLastEvent);
|
||||||
LeaveCriticalSection(&WINMM_IData.cs);
|
LeaveCriticalSection(&WINMM_cs);
|
||||||
if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound);
|
if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound);
|
||||||
if (wps->hThread) CloseHandle(wps->hThread);
|
if (wps->hThread) CloseHandle(wps->hThread);
|
||||||
HeapFree(GetProcessHeap(), 0, wps);
|
HeapFree(GetProcessHeap(), 0, wps);
|
||||||
|
@ -220,10 +235,10 @@ static WINE_PLAYSOUND* PlaySound_Alloc(const void* pszSound, HMODULE hmod,
|
||||||
{
|
{
|
||||||
if (fdwSound & SND_ASYNC)
|
if (fdwSound & SND_ASYNC)
|
||||||
{
|
{
|
||||||
wps->pszSound = HeapAlloc(GetProcessHeap(), 0,
|
LPWSTR sound = HeapAlloc(GetProcessHeap(), 0,
|
||||||
(lstrlenW(pszSound)+1) * sizeof(WCHAR));
|
(lstrlenW(pszSound)+1) * sizeof(WCHAR));
|
||||||
if (!wps->pszSound) goto oom_error;
|
if (!sound) goto oom_error;
|
||||||
lstrcpyW((LPWSTR)wps->pszSound, pszSound);
|
wps->pszSound = lstrcpyW(sound, pszSound);
|
||||||
wps->bAlloc = TRUE;
|
wps->bAlloc = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -249,13 +264,12 @@ static WINE_PLAYSOUND* PlaySound_Alloc(const void* pszSound, HMODULE hmod,
|
||||||
|
|
||||||
static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
||||||
{
|
{
|
||||||
WINE_PLAYSOUND* wps = (WINE_PLAYSOUND*)arg;
|
WINE_PLAYSOUND* wps = arg;
|
||||||
BOOL bRet = FALSE;
|
BOOL bRet = FALSE;
|
||||||
HMMIO hmmio = 0;
|
HMMIO hmmio = 0;
|
||||||
MMCKINFO ckMainRIFF;
|
MMCKINFO ckMainRIFF;
|
||||||
MMCKINFO mmckInfo;
|
MMCKINFO mmckInfo;
|
||||||
LPWAVEFORMATEX lpWaveFormat = NULL;
|
LPWAVEFORMATEX lpWaveFormat = NULL;
|
||||||
HWAVEOUT hWave = 0;
|
|
||||||
LPWAVEHDR waveHdr = NULL;
|
LPWAVEHDR waveHdr = NULL;
|
||||||
INT count, bufsize, left, index;
|
INT count, bufsize, left, index;
|
||||||
struct playsound_data s;
|
struct playsound_data s;
|
||||||
|
@ -263,7 +277,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
||||||
|
|
||||||
s.hEvent = 0;
|
s.hEvent = 0;
|
||||||
|
|
||||||
TRACE("SoundName='%s' !\n", debugstr_w(wps->pszSound));
|
TRACE("SoundName=%s !\n", debugstr_w(wps->pszSound));
|
||||||
|
|
||||||
/* if resource, grab it */
|
/* if resource, grab it */
|
||||||
if ((wps->fdwSound & SND_RESOURCE) == SND_RESOURCE) {
|
if ((wps->fdwSound & SND_RESOURCE) == SND_RESOURCE) {
|
||||||
|
@ -289,13 +303,43 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
||||||
|
|
||||||
memset(&mminfo, 0, sizeof(mminfo));
|
memset(&mminfo, 0, sizeof(mminfo));
|
||||||
mminfo.fccIOProc = FOURCC_MEM;
|
mminfo.fccIOProc = FOURCC_MEM;
|
||||||
mminfo.pchBuffer = (LPSTR)data;
|
mminfo.pchBuffer = data;
|
||||||
mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */
|
mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */
|
||||||
TRACE("Memory sound %p\n", data);
|
TRACE("Memory sound %p\n", data);
|
||||||
hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ);
|
hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ);
|
||||||
}
|
}
|
||||||
else if (wps->fdwSound & SND_ALIAS)
|
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);
|
hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
|
||||||
}
|
}
|
||||||
else if (wps->fdwSound & SND_FILENAME)
|
else if (wps->fdwSound & SND_FILENAME)
|
||||||
|
@ -317,7 +361,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
||||||
if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0))
|
if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0))
|
||||||
goto errCleanUp;
|
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);
|
(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
|
||||||
|
|
||||||
if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
|
if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
|
||||||
|
@ -328,18 +372,18 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
||||||
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
|
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
|
||||||
goto errCleanUp;
|
goto errCleanUp;
|
||||||
|
|
||||||
TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
|
TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
|
||||||
(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
|
(LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
|
||||||
|
|
||||||
lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, 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;
|
goto errCleanUp;
|
||||||
|
|
||||||
TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag);
|
TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag);
|
||||||
TRACE("nChannels=%d \n", lpWaveFormat->nChannels);
|
TRACE("nChannels=%d\n", lpWaveFormat->nChannels);
|
||||||
TRACE("nSamplesPerSec=%ld\n", lpWaveFormat->nSamplesPerSec);
|
TRACE("nSamplesPerSec=%d\n", lpWaveFormat->nSamplesPerSec);
|
||||||
TRACE("nAvgBytesPerSec=%ld\n", lpWaveFormat->nAvgBytesPerSec);
|
TRACE("nAvgBytesPerSec=%d\n", lpWaveFormat->nAvgBytesPerSec);
|
||||||
TRACE("nBlockAlign=%d \n", lpWaveFormat->nBlockAlign);
|
TRACE("nBlockAlign=%d\n", lpWaveFormat->nBlockAlign);
|
||||||
TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample);
|
TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample);
|
||||||
|
|
||||||
/* move to end of 'fmt ' chunk */
|
/* move to end of 'fmt ' chunk */
|
||||||
|
@ -349,13 +393,13 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
||||||
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
|
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
|
||||||
goto errCleanUp;
|
goto errCleanUp;
|
||||||
|
|
||||||
TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX\n",
|
TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
|
||||||
(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
|
(LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
|
||||||
|
|
||||||
s.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
s.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
if (waveOutOpen(&hWave, WAVE_MAPPER, lpWaveFormat, (DWORD)PlaySound_Callback,
|
if (waveOutOpen(&wps->hWave, WAVE_MAPPER, lpWaveFormat, (DWORD_PTR)PlaySound_Callback,
|
||||||
(DWORD)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
|
(DWORD_PTR)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
|
||||||
goto errCleanUp;
|
goto errCleanUp;
|
||||||
|
|
||||||
/* make it so that 3 buffers per second are needed */
|
/* 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].dwLoops = waveHdr[1].dwLoops = 0L;
|
||||||
waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
|
waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
|
||||||
waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
|
waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
|
||||||
if (waveOutPrepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
|
if (waveOutPrepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
|
||||||
waveOutPrepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR))) {
|
waveOutPrepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
|
||||||
goto errCleanUp;
|
goto errCleanUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +426,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
||||||
mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
|
mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
|
||||||
while (left)
|
while (left)
|
||||||
{
|
{
|
||||||
if (WaitForSingleObject(WINMM_IData.psStopEvent, 0) == WAIT_OBJECT_0)
|
if (WaitForSingleObject(psStopEvent, 0) == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
wps->bLoop = FALSE;
|
wps->bLoop = FALSE;
|
||||||
break;
|
break;
|
||||||
|
@ -392,7 +436,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
||||||
left -= count;
|
left -= count;
|
||||||
waveHdr[index].dwBufferLength = count;
|
waveHdr[index].dwBufferLength = count;
|
||||||
waveHdr[index].dwFlags &= ~WHDR_DONE;
|
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;
|
index ^= 1;
|
||||||
PlaySound_WaitDone(&s);
|
PlaySound_WaitDone(&s);
|
||||||
}
|
}
|
||||||
|
@ -402,17 +446,17 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
||||||
} while (wps->bLoop);
|
} while (wps->bLoop);
|
||||||
|
|
||||||
PlaySound_WaitDone(&s); /* for last buffer */
|
PlaySound_WaitDone(&s); /* for last buffer */
|
||||||
waveOutReset(hWave);
|
waveOutReset(wps->hWave);
|
||||||
|
|
||||||
waveOutUnprepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR));
|
waveOutUnprepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR));
|
||||||
waveOutUnprepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR));
|
waveOutUnprepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR));
|
||||||
|
|
||||||
errCleanUp:
|
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);
|
CloseHandle(s.hEvent);
|
||||||
HeapFree(GetProcessHeap(), 0, waveHdr);
|
HeapFree(GetProcessHeap(), 0, waveHdr);
|
||||||
HeapFree(GetProcessHeap(), 0, lpWaveFormat);
|
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);
|
if (hmmio) mmioClose(hmmio, 0);
|
||||||
|
|
||||||
PlaySound_Free(wps);
|
PlaySound_Free(wps);
|
||||||
|
@ -424,13 +468,13 @@ static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSo
|
||||||
{
|
{
|
||||||
WINE_PLAYSOUND* wps = NULL;
|
WINE_PLAYSOUND* wps = NULL;
|
||||||
|
|
||||||
TRACE("pszSound='%p' hmod=%p fdwSound=%08lX\n",
|
TRACE("pszSound='%p' hmod=%p fdwSound=%08X\n",
|
||||||
pszSound, hmod, fdwSound);
|
pszSound, hmod, fdwSound);
|
||||||
|
|
||||||
/* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP !
|
/* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP !
|
||||||
* there could be one if several sounds can be played at once...
|
* 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;
|
return FALSE;
|
||||||
|
|
||||||
/* alloc internal structure, if we need to play something */
|
/* 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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterCriticalSection(&WINMM_IData.cs);
|
EnterCriticalSection(&WINMM_cs);
|
||||||
/* since several threads can enter PlaySound in parallel, we're not
|
/* since several threads can enter PlaySound in parallel, we're not
|
||||||
* sure, at this point, that another thread didn't start a new playsound
|
* 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
|
/* FIXME: doc says we have to stop all instances of pszSound if it's non
|
||||||
* NULL... as of today, we stop all playing instances */
|
* NULL... as of today, we stop all playing instances */
|
||||||
SetEvent(WINMM_IData.psStopEvent);
|
SetEvent(psStopEvent);
|
||||||
|
|
||||||
LeaveCriticalSection(&WINMM_IData.cs);
|
waveOutReset(PlaySoundList->hWave);
|
||||||
WaitForSingleObject(WINMM_IData.psLastEvent, INFINITE);
|
LeaveCriticalSection(&WINMM_cs);
|
||||||
EnterCriticalSection(&WINMM_IData.cs);
|
WaitForSingleObject(psLastEvent, INFINITE);
|
||||||
|
EnterCriticalSection(&WINMM_cs);
|
||||||
|
|
||||||
ResetEvent(WINMM_IData.psStopEvent);
|
ResetEvent(psStopEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wps) wps->lpNext = WINMM_IData.lpPlaySound;
|
if (wps) wps->lpNext = PlaySoundList;
|
||||||
WINMM_IData.lpPlaySound = wps;
|
PlaySoundList = wps;
|
||||||
LeaveCriticalSection(&WINMM_IData.cs);
|
LeaveCriticalSection(&WINMM_cs);
|
||||||
|
|
||||||
if (!pszSound || (fdwSound & SND_PURGE)) return TRUE;
|
if (!pszSound || (fdwSound & SND_PURGE)) return TRUE;
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,14 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* 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 "config.h"
|
||||||
#include "wine/port.h"
|
#include "wine/port.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
|
@ -31,6 +32,12 @@
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_POLL_H
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -38,15 +45,47 @@
|
||||||
|
|
||||||
#include "winemm.h"
|
#include "winemm.h"
|
||||||
|
|
||||||
|
#include "wine/list.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(mmtime);
|
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 HANDLE TIME_hMMTimer;
|
||||||
static LPWINE_TIMERENTRY TIME_TimersList;
|
|
||||||
static HANDLE TIME_hKillEvent;
|
|
||||||
static HANDLE TIME_hWakeEvent;
|
|
||||||
static BOOL TIME_TimeToDie = TRUE;
|
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.
|
* Some observations on the behavior of winmm on Windows.
|
||||||
|
@ -77,58 +116,15 @@ static BOOL TIME_TimeToDie = TRUE;
|
||||||
#define MMSYSTIME_MININTERVAL (1)
|
#define MMSYSTIME_MININTERVAL (1)
|
||||||
#define MMSYSTIME_MAXINTERVAL (65535)
|
#define MMSYSTIME_MAXINTERVAL (65535)
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* TIME_MMSysTimeCallback
|
* TIME_MMSysTimeCallback
|
||||||
*/
|
*/
|
||||||
static DWORD CALLBACK TIME_MMSysTimeCallback(LPWINE_MM_IDATA iData)
|
static int TIME_MMSysTimeCallback(void)
|
||||||
{
|
{
|
||||||
static int nSizeLpTimers;
|
WINE_TIMERENTRY *timer, *to_free;
|
||||||
static LPWINE_TIMERENTRY lpTimers;
|
int delta_time;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* since timeSetEvent() and timeKillEvent() can be called
|
/* since timeSetEvent() and timeKillEvent() can be called
|
||||||
* from 16 bit code, there are cases where win16 lock is
|
* 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
|
* To cope with that, we just copy the WINE_TIMERENTRY struct
|
||||||
* that need to trigger the callback, and call it without the
|
* that need to trigger the callback, and call it without the
|
||||||
* mm timer crit sect locked.
|
* 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);
|
EnterCriticalSection(&WINMM_cs);
|
||||||
for (ptimer = &TIME_TimersList; *ptimer != NULL; ) {
|
for (;;)
|
||||||
timer = *ptimer;
|
{
|
||||||
next_ptimer = &timer->lpNext;
|
struct list *ptr = list_head( &timer_list );
|
||||||
if (cur_time >= timer->dwTriggerTime)
|
if (!ptr)
|
||||||
{
|
{
|
||||||
if (timer->lpFunc) {
|
delta_time = -1;
|
||||||
if (idx == nSizeLpTimers) {
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
delta_time = timer->dwTriggerTime - cur_time;
|
|
||||||
|
|
||||||
/* Determine when we need to return to this function */
|
timer = LIST_ENTRY( ptr, WINE_TIMERENTRY, entry );
|
||||||
ret_time = min(ret_time, delta_time);
|
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(&WINMM_cs);
|
||||||
LeaveCriticalSection(&iData->cs);
|
return delta_time;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -225,9 +197,12 @@ static LPWINE_TIMERENTRY lpTimers;
|
||||||
*/
|
*/
|
||||||
static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
|
static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
|
||||||
{
|
{
|
||||||
LPWINE_MM_IDATA iData = (LPWINE_MM_IDATA)arg;
|
int sleep_time, ret;
|
||||||
DWORD sleep_time;
|
char readme[16];
|
||||||
DWORD rc;
|
struct pollfd pfd;
|
||||||
|
|
||||||
|
pfd.fd = TIME_fdWake[0];
|
||||||
|
pfd.events = POLLIN;
|
||||||
|
|
||||||
TRACE("Starting main winmm thread\n");
|
TRACE("Starting main winmm thread\n");
|
||||||
|
|
||||||
|
@ -239,17 +214,21 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
|
||||||
|
|
||||||
while (! TIME_TimeToDie)
|
while (! TIME_TimeToDie)
|
||||||
{
|
{
|
||||||
sleep_time = TIME_MMSysTimeCallback(iData);
|
sleep_time = TIME_MMSysTimeCallback();
|
||||||
|
|
||||||
if (sleep_time == 0)
|
if (sleep_time == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rc = WaitForSingleObject(TIME_hWakeEvent, sleep_time);
|
if ((ret = poll(&pfd, 1, sleep_time)) < 0)
|
||||||
if (rc != WAIT_TIMEOUT && rc != WAIT_OBJECT_0)
|
|
||||||
{
|
{
|
||||||
FIXME("Unexpected error %ld(%ld) in timer thread\n", rc, GetLastError());
|
if (errno != EINTR && errno != EAGAIN)
|
||||||
break;
|
{
|
||||||
}
|
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");
|
TRACE("Exiting main winmm thread\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -258,34 +237,50 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* TIME_MMTimeStart
|
* TIME_MMTimeStart
|
||||||
*/
|
*/
|
||||||
void TIME_MMTimeStart(void)
|
static void TIME_MMTimeStart(void)
|
||||||
{
|
{
|
||||||
if (!TIME_hMMTimer) {
|
if (!TIME_hMMTimer) {
|
||||||
TIME_TimersList = NULL;
|
if (pipe(TIME_fdWake) < 0)
|
||||||
TIME_hWakeEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
{
|
||||||
|
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_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);
|
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
|
* TIME_MMTimeStop
|
||||||
*/
|
*/
|
||||||
void TIME_MMTimeStop(void)
|
void TIME_MMTimeStop(void)
|
||||||
{
|
{
|
||||||
if (TIME_hMMTimer) {
|
if (TIME_hMMTimer) {
|
||||||
|
const char a='a';
|
||||||
|
|
||||||
TIME_TimeToDie = TRUE;
|
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);
|
||||||
WaitForSingleObject(TIME_hMMTimer, INFINITE);
|
close(TIME_fdWake[0]);
|
||||||
|
close(TIME_fdWake[1]);
|
||||||
CloseHandle(TIME_hMMTimer);
|
TIME_fdWake[0] = TIME_fdWake[1] = -1;
|
||||||
CloseHandle(TIME_hWakeEvent);
|
CloseHandle(TIME_hMMTimer);
|
||||||
TIME_hMMTimer = 0;
|
TIME_hMMTimer = 0;
|
||||||
TIME_TimersList = NULL;
|
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,
|
MMRESULT WINAPI timeSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc,
|
||||||
LPTIMECALLBACK lpFunc, DWORD dwUser, UINT wFlags)
|
DWORD_PTR dwUser, UINT wFlags)
|
||||||
{
|
{
|
||||||
WORD wNewID = 0;
|
WORD wNewID = 0;
|
||||||
LPWINE_TIMERENTRY lpNewTimer;
|
LPWINE_TIMERENTRY lpNewTimer;
|
||||||
LPWINE_TIMERENTRY lpTimer;
|
LPWINE_TIMERENTRY lpTimer;
|
||||||
|
const char c = 'c';
|
||||||
|
|
||||||
TRACE("(%u, %u, %p, %08lX, %04X);\n", wDelay, wResol, lpFunc, dwUser, wFlags);
|
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)
|
if (lpNewTimer == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
TIME_MMTimeStart();
|
|
||||||
|
|
||||||
lpNewTimer->wDelay = wDelay;
|
lpNewTimer->wDelay = wDelay;
|
||||||
lpNewTimer->dwTriggerTime = GetTickCount() + wDelay;
|
lpNewTimer->dwTriggerTime = GetTickCount() + wDelay;
|
||||||
|
|
||||||
|
@ -335,70 +329,58 @@ WORD TIME_SetEventInternal(UINT wDelay, UINT wResol,
|
||||||
lpNewTimer->dwUser = dwUser;
|
lpNewTimer->dwUser = dwUser;
|
||||||
lpNewTimer->wFlags = wFlags;
|
lpNewTimer->wFlags = wFlags;
|
||||||
|
|
||||||
EnterCriticalSection(&WINMM_IData.cs);
|
EnterCriticalSection(&WINMM_cs);
|
||||||
|
|
||||||
if ((wFlags & TIME_KILL_SYNCHRONOUS) && !TIME_hKillEvent)
|
LIST_FOR_EACH_ENTRY( lpTimer, &timer_list, WINE_TIMERENTRY, entry )
|
||||||
TIME_hKillEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
|
wNewID = max(wNewID, lpTimer->wTimerID);
|
||||||
|
|
||||||
for (lpTimer = TIME_TimersList; lpTimer != NULL; lpTimer = lpTimer->lpNext) {
|
link_timer( lpNewTimer );
|
||||||
wNewID = max(wNewID, lpTimer->wTimerID);
|
|
||||||
}
|
|
||||||
|
|
||||||
lpNewTimer->lpNext = TIME_TimersList;
|
|
||||||
TIME_TimersList = lpNewTimer;
|
|
||||||
lpNewTimer->wTimerID = wNewID + 1;
|
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 */
|
/* 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);
|
TRACE("=> %u\n", wNewID + 1);
|
||||||
|
|
||||||
return 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.@]
|
* timeKillEvent [WINMM.@]
|
||||||
*/
|
*/
|
||||||
MMRESULT WINAPI timeKillEvent(UINT wID)
|
MMRESULT WINAPI timeKillEvent(UINT wID)
|
||||||
{
|
{
|
||||||
LPWINE_TIMERENTRY lpSelf = NULL, *lpTimer;
|
WINE_TIMERENTRY *lpSelf = NULL, *lpTimer;
|
||||||
|
DWORD wFlags;
|
||||||
|
|
||||||
TRACE("(%u)\n", wID);
|
TRACE("(%u)\n", wID);
|
||||||
EnterCriticalSection(&WINMM_IData.cs);
|
EnterCriticalSection(&WINMM_cs);
|
||||||
/* remove WINE_TIMERENTRY from list */
|
/* remove WINE_TIMERENTRY from list */
|
||||||
for (lpTimer = &TIME_TimersList; *lpTimer; lpTimer = &(*lpTimer)->lpNext) {
|
LIST_FOR_EACH_ENTRY( lpTimer, &timer_list, WINE_TIMERENTRY, entry )
|
||||||
if (wID == (*lpTimer)->wTimerID) {
|
{
|
||||||
lpSelf = *lpTimer;
|
if (wID == lpTimer->wTimerID) {
|
||||||
/* unlink timer of id 'wID' */
|
lpSelf = lpTimer;
|
||||||
*lpTimer = (*lpTimer)->lpNext;
|
list_remove( &lpTimer->entry );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&WINMM_IData.cs);
|
LeaveCriticalSection(&WINMM_cs);
|
||||||
|
|
||||||
if (!lpSelf)
|
if (!lpSelf)
|
||||||
{
|
{
|
||||||
WARN("wID=%u is not a valid timer ID\n", wID);
|
WARN("wID=%u is not a valid timer ID\n", wID);
|
||||||
return MMSYSERR_INVALPARAM;
|
return MMSYSERR_INVALPARAM;
|
||||||
}
|
}
|
||||||
if (lpSelf->wFlags & TIME_KILL_SYNCHRONOUS)
|
wFlags = lpSelf->wFlags;
|
||||||
WaitForSingleObject(TIME_hKillEvent, INFINITE);
|
if (wFlags & TIME_KILL_SYNCHRONOUS)
|
||||||
|
EnterCriticalSection(&TIME_cbcrst);
|
||||||
HeapFree(GetProcessHeap(), 0, lpSelf);
|
HeapFree(GetProcessHeap(), 0, lpSelf);
|
||||||
|
if (wFlags & TIME_KILL_SYNCHRONOUS)
|
||||||
|
LeaveCriticalSection(&TIME_cbcrst);
|
||||||
return TIMERR_NOERROR;
|
return TIMERR_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +438,6 @@ MMRESULT WINAPI timeEndPeriod(UINT wPeriod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* timeGetTime [MMSYSTEM.607]
|
|
||||||
* timeGetTime [WINMM.@]
|
* timeGetTime [WINMM.@]
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI timeGetTime(void)
|
DWORD WINAPI timeGetTime(void)
|
||||||
|
@ -465,7 +446,7 @@ DWORD WINAPI timeGetTime(void)
|
||||||
DWORD count;
|
DWORD count;
|
||||||
|
|
||||||
/* FIXME: releasing the win16 lock here is a temporary hack (I hope)
|
/* 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 (pFnReleaseThunkLock) pFnReleaseThunkLock(&count);
|
||||||
if (pFnRestoreThunkLock) pFnRestoreThunkLock(count);
|
if (pFnRestoreThunkLock) pFnRestoreThunkLock(count);
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
/*
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Copyright 1998, Luiz Otavio L. Zorzella
|
* Copyright 1998, Luiz Otavio L. Zorzella
|
||||||
* 1999, Eric Pouech
|
* 1999, Eric Pouech
|
||||||
*
|
*
|
||||||
|
@ -18,8 +16,7 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* 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>
|
#include <stdarg.h>
|
||||||
|
@ -28,20 +25,10 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "mmddk.h"
|
#include "mmddk.h"
|
||||||
|
|
||||||
#define WINE_DEFAULT_WINMM_DRIVER "oss"
|
#define WINE_DEFAULT_WINMM_DRIVER "alsa,oss,coreaudio,esd"
|
||||||
#define WINE_DEFAULT_WINMM_MAPPER "msacm.drv"
|
#define WINE_DEFAULT_WINMM_MAPPER "msacm32.drv"
|
||||||
#define WINE_DEFAULT_WINMM_MIDI "midimap.dll"
|
#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 ? */
|
/* Who said goofy boy ? */
|
||||||
#define WINE_DI_MAGIC 0x900F1B01
|
#define WINE_DI_MAGIC 0x900F1B01
|
||||||
|
|
||||||
|
@ -50,22 +37,14 @@ typedef struct tagWINE_DRIVER
|
||||||
DWORD dwMagic;
|
DWORD dwMagic;
|
||||||
/* as usual LPWINE_DRIVER == hDriver32 */
|
/* as usual LPWINE_DRIVER == hDriver32 */
|
||||||
DWORD dwFlags;
|
DWORD dwFlags;
|
||||||
union {
|
HMODULE hModule;
|
||||||
struct {
|
DRIVERPROC lpDrvProc;
|
||||||
HMODULE hModule;
|
DWORD_PTR dwDriverID;
|
||||||
DRIVERPROC lpDrvProc;
|
|
||||||
DWORD dwDriverID;
|
|
||||||
} d32;
|
|
||||||
struct {
|
|
||||||
UINT16 hDriver16;
|
|
||||||
} d16;
|
|
||||||
} d;
|
|
||||||
struct tagWINE_DRIVER* lpPrevItem;
|
struct tagWINE_DRIVER* lpPrevItem;
|
||||||
struct tagWINE_DRIVER* lpNextItem;
|
struct tagWINE_DRIVER* lpNextItem;
|
||||||
} WINE_DRIVER, *LPWINE_DRIVER;
|
} WINE_DRIVER, *LPWINE_DRIVER;
|
||||||
|
|
||||||
typedef DWORD (CALLBACK *WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
|
typedef DWORD (CALLBACK *WINEMM_msgFunc32)(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR);
|
||||||
typedef DWORD (CALLBACK *WINEMM_msgFunc32)(UINT , UINT, DWORD, DWORD, DWORD);
|
|
||||||
|
|
||||||
/* for each loaded driver and each known type of driver, this structure contains
|
/* for each loaded driver and each known type of driver, this structure contains
|
||||||
* the information needed to access it
|
* 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 {
|
typedef struct tagWINE_MM_DRIVER_PART {
|
||||||
int nIDMin; /* lower bound of global indexes for this type */
|
int nIDMin; /* lower bound of global indexes for this type */
|
||||||
int nIDMax; /* hhigher 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_msgFunc32 fnMessage32; /* pointer to function */
|
|
||||||
WINEMM_msgFunc16 fnMessage16;
|
|
||||||
} u;
|
|
||||||
} WINE_MM_DRIVER_PART;
|
} WINE_MM_DRIVER_PART;
|
||||||
|
|
||||||
#define MMDRV_AUX 0
|
#define MMDRV_AUX 0
|
||||||
|
@ -91,8 +67,7 @@ typedef struct tagWINE_MM_DRIVER_PART {
|
||||||
typedef struct tagWINE_MM_DRIVER {
|
typedef struct tagWINE_MM_DRIVER {
|
||||||
HDRVR hDriver;
|
HDRVR hDriver;
|
||||||
LPSTR drvname; /* name of the driver */
|
LPSTR drvname; /* name of the driver */
|
||||||
unsigned bIs32 : 1, /* TRUE if 32 bit driver, FALSE for 16 */
|
unsigned bIsMapper : 1; /* TRUE if mapper */
|
||||||
bIsMapper : 1; /* TRUE if mapper */
|
|
||||||
WINE_MM_DRIVER_PART parts[MMDRV_MAX];/* Information for all known types */
|
WINE_MM_DRIVER_PART parts[MMDRV_MAX];/* Information for all known types */
|
||||||
} WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
|
} WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
|
||||||
|
|
||||||
|
@ -101,12 +76,11 @@ typedef struct tagWINE_MLD {
|
||||||
UINT uDeviceID;
|
UINT uDeviceID;
|
||||||
UINT type;
|
UINT type;
|
||||||
UINT mmdIndex; /* index to low-level driver in MMDrvs table */
|
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 */
|
* opendesc.dwInstance which is client (callback) related */
|
||||||
WORD bFrom32;
|
|
||||||
WORD dwFlags;
|
WORD dwFlags;
|
||||||
DWORD dwCallback;
|
DWORD_PTR dwCallback;
|
||||||
DWORD dwClientInstance;
|
DWORD_PTR dwClientInstance;
|
||||||
} WINE_MLD, *LPWINE_MLD;
|
} WINE_MLD, *LPWINE_MLD;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -122,24 +96,6 @@ typedef struct {
|
||||||
WINE_MLD mld;
|
WINE_MLD mld;
|
||||||
} WINE_MIXER, *LPWINE_MIXER;
|
} 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 {
|
typedef struct tagWINE_MCIDRIVER {
|
||||||
UINT wDeviceID;
|
UINT wDeviceID;
|
||||||
UINT wType;
|
UINT wType;
|
||||||
|
@ -147,37 +103,21 @@ typedef struct tagWINE_MCIDRIVER {
|
||||||
LPWSTR lpstrDeviceType;
|
LPWSTR lpstrDeviceType;
|
||||||
LPWSTR lpstrAlias;
|
LPWSTR lpstrAlias;
|
||||||
HDRVR hDriver;
|
HDRVR hDriver;
|
||||||
DWORD dwPrivate;
|
DWORD_PTR dwPrivate;
|
||||||
YIELDPROC lpfnYieldProc;
|
YIELDPROC lpfnYieldProc;
|
||||||
DWORD dwYieldData;
|
DWORD dwYieldData;
|
||||||
BOOL bIs32;
|
|
||||||
DWORD CreatorThread;
|
DWORD CreatorThread;
|
||||||
UINT uTypeCmdTable;
|
UINT uTypeCmdTable;
|
||||||
UINT uSpecificCmdTable;
|
UINT uSpecificCmdTable;
|
||||||
struct tagWINE_MCIDRIVER*lpNext;
|
struct tagWINE_MCIDRIVER*lpNext;
|
||||||
} WINE_MCIDRIVER, *LPWINE_MCIDRIVER;
|
} 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
|
||||||
{
|
{
|
||||||
struct IOProcList*pNext; /* Next item in linked list */
|
struct IOProcList*pNext; /* Next item in linked list */
|
||||||
FOURCC fourCC; /* four-character code identifying IOProc */
|
FOURCC fourCC; /* four-character code identifying IOProc */
|
||||||
LPMMIOPROC pIOProc; /* pointer to IProc */
|
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 */
|
int count; /* number of objects linked to it */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -187,134 +127,53 @@ typedef struct tagWINE_MMIO {
|
||||||
struct IOProcList* ioProc;
|
struct IOProcList* ioProc;
|
||||||
unsigned bTmpIOProc : 1,
|
unsigned bTmpIOProc : 1,
|
||||||
bBufferLoaded : 1;
|
bBufferLoaded : 1;
|
||||||
DWORD segBuffer16;
|
|
||||||
DWORD dwFileSize;
|
DWORD dwFileSize;
|
||||||
} WINE_MMIO, *LPWINE_MMIO;
|
} 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 */
|
/* function prototypes */
|
||||||
|
BOOL WINMM_CheckForMMSystem(void);
|
||||||
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);
|
|
||||||
LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr);
|
LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr);
|
||||||
BOOL DRIVER_GetLibName(LPCWSTR keyName, LPCWSTR sectName, LPWSTR buf, int sz);
|
BOOL DRIVER_GetLibName(LPCWSTR keyName, LPCWSTR sectName, LPWSTR buf, int sz);
|
||||||
LPWINE_DRIVER DRIVER_TryOpenDriver32(LPCWSTR fn, LPARAM lParam2);
|
LPWINE_DRIVER DRIVER_TryOpenDriver32(LPCWSTR fn, LPARAM lParam2);
|
||||||
void DRIVER_UnloadAll(void);
|
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);
|
BOOL MMDRV_Init(void);
|
||||||
void MMDRV_Exit(void);
|
void MMDRV_Exit(void);
|
||||||
UINT MMDRV_GetNum(UINT);
|
UINT MMDRV_GetNum(UINT);
|
||||||
LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
|
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);
|
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);
|
DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg);
|
||||||
LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID);
|
LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID);
|
||||||
LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType, BOOL bSrcCanBeID, UINT dstTyped);
|
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);
|
DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
|
||||||
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);
|
||||||
BOOL MMDRV_Is32(unsigned int);
|
|
||||||
void MMDRV_InstallMap(unsigned int, MMDRV_MAPFUNC, MMDRV_UNMAPFUNC,
|
|
||||||
MMDRV_MAPFUNC, MMDRV_UNMAPFUNC, LPDRVCALLBACK);
|
|
||||||
|
|
||||||
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);
|
const char* MCI_MessageToString(UINT wMsg);
|
||||||
UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data);
|
DWORD MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
|
||||||
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);
|
|
||||||
LPWSTR MCI_strdupAtoW(LPCSTR str);
|
LPWSTR MCI_strdupAtoW(LPCSTR str);
|
||||||
LPSTR MCI_strdupWtoA(LPCWSTR str);
|
LPSTR MCI_strdupWtoA(LPCWSTR str);
|
||||||
|
|
||||||
BOOL WINMM_CheckForMMSystem(void);
|
|
||||||
const char* WINMM_ErrorToString(MMRESULT error);
|
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);
|
void TIME_MMTimeStop(void);
|
||||||
|
|
||||||
/* Global variables */
|
/* 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)
|
/* GetDriverFlags() returned bits is not documented (nor the call itself)
|
||||||
* Here are Wine only definitions of the bits
|
* Here are Wine only definitions of the bits
|
||||||
*/
|
*/
|
||||||
#define WINE_GDF_EXIST 0x80000000
|
#define WINE_GDF_EXIST 0x80000000
|
||||||
#define WINE_GDF_16BIT 0x10000000
|
#define WINE_GDF_EXTERNAL_MASK 0xF0000000
|
||||||
|
#define WINE_GDF_SESSION 0x00000001
|
||||||
|
|
||||||
|
|
||||||
/* Modification to take into account Windows NT's registry format */
|
/* 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"
|
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers"
|
||||||
|
|
||||||
INT LoadRegistryMMEDrivers(char* key);
|
INT LoadRegistryMMEDrivers(char* key);
|
||||||
BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper);
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,6 +14,7 @@
|
||||||
<library>kernel32</library>
|
<library>kernel32</library>
|
||||||
<library>advapi32</library>
|
<library>advapi32</library>
|
||||||
<library>user32</library>
|
<library>user32</library>
|
||||||
|
<library>pseh</library>
|
||||||
<file>driver.c</file>
|
<file>driver.c</file>
|
||||||
<file>joystick.c</file>
|
<file>joystick.c</file>
|
||||||
<file>lolvldrv.c</file>
|
<file>lolvldrv.c</file>
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
@ stdcall auxGetVolume(long ptr)
|
@ stdcall auxGetVolume(long ptr)
|
||||||
@ stdcall auxOutMessage(long long long long)
|
@ stdcall auxOutMessage(long long long long)
|
||||||
@ stdcall auxSetVolume(long long)
|
@ stdcall auxSetVolume(long long)
|
||||||
@ stub joyConfigChanged
|
@ stdcall joyConfigChanged(long)
|
||||||
@ stdcall joyGetDevCapsA(long ptr long)
|
@ stdcall joyGetDevCapsA(long ptr long)
|
||||||
@ stdcall joyGetDevCapsW(long ptr long)
|
@ stdcall joyGetDevCapsW(long ptr long)
|
||||||
@ stdcall joyGetNumDevs()
|
@ stdcall joyGetNumDevs()
|
||||||
|
@ -56,8 +56,8 @@
|
||||||
@ stdcall mciSendStringW(wstr ptr long long)
|
@ stdcall mciSendStringW(wstr ptr long long)
|
||||||
@ stdcall mciSetDriverData(long long)
|
@ stdcall mciSetDriverData(long long)
|
||||||
@ stdcall mciSetYieldProc(long ptr long)
|
@ stdcall mciSetYieldProc(long ptr long)
|
||||||
@ stub midiConnect
|
@ stdcall midiConnect(long long ptr)
|
||||||
@ stub midiDisconnect
|
@ stdcall midiDisconnect(long long ptr)
|
||||||
@ stdcall midiInAddBuffer(long ptr long)
|
@ stdcall midiInAddBuffer(long ptr long)
|
||||||
@ stdcall midiInClose(long)
|
@ stdcall midiInClose(long)
|
||||||
@ stdcall midiInGetDevCapsA(long ptr long)
|
@ stdcall midiInGetDevCapsA(long ptr long)
|
||||||
|
|
|
@ -452,18 +452,18 @@ BOOL WINAPI mciFreeCommandResource(UINT uTable);
|
||||||
#define DCB_TYPEMASK 0x0007
|
#define DCB_TYPEMASK 0x0007
|
||||||
#define DCB_NOSWITCH 0x0008 /* don't switch stacks for callback */
|
#define DCB_NOSWITCH 0x0008 /* don't switch stacks for callback */
|
||||||
|
|
||||||
BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
|
BOOL APIENTRY DriverCallback(DWORD_PTR dwCallBack, DWORD uFlags, HDRVR hDev,
|
||||||
UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
|
DWORD wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
|
||||||
|
|
||||||
typedef void (*LPTASKCALLBACK)(DWORD dwInst);
|
typedef void (*LPTASKCALLBACK)(DWORD dwInst);
|
||||||
|
|
||||||
#define TASKERR_NOTASKSUPPORT 1
|
#define TASKERR_NOTASKSUPPORT 1
|
||||||
#define TASKERR_OUTOFMEMORY 2
|
#define TASKERR_OUTOFMEMORY 2
|
||||||
MMRESULT WINAPI mmTaskCreate(LPTASKCALLBACK, HANDLE*, DWORD);
|
MMRESULT WINAPI mmTaskCreate(LPTASKCALLBACK, HANDLE*, DWORD);
|
||||||
void WINAPI mmTaskBlock(HANDLE);
|
void WINAPI mmTaskBlock(DWORD);
|
||||||
BOOL WINAPI mmTaskSignal(HANDLE);
|
BOOL WINAPI mmTaskSignal(DWORD);
|
||||||
void WINAPI mmTaskYield(void);
|
void WINAPI mmTaskYield(void);
|
||||||
HANDLE WINAPI mmGetCurrentTask(void);
|
DWORD WINAPI mmGetCurrentTask(void);
|
||||||
|
|
||||||
|
|
||||||
#define WAVE_DIRECTSOUND 0x0080
|
#define WAVE_DIRECTSOUND 0x0080
|
||||||
|
|
|
@ -159,7 +159,7 @@ extern "C" {
|
||||||
#define SND_PURGE 0x40
|
#define SND_PURGE 0x40
|
||||||
#define SND_APPLICATION 0x80
|
#define SND_APPLICATION 0x80
|
||||||
#define SND_ALIAS_START 0
|
#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_SYSTEMASTERISK sndAlias('S','*')
|
||||||
#define SND_ALIAS_SYSTEMQUESTION sndAlias('S','?')
|
#define SND_ALIAS_SYSTEMQUESTION sndAlias('S','?')
|
||||||
#define SND_ALIAS_SYSTEMHAND sndAlias('S','H')
|
#define SND_ALIAS_SYSTEMHAND sndAlias('S','H')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue