diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c
index 7050ca72463..27c38a5dac8 100644
--- a/reactos/dll/win32/wdmaud.drv/wdmaud.c
+++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c
@@ -428,16 +428,18 @@ SetWdmWaveDeviceFormat(
Instance->BufferCount = 100;
}
-
- /* Now start the stream */
- DeviceInfo.u.State = KSSTATE_RUN;
- SyncOverlappedDeviceIoControl(KernelHandle,
- IOCTL_SETDEVICE_STATE,
- (LPVOID) &DeviceInfo,
- sizeof(WDMAUD_DEVICE_INFO),
- (LPVOID) &DeviceInfo,
- sizeof(WDMAUD_DEVICE_INFO),
- NULL);
+ if (DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ /* Now start the stream */
+ DeviceInfo.u.State = KSSTATE_RUN;
+ SyncOverlappedDeviceIoControl(KernelHandle,
+ IOCTL_SETDEVICE_STATE,
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ NULL);
+ }
return MMSYSERR_NOERROR;
}
@@ -502,13 +504,56 @@ WriteFileEx_Committer2(
else if (DeviceType == WAVE_IN_DEVICE_TYPE)
{
Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
- if (Ret)
- WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
+ //if (Ret)
+ // WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
}
return MMSYSERR_NOERROR;
}
+MMRESULT
+SetWdmWaveState(
+ IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
+ IN BOOL bStart)
+{
+ MMRESULT Result;
+ PSOUND_DEVICE SoundDevice;
+ WDMAUD_DEVICE_INFO DeviceInfo;
+ MMDEVICE_TYPE DeviceType;
+ HANDLE Handle;
+
+ Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
+
+ if ( ! MMSUCCESS(Result) )
+ {
+ return TranslateInternalMmResult(Result);
+ }
+
+ Result = GetSoundDeviceType(SoundDevice, &DeviceType);
+ SND_ASSERT( Result == MMSYSERR_NOERROR );
+
+ Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
+ SND_ASSERT( Result == MMSYSERR_NOERROR );
+
+ ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+ DeviceInfo.hDevice = Handle;
+ DeviceInfo.DeviceType = DeviceType;
+
+ if (bStart)
+ DeviceInfo.u.State = KSSTATE_RUN;
+ else
+ DeviceInfo.u.State = KSSTATE_PAUSE;
+ Result = SyncOverlappedDeviceIoControl(KernelHandle,
+ IOCTL_SETDEVICE_STATE,
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ NULL);
+
+ return Result;
+}
+
MMRESULT
GetWdmPosition(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
@@ -682,6 +727,11 @@ PopulateWdmDeviceList(
FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
}
+ if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ FuncTable.SetState = SetWdmWaveState;
+ }
+
FuncTable.Open = OpenWdmSoundDevice;
FuncTable.Close = CloseWdmSoundDevice;
#ifndef USERMODE_MIXER
diff --git a/reactos/dll/win32/winmm/winmm.c b/reactos/dll/win32/winmm/winmm.c
index 07e22e61b7a..2a1c7059ffd 100644
--- a/reactos/dll/win32/winmm/winmm.c
+++ b/reactos/dll/win32/winmm/winmm.c
@@ -2150,6 +2150,12 @@ UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps,
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
+ if (uDeviceID == WAVE_MAPPER)
+ {
+ FIXME("Support WAVE_MAPPER\n");
+ uDeviceID = 0;
+ }
+
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEOUT, TRUE)) == NULL)
return MMSYSERR_BADDEVICEID;
@@ -2543,6 +2549,13 @@ UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSi
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
+ if (uDeviceID == WAVE_MAPPER)
+ {
+ FIXME("Support WAVE_MAPPER\n");
+ uDeviceID = 0;
+ }
+
+
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEIN, TRUE)) == NULL)
return MMSYSERR_BADDEVICEID;
diff --git a/reactos/dll/win32/winmm/winmm.rbuild b/reactos/dll/win32/winmm/winmm.rbuild
index 1231b37ddcc..52688daf28b 100644
--- a/reactos/dll/win32/winmm/winmm.rbuild
+++ b/reactos/dll/win32/winmm/winmm.rbuild
@@ -21,9 +21,9 @@
mci.c
mmio.c
playsound.c
+ registry.c
time.c
winmm.c
- registry.c
winmm_res.rc
diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp
index 5b4c8b16d5b..f3b1d7b0e2f 100644
--- a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp
+++ b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp
@@ -133,9 +133,11 @@ CIrpQueue::AddMapping(
// Wdmaud already probes buffers, therefore no need to probe it again
// probe the stream irp
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM)
- Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0);
- else
- Status = KsProbeStreamIrp(Irp, KSSTREAM_READ| KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0);
+ Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, 0);
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM)
+ Status = KsProbeStreamIrp(Irp, KSSTREAM_READ | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, 0);
+ else
+ PC_ASSERT(0);
// check for success
if (!NT_SUCCESS(Status))
diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
index 241b3f4848f..73b4b7056a8 100644
--- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
+++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
@@ -291,6 +291,7 @@ WdmAudReadWrite(
PIO_STACK_LOCATION IoStack;
ULONG Length;
PMDL Mdl;
+ BOOLEAN Read = TRUE;
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -318,6 +319,7 @@ WdmAudReadWrite(
if (IoStack->MajorFunction == IRP_MJ_WRITE)
{
/* probe the write stream irp */
+ Read = FALSE;
Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
}
else
@@ -353,13 +355,22 @@ WdmAudReadWrite(
/* get next stack location */
IoStack = IoGetNextIrpStackLocation(Irp);
+ if (Read)
+ {
+ IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_READ_STREAM;
+ }
+ else
+ {
+ IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM;
+ }
+
/* attach file object */
IoStack->FileObject = FileObject;
IoStack->Parameters.Write.Length = Length;
IoStack->MajorFunction = IRP_MJ_WRITE;
/* mark irp as pending */
- IoMarkIrpPending(Irp);
+// IoMarkIrpPending(Irp);
/* call the driver */
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
diff --git a/reactos/drivers/wdm/audio/sysaudio/pin.c b/reactos/drivers/wdm/audio/sysaudio/pin.c
index ef1a4df6d6e..234f43c4a39 100644
--- a/reactos/drivers/wdm/audio/sysaudio/pin.c
+++ b/reactos/drivers/wdm/audio/sysaudio/pin.c
@@ -73,13 +73,10 @@ Pin_fnWrite(
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
- ULONG Length;
/* Get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
- Length = IoStack->Parameters.Write.Length;
-
/* The dispatch context is stored in the FsContext member */
Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
@@ -113,9 +110,7 @@ Pin_fnWrite(
/* store file object of next device object */
IoStack->FileObject = FileObject;
IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
- IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM; //FIXME
- IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
- ASSERT(Irp->AssociatedIrp.SystemBuffer);
+ //ASSERT(Irp->AssociatedIrp.SystemBuffer);
/* now call the driver */
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
diff --git a/reactos/include/reactos/libs/sound/mmebuddy.h b/reactos/include/reactos/libs/sound/mmebuddy.h
index f8b2d8d57ae..b8158005abe 100644
--- a/reactos/include/reactos/libs/sound/mmebuddy.h
+++ b/reactos/include/reactos/libs/sound/mmebuddy.h
@@ -236,6 +236,12 @@ typedef MMRESULT(*MMGETPOS_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN MMTIME* Time);
+
+typedef MMRESULT(*MMSETSTATE_FUNC)(
+ IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
+ IN BOOL bStart);
+
+
typedef struct _MMFUNCTION_TABLE
{
union
@@ -258,6 +264,7 @@ typedef struct _MMFUNCTION_TABLE
WAVE_COMMIT_FUNC CommitWaveBuffer;
MMGETPOS_FUNC GetPos;
+ MMSETSTATE_FUNC SetState;
// Redundant
//MMWAVEHEADER_FUNC PrepareWaveHeader;
@@ -407,6 +414,11 @@ MmeGetPosition(
IN MMTIME* Time,
IN DWORD Size);
+MMRESULT
+MmeSetState(
+ IN DWORD PrivateHandle,
+ IN BOOL bStart);
+
#define MmePrepareWaveHeader(private_handle, header) \
PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
diff --git a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c
index 7e25ac9e678..88190cb1abb 100644
--- a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c
+++ b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c
@@ -182,6 +182,7 @@ mxdMessage(
case MXDM_INIT :
{
+ Result = MMSYSERR_NOERROR;
break;
}
diff --git a/reactos/lib/drivers/sound/mmebuddy/mmewrap.c b/reactos/lib/drivers/sound/mmebuddy/mmewrap.c
index a5a4a6d0fb6..f63e55a5ee2 100644
--- a/reactos/lib/drivers/sound/mmebuddy/mmewrap.c
+++ b/reactos/lib/drivers/sound/mmebuddy/mmewrap.c
@@ -15,6 +15,47 @@
#include
#include
+
+/*
+ Sets the device into running or stopped state
+*/
+
+MMRESULT
+MmeSetState(
+ IN DWORD PrivateHandle,
+ IN BOOL bStart)
+{
+ MMRESULT Result;
+ PMMFUNCTION_TABLE FunctionTable;
+ PSOUND_DEVICE SoundDevice;
+ PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
+
+ VALIDATE_MMSYS_PARAMETER( PrivateHandle );
+ SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
+
+ VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
+
+ Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
+ if ( ! MMSUCCESS(Result) )
+ return TranslateInternalMmResult(Result);
+
+ /* Get the function table, and validate it */
+ Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
+ if ( ! MMSUCCESS(Result) )
+ return TranslateInternalMmResult(Result);
+
+ SND_ASSERT( FunctionTable->SetState );
+ if ( FunctionTable->SetState == NULL )
+ {
+ /* FIXME */
+ return MMSYSERR_NOTSUPPORTED;
+ }
+ /* Try change state */
+ Result = FunctionTable->SetState(SoundDeviceInstance, bStart);
+
+ return Result;
+}
+
/*
Call the client application when something interesting happens (MME API
defines "interesting things" as device open, close, and buffer
diff --git a/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c b/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c
index e611a0b8d73..f910bf96c96 100644
--- a/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c
+++ b/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c
@@ -170,6 +170,7 @@ CompleteIO(
PWAVEHDR WaveHdr;
PWAVEHDR_EXTENSION HdrExtension;
MMRESULT Result;
+ DWORD Bytes;
WaveHdr = (PWAVEHDR) SoundOverlapped->Header;
SND_ASSERT( WaveHdr );
@@ -187,18 +188,48 @@ CompleteIO(
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
SND_ASSERT( MMSUCCESS(Result) );
- HdrExtension->BytesCompleted += dwNumberOfBytesTransferred;
- SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
+ do
+ {
- /* We have an available buffer now */
- -- SoundDeviceInstance->OutstandingBuffers;
+ /* We have an available buffer now */
+ -- SoundDeviceInstance->OutstandingBuffers;
- /* Did we finish a WAVEHDR and aren't looping? */
- if ( HdrExtension->BytesCompleted == WaveHdr->dwBufferLength &&
- SoundOverlapped->PerformCompletion )
- {
- CompleteWaveHeader(SoundDeviceInstance, WaveHdr);
- }
+ /* Did we finish a WAVEHDR and aren't looping? */
+ if ( HdrExtension->BytesCompleted + dwNumberOfBytesTransferred >= WaveHdr->dwBufferLength &&
+ SoundOverlapped->PerformCompletion )
+ {
+ /* Wave buffer fully completed */
+ Bytes = WaveHdr->dwBufferLength - HdrExtension->BytesCompleted;
+
+ HdrExtension->BytesCompleted += Bytes;
+ dwNumberOfBytesTransferred -= Bytes;
+
+ CompleteWaveHeader(SoundDeviceInstance, WaveHdr);
+ SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
+ }
+ else
+ {
+ SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
+ /* Partially completed */
+ HdrExtension->BytesCompleted += dwNumberOfBytesTransferred;
+ break;
+ }
+
+ /* Move to next wave header */
+ WaveHdr = WaveHdr->lpNext;
+
+ if (!WaveHdr)
+ {
+ /* No following WaveHdr */
+ SND_ASSERT(dwNumberOfBytesTransferred == 0);
+ break;
+ }
+
+ HdrExtension = (PWAVEHDR_EXTENSION) WaveHdr->reserved;
+ SND_ASSERT( HdrExtension );
+
+
+ }while(dwNumberOfBytesTransferred);
DoWaveStreaming(SoundDeviceInstance);
diff --git a/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c b/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c
index 366ab3cabe2..de9e353fadc 100644
--- a/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c
+++ b/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c
@@ -45,6 +45,18 @@ widMessage(
break;
}
+ case WIDM_START :
+ {
+ Result = MmeSetState(PrivateHandle, TRUE);
+ break;
+ }
+
+ case WIDM_STOP :
+ {
+ Result = MmeSetState(PrivateHandle, FALSE);
+ break;
+ }
+
case WIDM_GETDEVCAPS :
{