From 03a1e1b19149daaad5ffd74ed39b2716a835fa05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Fri, 6 May 2005 19:16:10 +0000 Subject: [PATCH] Sync to Wine-20050419: Robert Reif - Stub out DRVM_MAPPER_RECONFIGURE support. - Correctly handle where waveOutGetPosition changes timepos.wType because the requested type is not supported. - Added Jeremy White's waveOutGetPosition fix to waveInGetPosition. - Fix memory leak in error path. - Provide default implementation of waveInPrepareHeader and waveInUnprepareHeader if driver doesn't support them. Jose Manuel Ferrer Ortiz - Spanish translations updated. Peter Berg Larsen - Assorted memleak fixes. Found on Michael Stefaniuc smatch list. Jeremy White - Do not fallback to defaults if a driver, mapper, or midi is specified in the registry; consolidate MMDRV_Init() into a single function. Robert Reif - Fix memory leak when there are too many drivers. Vincent Beron - Correct and complete some api documentation. Filip Navara - Specify correct buffer size in GetPrivateProfileStringW calls. Jakob Eriksson - Get rid of HeapAlloc casts. Jason Edmeades - Avoid trap in mixerGetLineControlsA when cControls is uninitialized and MIXER_GETLINECONTROLSSF_ONEBYTYPE requested. svn path=/trunk/; revision=15056 --- reactos/lib/winmm/driver.c | 11 ++-- reactos/lib/winmm/lolvldrv.c | 91 ++++++++++++----------------- reactos/lib/winmm/mci.c | 6 +- reactos/lib/winmm/mmio.c | 7 ++- reactos/lib/winmm/mmsystem.c | 17 +++--- reactos/lib/winmm/time.c | 6 +- reactos/lib/winmm/wavemap/wavemap.c | 89 ++++++++++++++++++++++++---- reactos/lib/winmm/winemm.h | 4 ++ reactos/lib/winmm/winmm.c | 40 +++++++++++-- reactos/lib/winmm/winmm_Es.rc | 27 ++++----- 10 files changed, 195 insertions(+), 103 deletions(-) diff --git a/reactos/lib/winmm/driver.c b/reactos/lib/winmm/driver.c index 9bda8da6dbf..d13a2b967ab 100644 --- a/reactos/lib/winmm/driver.c +++ b/reactos/lib/winmm/driver.c @@ -308,13 +308,13 @@ HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lPara INT len; LPWSTR dn = NULL; LPWSTR sn = NULL; - HDRVR ret; + HDRVR ret = 0; if (lpDriverName) { len = MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, NULL, 0 ); dn = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); - if (!dn) return 0; + if (!dn) goto done; MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, dn, len ); } @@ -322,14 +322,15 @@ HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lPara { len = MultiByteToWideChar( CP_ACP, 0, lpSectionName, -1, NULL, 0 ); sn = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); - if (!sn) return 0; + if (!sn) goto done; MultiByteToWideChar( CP_ACP, 0, lpSectionName, -1, sn, len ); } ret = OpenDriver(dn, sn, lParam); - if (dn) HeapFree(GetProcessHeap(), 0, dn); - if (sn) HeapFree(GetProcessHeap(), 0, sn); +done: + HeapFree(GetProcessHeap(), 0, dn); + HeapFree(GetProcessHeap(), 0, sn); return ret; } diff --git a/reactos/lib/winmm/lolvldrv.c b/reactos/lib/winmm/lolvldrv.c index 50c029b6103..335e15d8f39 100644 --- a/reactos/lib/winmm/lolvldrv.c +++ b/reactos/lib/winmm/lolvldrv.c @@ -309,6 +309,7 @@ LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags, if (i == MAX_MM_MLDRVS) { /* the MM_MLDrvs table could be made growable in the future if needed */ ERR("Too many open drivers\n"); + HeapFree(GetProcessHeap(), 0, mld); return NULL; } MM_MLDrvs[i] = mld; @@ -714,78 +715,60 @@ static BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper) } /************************************************************************** - * MMDRV_InitFromRegistry [internal] + * MMDRV_Init */ -static BOOL MMDRV_InitFromRegistry(void) +BOOL MMDRV_Init(void) { HKEY hKey; - char buffer[256]; + char driver_buffer[256]; + char mapper_buffer[256]; + char midi_buffer[256]; char* p1; char* p2; DWORD type, size; BOOL ret = FALSE; TRACE("()\n"); - if (RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\WinMM", &hKey)) { - TRACE("Cannot open WinMM config key\n"); - return FALSE; + strcpy(driver_buffer, WINE_DEFAULT_WINMM_DRIVER); + strcpy(mapper_buffer, WINE_DEFAULT_WINMM_MAPPER); + strcpy(midi_buffer, WINE_DEFAULT_WINMM_MIDI); + + if (! RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\WinMM", &hKey)) { + size = sizeof(driver_buffer); + if (RegQueryValueExA(hKey, "Drivers", 0, &type, (LPVOID)driver_buffer, &size)) + strcpy(driver_buffer, WINE_DEFAULT_WINMM_DRIVER); + + /* finish with mappers */ + size = sizeof(mapper_buffer); + if (RegQueryValueExA(hKey, "WaveMapper", 0, &type, (LPVOID)mapper_buffer, &size)) + strcpy(mapper_buffer, WINE_DEFAULT_WINMM_MAPPER); + + size = sizeof(midi_buffer); + if (RegQueryValueExA(hKey, "MidiMapper", 0, &type, (LPVOID)midi_buffer, &size)) + strcpy(midi_buffer, WINE_DEFAULT_WINMM_MIDI); + + RegCloseKey(hKey); } - size = sizeof(buffer); - if (!RegQueryValueExA(hKey, "Drivers", 0, &type, (LPVOID)buffer, &size)) { - p1 = buffer; - while (p1) { - p2 = strchr(p1, ';'); - if (p2) *p2++ = '\0'; - ret |= MMDRV_Install(p1, p1, FALSE); - p1 = p2; - } - } - - /* finish with mappers */ - size = sizeof(buffer); - if (!RegQueryValueExA(hKey, "WaveMapper", 0, &type, (LPVOID)buffer, &size)) - ret |= MMDRV_Install("wavemapper", buffer, TRUE); - size = sizeof(buffer); - if (!RegQueryValueExA(hKey, "MidiMapper", 0, &type, (LPVOID)buffer, &size)) - ret |= MMDRV_Install("midimapper", buffer, TRUE); - - RegCloseKey(hKey); - - return ret; -} - -/************************************************************************** - * MMDRV_InitHardcoded [internal] - */ -static BOOL MMDRV_InitHardcoded(void) -{ - TRACE("()\n"); - /* first load hardware drivers */ #ifndef __REACTOS__ - MMDRV_Install("wineoss.drv", "wineoss.drv", FALSE); -#endif /* __REACTOS__ */ + p1 = driver_buffer; + while (p1) { + p2 = strchr(p1, ';'); + if (p2) *p2++ = '\0'; + ret |= MMDRV_Install(p1, p1, FALSE); + p1 = p2; + } +#endif #ifdef __REACTOS__ // AG: TESTING: - MMDRV_Install("mmdrv.dll", "mmdrv.dll", FALSE); + ret |= MMDRV_Install("mmdrv.dll", "mmdrv.dll", FALSE); #endif - /* finish with mappers */ - MMDRV_Install("wavemapper", "msacm32.dll", TRUE); - MMDRV_Install("midimapper", "midimap.dll", TRUE); + ret |= MMDRV_Install("wavemapper", mapper_buffer, TRUE); + ret |= MMDRV_Install("midimapper", midi_buffer, TRUE); + return ret; - return TRUE; -} - -/************************************************************************** - * MMDRV_Init [internal] - */ -BOOL MMDRV_Init(void) -{ - TRACE("()\n"); - /* FIXME: MMDRV_InitFromRegistry shall be MMDRV_Init in a near future */ - return MMDRV_InitFromRegistry() || MMDRV_InitHardcoded(); } /****************************************************************** diff --git a/reactos/lib/winmm/mci.c b/reactos/lib/winmm/mci.c index 6cf7a639f52..c46be056c84 100644 --- a/reactos/lib/winmm/mci.c +++ b/reactos/lib/winmm/mci.c @@ -1458,7 +1458,11 @@ DWORD WINAPI mciSendStringA(LPCSTR lpstrCommand, LPSTR lpstrRet, if (lpstrRet) { lpwstrRet = HeapAlloc(GetProcessHeap(), 0, uRetLen * sizeof(WCHAR)); - if (!lpwstrRet) return MCIERR_OUT_OF_MEMORY; + if (!lpwstrRet) { + WARN("no memory\n"); + HeapFree( GetProcessHeap(), 0, lpwstrCommand ); + return MCIERR_OUT_OF_MEMORY; + } } ret = mciSendStringW(lpwstrCommand, lpwstrRet, uRetLen, hwndCallback); if (lpwstrRet) diff --git a/reactos/lib/winmm/mmio.c b/reactos/lib/winmm/mmio.c index 9a05f1fc4cd..7cf1e11154e 100644 --- a/reactos/lib/winmm/mmio.c +++ b/reactos/lib/winmm/mmio.c @@ -1360,26 +1360,27 @@ MMRESULT WINAPI mmioRenameW(LPCWSTR szFileName, LPCWSTR szNewFileName, { LPSTR szFn = NULL; LPSTR sznFn = NULL; - UINT ret; + UINT ret = MMSYSERR_NOMEM; INT len; if (szFileName) { len = WideCharToMultiByte( CP_ACP, 0, szFileName, -1, NULL, 0, NULL, NULL ); szFn = HeapAlloc( GetProcessHeap(), 0, len ); - if (!szFn) return MMSYSERR_NOMEM; + if (!szFn) goto done; WideCharToMultiByte( CP_ACP, 0, szFileName, -1, szFn, len, NULL, NULL ); } if (szNewFileName) { len = WideCharToMultiByte( CP_ACP, 0, szNewFileName, -1, NULL, 0, NULL, NULL ); sznFn = HeapAlloc( GetProcessHeap(), 0, len ); - if (!sznFn) return MMSYSERR_NOMEM; + if (!sznFn) goto done; WideCharToMultiByte( CP_ACP, 0, szNewFileName, -1, sznFn, len, NULL, NULL ); } ret = mmioRenameA(szFn, sznFn, lpmmioinfo, dwFlags); +done: HeapFree(GetProcessHeap(),0,szFn); HeapFree(GetProcessHeap(),0,sznFn); return ret; diff --git a/reactos/lib/winmm/mmsystem.c b/reactos/lib/winmm/mmsystem.c index 1e4e41de1d8..98eb8e1a1dd 100644 --- a/reactos/lib/winmm/mmsystem.c +++ b/reactos/lib/winmm/mmsystem.c @@ -731,7 +731,7 @@ UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID, LPMIDIOUTCAPS16 lpCaps, /************************************************************************** * midiOutGetErrorText [MMSYSTEM.203] - * midiInGetErrorText [MMSYSTEM.203] + * midiInGetErrorText [MMSYSTEM.303] */ UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize) { @@ -1231,7 +1231,7 @@ UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID, /************************************************************************** * waveOutGetErrorText [MMSYSTEM.403] - * waveInGetErrorText [MMSYSTEM.403] + * waveInGetErrorText [MMSYSTEM.503] */ UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize) { @@ -2260,7 +2260,7 @@ static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lPara LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2); if (dci16) { - LPSTR str1; + LPSTR str1 = NULL,str2; INT len; dci16->dwDCISize = sizeof(DRVCONFIGINFO16); @@ -2271,6 +2271,7 @@ static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lPara WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCISectionName, -1, str1, len, NULL, NULL ); dci16->lpszDCISectionName = MapLS( str1 ); } else { + HeapFree( GetProcessHeap(), 0, dci16); return WINMM_MAP_NOMEM; } } else { @@ -2278,11 +2279,13 @@ static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lPara } if (dci32->lpszDCIAliasName) { len = WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, NULL, 0, NULL, NULL ); - str1 = HeapAlloc( GetProcessHeap(), 0, len ); - if (str1) { - WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, str1, len, NULL, NULL ); - dci16->lpszDCIAliasName = MapLS( str1 ); + str2 = HeapAlloc( GetProcessHeap(), 0, len ); + if (str2) { + WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, str2, len, NULL, NULL ); + dci16->lpszDCIAliasName = MapLS( str2 ); } else { + HeapFree( GetProcessHeap(), 0, str1); + HeapFree( GetProcessHeap(), 0, dci16); return WINMM_MAP_NOMEM; } } else { diff --git a/reactos/lib/winmm/time.c b/reactos/lib/winmm/time.c index dbd912e3904..b97fa194217 100644 --- a/reactos/lib/winmm/time.c +++ b/reactos/lib/winmm/time.c @@ -315,11 +315,11 @@ WORD TIME_SetEventInternal(UINT wDelay, UINT wResol, TRACE("(%u, %u, %p, %08lX, %04X);\n", wDelay, wResol, lpFunc, dwUser, wFlags); - lpNewTimer = (LPWINE_TIMERENTRY)HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_TIMERENTRY)); - if (lpNewTimer == NULL) + if (wDelay < MMSYSTIME_MININTERVAL || wDelay > MMSYSTIME_MAXINTERVAL) return 0; - if (wDelay < MMSYSTIME_MININTERVAL || wDelay > MMSYSTIME_MAXINTERVAL) + lpNewTimer = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_TIMERENTRY)); + if (lpNewTimer == NULL) return 0; TIME_MMTimeStart(); diff --git a/reactos/lib/winmm/wavemap/wavemap.c b/reactos/lib/winmm/wavemap/wavemap.c index 2ff43cdbe1e..5a3a72dd3f2 100644 --- a/reactos/lib/winmm/wavemap/wavemap.c +++ b/reactos/lib/winmm/wavemap/wavemap.c @@ -166,6 +166,7 @@ static DWORD wodOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags) if (dwFlags & WAVE_MAPPED) { if (lpDesc->uMappedDeviceID >= ndhi) { WARN("invalid parameter: dwFlags WAVE_MAPPED\n"); + HeapFree(GetProcessHeap(), 0, wom); return MMSYSERR_INVALPARAM; } ndlo = lpDesc->uMappedDeviceID; @@ -427,9 +428,10 @@ static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2) if (lpTime->wType == TIME_MS) timepos.wType = TIME_BYTES; + /* This can change timepos.wType if the requested type is not supported */ val = waveOutGetPosition(wom->u.out.hInnerWave, &timepos, dwParam2); - if (lpTime->wType == TIME_BYTES || lpTime->wType == TIME_MS) + if (timepos.wType == TIME_BYTES) { DWORD dwInnerSamplesPerOuter = wom->nSamplesPerSecInner / wom->nSamplesPerSecOuter; if (dwInnerSamplesPerOuter > 0) @@ -463,10 +465,12 @@ static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2) /* Once we have the TIME_BYTES right, we can easily convert to TIME_MS */ if (lpTime->wType == TIME_MS) - lpTime->u.cb = MulDiv(lpTime->u.cb, 1000, wom->avgSpeedOuter); + lpTime->u.ms = MulDiv(lpTime->u.cb, 1000, wom->avgSpeedOuter); + else + lpTime->wType = TIME_BYTES; } - else if (lpTime->wType == TIME_SAMPLES) - lpTime->u.cb = MulDiv(timepos.u.cb, wom->nSamplesPerSecOuter, wom->nSamplesPerSecInner); + else if (lpTime->wType == TIME_SAMPLES && timepos.wType == TIME_SAMPLES) + lpTime->u.sample = MulDiv(timepos.u.sample, wom->nSamplesPerSecOuter, wom->nSamplesPerSecInner); else /* other time types don't require conversion */ lpTime->u = timepos.u; @@ -586,6 +590,13 @@ static DWORD wodMapperStatus(WAVEMAPDATA* wom, DWORD flags, LPVOID ptr) return ret; } +static DWORD wodMapperReconfigure(WAVEMAPDATA* wom, DWORD dwParam1, DWORD dwParam2) +{ + FIXME("(%p %08lx %08lx) stub!\n", wom, dwParam1, dwParam2); + + return MMSYSERR_NOERROR; +} + /************************************************************************** * wodMessage (MSACM.@) */ @@ -621,6 +632,7 @@ DWORD WINAPI WAVEMAP_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser, case WODM_RESTART: return wodRestart ((WAVEMAPDATA*)dwUser); case WODM_RESET: return wodReset ((WAVEMAPDATA*)dwUser); case WODM_MAPPER_STATUS: return wodMapperStatus ((WAVEMAPDATA*)dwUser, dwParam1, (LPVOID)dwParam2); + case DRVM_MAPPER_RECONFIGURE: return wodMapperReconfigure((WAVEMAPDATA*)dwUser, dwParam1, dwParam2); /* known but not supported */ case DRV_QUERYDEVICEINTERFACESIZE: case DRV_QUERYDEVICEINTERFACE: @@ -961,15 +973,62 @@ static DWORD widUnprepare(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdrDst, DWORD dwPara static DWORD widGetPosition(WAVEMAPDATA* wim, LPMMTIME lpTime, DWORD dwParam2) { DWORD val; - + MMTIME timepos; TRACE("(%p %p %08lx)\n", wim, lpTime, dwParam2); - val = waveInGetPosition(wim->u.in.hInnerWave, lpTime, dwParam2); - if (lpTime->wType == TIME_BYTES) - lpTime->u.cb = MulDiv(lpTime->u.cb, wim->avgSpeedOuter, wim->avgSpeedInner); - if (lpTime->wType == TIME_SAMPLES) - lpTime->u.cb = MulDiv(lpTime->u.cb, wim->nSamplesPerSecOuter, wim->nSamplesPerSecInner); - /* other time types don't require conversion */ + memcpy(&timepos, lpTime, sizeof(timepos)); + + /* For TIME_MS, we're going to recalculate using TIME_BYTES */ + if (lpTime->wType == TIME_MS) + timepos.wType = TIME_BYTES; + + /* This can change timepos.wType if the requested type is not supported */ + val = waveInGetPosition(wim->u.in.hInnerWave, &timepos, dwParam2); + + if (timepos.wType == TIME_BYTES) + { + DWORD dwInnerSamplesPerOuter = wim->nSamplesPerSecInner / wim->nSamplesPerSecOuter; + if (dwInnerSamplesPerOuter > 0) + { + DWORD dwInnerBytesPerSample = wim->avgSpeedInner / wim->nSamplesPerSecInner; + DWORD dwInnerBytesPerOuterSample = dwInnerBytesPerSample * dwInnerSamplesPerOuter; + DWORD remainder = 0; + + /* If we are up sampling (going from lower sample rate to higher), + ** we need to make a special accomodation for times when we've + ** written a partial output sample. This happens frequently + ** to us because we use msacm to do our up sampling, and it + ** will up sample on an unaligned basis. + ** For example, if you convert a 2 byte wide 8,000 'outer' + ** buffer to a 2 byte wide 48,000 inner device, you would + ** expect 2 bytes of input to produce 12 bytes of output. + ** Instead, msacm will produce 8 bytes of output. + ** But reporting our position as 1 byte of output is + ** nonsensical; the output buffer position needs to be + ** aligned on outer sample size, and aggressively rounded up. + */ + remainder = timepos.u.cb % dwInnerBytesPerOuterSample; + if (remainder > 0) + { + timepos.u.cb -= remainder; + timepos.u.cb += dwInnerBytesPerOuterSample; + } + } + + lpTime->u.cb = MulDiv(timepos.u.cb, wim->avgSpeedOuter, wim->avgSpeedInner); + + /* Once we have the TIME_BYTES right, we can easily convert to TIME_MS */ + if (lpTime->wType == TIME_MS) + lpTime->u.ms = MulDiv(lpTime->u.cb, 1000, wim->avgSpeedOuter); + else + lpTime->wType = TIME_BYTES; + } + else if (lpTime->wType == TIME_SAMPLES && timepos.wType == TIME_SAMPLES) + lpTime->u.sample = MulDiv(timepos.u.sample, wim->nSamplesPerSecOuter, wim->nSamplesPerSecInner); + else + /* other time types don't require conversion */ + lpTime->u = timepos.u; + return val; } @@ -1058,6 +1117,13 @@ static DWORD widMapperStatus(WAVEMAPDATA* wim, DWORD flags, LPVOID ptr) return ret; } +static DWORD widMapperReconfigure(WAVEMAPDATA* wim, DWORD dwParam1, DWORD dwParam2) +{ + FIXME("(%p %08lx %08lx) stub!\n", wim, dwParam1, dwParam2); + + return MMSYSERR_NOERROR; +} + /************************************************************************** * widMessage (MSACM.@) */ @@ -1088,6 +1154,7 @@ DWORD WINAPI WAVEMAP_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, case WIDM_START: return widStart ((WAVEMAPDATA*)dwUser); case WIDM_STOP: return widStop ((WAVEMAPDATA*)dwUser); case WIDM_MAPPER_STATUS: return widMapperStatus ((WAVEMAPDATA*)dwUser, dwParam1, (LPVOID)dwParam2); + case DRVM_MAPPER_RECONFIGURE: return widMapperReconfigure((WAVEMAPDATA*)dwUser, dwParam1, dwParam2); /* known but not supported */ case DRV_QUERYDEVICEINTERFACESIZE: case DRV_QUERYDEVICEINTERFACE: diff --git a/reactos/lib/winmm/winemm.h b/reactos/lib/winmm/winemm.h index b26a5c1a012..4363543cfa8 100644 --- a/reactos/lib/winmm/winemm.h +++ b/reactos/lib/winmm/winemm.h @@ -28,6 +28,10 @@ #include "winbase.h" #include "mmddk.h" +#define WINE_DEFAULT_WINMM_DRIVER "wineoss.drv" +#define WINE_DEFAULT_WINMM_MAPPER "msacm.drv" +#define WINE_DEFAULT_WINMM_MIDI "midimap.drv" + 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); diff --git a/reactos/lib/winmm/winmm.c b/reactos/lib/winmm/winmm.c index 76e4ef74dc6..17f304e88d8 100644 --- a/reactos/lib/winmm/winmm.c +++ b/reactos/lib/winmm/winmm.c @@ -441,7 +441,7 @@ UINT WINAPI mixerGetControlDetailsA(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA if (lpmcdA->u.cMultipleItems != 0) { size *= lpmcdA->u.cMultipleItems; } - pDetailsW = (MIXERCONTROLDETAILS_LISTTEXTW *)HeapAlloc(GetProcessHeap(), 0, size); + pDetailsW = HeapAlloc(GetProcessHeap(), 0, size); lpmcdA->paDetails = pDetailsW; lpmcdA->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTW); /* set up lpmcd->paDetails */ @@ -492,7 +492,15 @@ UINT WINAPI mixerGetLineControlsA(HMIXEROBJ hmix, LPMIXERLINECONTROLSA lpmlcA, mlcW.dwLineID = lpmlcA->dwLineID; mlcW.u.dwControlID = lpmlcA->u.dwControlID; mlcW.u.dwControlType = lpmlcA->u.dwControlType; - mlcW.cControls = lpmlcA->cControls; + + /* Debugging on Windows shows for MIXER_GETLINECONTROLSF_ONEBYTYPE only, + the control count is assumed to be 1 - This is relied upon by a game, + "Dynomite Deluze" */ + if (MIXER_GETLINECONTROLSF_ONEBYTYPE == fdwControls) { + mlcW.cControls = 1; + } else { + mlcW.cControls = lpmlcA->cControls; + } mlcW.cbmxctrl = sizeof(MIXERCONTROLW); mlcW.pamxctrl = HeapAlloc(GetProcessHeap(), 0, mlcW.cControls * mlcW.cbmxctrl); @@ -2580,6 +2588,7 @@ UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr, UINT uSize) { LPWINE_MLD wmld; + UINT result; TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize); @@ -2589,9 +2598,18 @@ UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr, if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; + if ((result = MMDRV_Message(wmld, WIDM_PREPARE, (DWORD_PTR)lpWaveInHdr, + uSize, TRUE)) != MMSYSERR_NOTSUPPORTED) + return result; + + if (lpWaveInHdr->dwFlags & WHDR_INQUEUE) + return WAVERR_STILLPLAYING; + + lpWaveInHdr->dwFlags |= WHDR_PREPARED; + lpWaveInHdr->dwFlags &= ~WHDR_DONE; lpWaveInHdr->dwBytesRecorded = 0; - return MMDRV_Message(wmld, WIDM_PREPARE, (DWORD_PTR)lpWaveInHdr, uSize, TRUE); + return MMSYSERR_NOERROR; } /************************************************************************** @@ -2601,20 +2619,30 @@ UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr, UINT uSize) { LPWINE_MLD wmld; + UINT result; TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize); if (lpWaveInHdr == NULL || uSize < sizeof (WAVEHDR)) return MMSYSERR_INVALPARAM; - if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) { + if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) return MMSYSERR_NOERROR; - } if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD_PTR)lpWaveInHdr, uSize, TRUE); + if ((result = MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD_PTR)lpWaveInHdr, + uSize, TRUE)) != MMSYSERR_NOTSUPPORTED) + return result; + + if (lpWaveInHdr->dwFlags & WHDR_INQUEUE) + return WAVERR_STILLPLAYING; + + lpWaveInHdr->dwFlags &= ~WHDR_PREPARED; + lpWaveInHdr->dwFlags |= WHDR_DONE; + + return MMSYSERR_NOERROR; } /************************************************************************** diff --git a/reactos/lib/winmm/winmm_Es.rc b/reactos/lib/winmm/winmm_Es.rc index 7c4712cada7..934c7c924cc 100644 --- a/reactos/lib/winmm/winmm_Es.rc +++ b/reactos/lib/winmm/winmm_Es.rc @@ -1,5 +1,6 @@ /* * Copyright 1999 Julio Cesar Gazquez + * Copyright 2005 José Manuel Ferrer Ortiz * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,30 +18,30 @@ */ STRINGTABLE LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL - BEGIN +BEGIN - /* MMSYS errors */ +/* MMSYS errors */ MMSYSERR_NOERROR, "El comando especificado fue ejecutado." MMSYSERR_ERROR, "Error externo indefinido." MMSYSERR_BADDEVICEID, "Un identificador de dispositivo que ha sido usado está fuera de rango para su sistema." - MMSYSERR_NOTENABLED, "El controlador no fue activado." + MMSYSERR_NOTENABLED, "El manejador no fue activado." MMSYSERR_ALLOCATED, "El dispositivo especificado aún está en uso. Espere hasta que esté libre e intente nuevamente." MMSYSERR_INVALHANDLE, "El handle de dispositivo especificado es inválido." - MMSYSERR_NODRIVER, "No hay un controlador instalado en su sistema !\n" - MMSYSERR_NOMEM, "No hay suficiente memoria disponible para esta tarea. Cierre una o más aplicaciones para aumentar la memoria disponible e intente nuevamente." - MMSYSERR_NOTSUPPORTED, "Esta función no está soportada. Use la función Capacidades para determinar que funciones y mensajes soporta el controlador." + MMSYSERR_NODRIVER, "¡No hay un manejador instalado en su sistema!\n" + MMSYSERR_NOMEM, "No hay suficiente memoria disponible para esta tarea. Cierre una o más aplicaciones para aumentar la memoria disponible e inténtelo de nuevo." + MMSYSERR_NOTSUPPORTED, "Esta función no está soportada. Use la función Capacidades para determinar qué funciones y mensajes soporta el manejador." MMSYSERR_BADERRNUM, "Se ha especificado un número de error que no está definido en el sistema." - MMSYSERR_INVALFLAG, "Se ha pasado un flag no válido a una función del sistema." + MMSYSERR_INVALFLAG, "Se ha pasado una bandera no válida a una función del sistema." MMSYSERR_INVALPARAM, "Se ha pasado un parámetro no válido a una función del sistema." - /* WAVE errors */ +/* WAVE errors */ WAVERR_BADFORMAT, "El formato especificado no está soportado o no puede ser traducido. Use la función Capacidades para determinar los formatos soportados." WAVERR_STILLPLAYING, "Esta operación no puede ejecutarse mientras continúa la reproducción. Reinicie el dispositivo, o espere hasta que la reproducción termine." - WAVERR_UNPREPARED, "La cabecera del forma de onda no está preparada. Use la función Preparar para preparar la cabecera, e intente nuevamente." - WAVERR_SYNC, "No puede abrirse el dispositivo sin usar el flag WAVE_ALLOWSYNC. Use el flag, e intente nuevamente." + WAVERR_UNPREPARED, "La cabecera de onda no está preparada. Use la función Preparar para prepararla, e inténtelo de nuevo." + WAVERR_SYNC, "No puede abrirse el dispositivo sin usar la bandera WAVE_ALLOWSYNC. Utilícela, e inténtelo de nuevo." - /* MIDI errors */ - MIDIERR_UNPREPARED, "La cabecera MIDI no está preparada. Use la función Preparar para preparar la cabecera, e intente nuevamente." +/* MIDI errors */ + MIDIERR_UNPREPARED, "La cabecera MIDI no está preparada. Use la función Preparar para prepararla, e inténtelo de nuevo." MIDIERR_STILLPLAYING, "Esta operación no puede ejecutarse mientras se continúa tocando. Reinicie el dispositivo, o espera hasta que termine de tocar." MIDIERR_NOMAP, "No se encontró un mapa MIDI. Puede haber un problema con el controlador, el el fichero MIDIMAP.CFG puede faltar o estar corrupto." MIDIERR_NOTREADY, "El puerto está transmitiendo datos al dispositivo. Espera hasta que los datos hayan sido transmitidos, e intente nuevamente." @@ -123,4 +124,4 @@ STRINGTABLE LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL MCIERR_SEQ_PORTUNSPECIFIED, "El sistema no tiene actualmente un puerto MIDI especificado." MCIERR_SEQ_TIMER, "Todos los temporizadores de multimedia están siendo usados por otras aplicaciones. Cierre una de esas aplicaciones e intente nuevamente." - END +END