Sync to Wine-20050419: Robert Reif reif@earthlink.net - 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 jmfo1982@yahoo.es - Spanish translations updated. Peter Berg Larsen pebl@math.ku.dk - Assorted memleak fixes. Found on Michael Stefaniuc smatch list. Jeremy White jwhite@codeweavers.com - 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 reif@earthlink.net - Fix memory leak when there are too many drivers. Vincent Beron vberon@mecano.gme.usherb.ca - Correct and complete some api documentation. Filip Navara xnavara@volny.cz - Specify correct buffer size in GetPrivateProfileStringW calls. Jakob Eriksson jakov@vmlinux.org - Get rid of HeapAlloc casts. Jason Edmeades us@the-edmeades.demon.co.uk - Avoid trap in mixerGetLineControlsA when cControls is uninitialized and MIXER_GETLINECONTROLSSF_ONEBYTYPE requested. Modified: trunk/reactos/lib/winmm/driver.c Modified: trunk/reactos/lib/winmm/lolvldrv.c Modified: trunk/reactos/lib/winmm/mci.c Modified: trunk/reactos/lib/winmm/mmio.c Modified: trunk/reactos/lib/winmm/mmsystem.c Modified: trunk/reactos/lib/winmm/time.c Modified: trunk/reactos/lib/winmm/wavemap/wavemap.c Modified: trunk/reactos/lib/winmm/winemm.h Modified: trunk/reactos/lib/winmm/winmm.c Modified: trunk/reactos/lib/winmm/winmm_Es.rc _____
Modified: trunk/reactos/lib/winmm/driver.c --- trunk/reactos/lib/winmm/driver.c 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/driver.c 2005-05-06 19:16:10 UTC (rev 15056) @@ -308,13 +308,13 @@
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 @@ { 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; }
_____
Modified: trunk/reactos/lib/winmm/lolvldrv.c --- trunk/reactos/lib/winmm/lolvldrv.c 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/lolvldrv.c 2005-05-06 19:16:10 UTC (rev 15056) @@ -309,6 +309,7 @@
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,80 +715,62 @@ }
/*********************************************************************** *** - * 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);
- 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; - } - } + 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(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); + /* finish with mappers */ + size = sizeof(mapper_buffer); + if (RegQueryValueExA(hKey, "WaveMapper", 0, &type, (LPVOID)mapper_buffer, &size)) + strcpy(mapper_buffer, WINE_DEFAULT_WINMM_MAPPER);
- RegCloseKey(hKey); + size = sizeof(midi_buffer); + if (RegQueryValueExA(hKey, "MidiMapper", 0, &type, (LPVOID)midi_buffer, &size)) + strcpy(midi_buffer, WINE_DEFAULT_WINMM_MIDI);
- return ret; -} + RegCloseKey(hKey); + }
-/********************************************************************** **** - * 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(); -} - /****************************************************************** * ExitPerType * _____
Modified: trunk/reactos/lib/winmm/mci.c --- trunk/reactos/lib/winmm/mci.c 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/mci.c 2005-05-06 19:16:10 UTC (rev 15056) @@ -1458,7 +1458,11 @@
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) _____
Modified: trunk/reactos/lib/winmm/mmio.c --- trunk/reactos/lib/winmm/mmio.c 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/mmio.c 2005-05-06 19:16:10 UTC (rev 15056) @@ -1360,26 +1360,27 @@
{ 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; _____
Modified: trunk/reactos/lib/winmm/mmsystem.c --- trunk/reactos/lib/winmm/mmsystem.c 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/mmsystem.c 2005-05-06 19:16:10 UTC (rev 15056) @@ -731,7 +731,7 @@
/*********************************************************************** *** * midiOutGetErrorText [MMSYSTEM.203] - * midiInGetErrorText [MMSYSTEM.203] + * midiInGetErrorText [MMSYSTEM.303] */ UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize) { @@ -1231,7 +1231,7 @@
/*********************************************************************** *** * waveOutGetErrorText [MMSYSTEM.403] - * waveInGetErrorText [MMSYSTEM.403] + * waveInGetErrorText [MMSYSTEM.503] */ UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize) { @@ -2260,7 +2260,7 @@ LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2);
if (dci16) { - LPSTR str1; + LPSTR str1 = NULL,str2; INT len; dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
@@ -2271,6 +2271,7 @@ 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 @@ } 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 { _____
Modified: trunk/reactos/lib/winmm/time.c --- trunk/reactos/lib/winmm/time.c 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/time.c 2005-05-06 19:16:10 UTC (rev 15056) @@ -315,11 +315,11 @@
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(); _____
Modified: trunk/reactos/lib/winmm/wavemap/wavemap.c --- trunk/reactos/lib/winmm/wavemap/wavemap.c 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/wavemap/wavemap.c 2005-05-06 19:16:10 UTC (rev 15056) @@ -166,6 +166,7 @@
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 @@ 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 @@
/* 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 @@ 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 @@ 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 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 @@ 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 @@ 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: _____
Modified: trunk/reactos/lib/winmm/winemm.h --- trunk/reactos/lib/winmm/winemm.h 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/winemm.h 2005-05-06 19:16:10 UTC (rev 15056) @@ -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);
_____
Modified: trunk/reactos/lib/winmm/winmm.c --- trunk/reactos/lib/winmm/winmm.c 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/winmm.c 2005-05-06 19:16:10 UTC (rev 15056) @@ -441,7 +441,7 @@
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 @@ 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 uSize) { LPWINE_MLD wmld; + UINT result;
TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
@@ -2589,9 +2598,18 @@ 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 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; }
/*********************************************************************** *** _____
Modified: trunk/reactos/lib/winmm/winmm_Es.rc --- trunk/reactos/lib/winmm/winmm_Es.rc 2005-05-06 19:11:20 UTC (rev 15055) +++ trunk/reactos/lib/winmm/winmm_Es.rc 2005-05-06 19:16:10 UTC (rev 15056) @@ -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 @@ 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