*/
#include "wdmaud.h"
+const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
const GUID KSPROPSETID_Sysaudio = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
+const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
-NTSTATUS
-SetIrpIoStatus(
- IN PIRP Irp,
- IN NTSTATUS Status,
- IN ULONG Length)
-{
- Irp->IoStatus.Information = Length;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
-
-}
-
NTSTATUS
WdmAudControlOpen(
IN PDEVICE_OBJECT DeviceObject,
IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo)
{
- PSYSAUDIO_INSTANCE_INFO InstanceInfo;
- ULONG BytesReturned;
- NTSTATUS Status;
- ACCESS_MASK DesiredAccess = 0;
- HANDLE PinHandle;
- KSPIN_CONNECT * PinConnect;
- KSDATAFORMAT_WAVEFORMATEX * DataFormat;
-
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
+ if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
- DPRINT1("FIXME: only waveout devices are supported\n");
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ return WdmAudControlOpenMixer(DeviceObject, Irp, DeviceInfo, ClientInfo);
}
- InstanceInfo = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT));
- if (!InstanceInfo)
+ if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
{
- /* no memory */
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+ return WdmAudControlOpenWave(DeviceObject, Irp, DeviceInfo, ClientInfo);
}
- InstanceInfo->Property.Set = KSPROPSETID_Sysaudio;
- InstanceInfo->Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO;
- InstanceInfo->Property.Flags = KSPROPERTY_TYPE_SET;
- InstanceInfo->Flags = 0;
- InstanceInfo->DeviceNumber = DeviceInfo->DeviceIndex;
-
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned);
-
- if (!NT_SUCCESS(Status))
- {
- /* failed to acquire audio device */
- DPRINT1("KsSynchronousIoControlDevice failed with %x\n", Status);
- ExFreePool(InstanceInfo);
- return SetIrpIoStatus(Irp, Status, 0);
- }
-
- if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
- {
- DesiredAccess |= GENERIC_READ;
- }
-
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE ||
- DeviceInfo->DeviceType == AUX_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
- {
- DesiredAccess |= GENERIC_WRITE;
- }
-
- PinConnect = (KSPIN_CONNECT*)InstanceInfo;
-
-
- PinConnect->Interface.Set = KSINTERFACESETID_Standard;
- PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING;
- PinConnect->Interface.Flags = 0;
- PinConnect->Medium.Set = KSMEDIUMSETID_Standard;
- PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
- PinConnect->Medium.Flags = 0;
- PinConnect->PinId = 0; //FIXME
- PinConnect->PinToHandle = NULL;
- PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
- PinConnect->Priority.PrioritySubClass = 1;
-
-
- DataFormat = (KSDATAFORMAT_WAVEFORMATEX*) (PinConnect + 1);
- DataFormat->WaveFormatEx.wFormatTag = DeviceInfo->u.WaveFormatEx.wFormatTag;
- DataFormat->WaveFormatEx.nChannels = DeviceInfo->u.WaveFormatEx.nChannels;
- DataFormat->WaveFormatEx.nSamplesPerSec = DeviceInfo->u.WaveFormatEx.nSamplesPerSec;
- DataFormat->WaveFormatEx.nBlockAlign = DeviceInfo->u.WaveFormatEx.nBlockAlign;
- DataFormat->WaveFormatEx.nAvgBytesPerSec = DeviceInfo->u.WaveFormatEx.nAvgBytesPerSec;
- DataFormat->WaveFormatEx.wBitsPerSample = DeviceInfo->u.WaveFormatEx.wBitsPerSample;
- DataFormat->WaveFormatEx.cbSize = 0;
- DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
- DataFormat->DataFormat.Flags = 0;
- DataFormat->DataFormat.Reserved = 0;
- DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
-
- if (DeviceInfo->u.WaveFormatEx.wFormatTag != WAVE_FORMAT_PCM)
- DPRINT1("FIXME\n");
-
- DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
- DataFormat->DataFormat.SampleSize = 4;
-
-
- Status = KsCreatePin(ClientInfo->hSysAudio, PinConnect, DesiredAccess, &PinHandle);
- DPRINT1("KsCreatePin Status %x\n", Status);
-
-
- /* free buffer */
- ExFreePool(InstanceInfo);
-
- if (NT_SUCCESS(Status))
- {
- DeviceInfo->hDevice = PinHandle;
- }
- else
- {
- DeviceInfo->hDevice = NULL;
- }
-
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
}
NTSTATUS
IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo)
{
- KSPROPERTY Property;
- ULONG Result, BytesReturned;
- NTSTATUS Status;
+ ULONG Result = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
+ if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
- DPRINT1("FIXME: only waveout devices are supported\n");
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ Result = DeviceExtension->MixerInfoCount;
+ }
+ else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ Result = DeviceExtension->WaveOutDeviceCount;
+ }
+ else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
+ {
+ Result = DeviceExtension->WaveInDeviceCount;
}
- Property.Set = KSPROPSETID_Sysaudio;
- Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
- Property.Flags = KSPROPERTY_TYPE_GET;
-
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Result, sizeof(ULONG), &BytesReturned);
-
- if (NT_SUCCESS(Status))
- DeviceInfo->DeviceCount = Result;
- else
- DeviceInfo->DeviceCount = 0;
+ /* store result count */
+ DeviceInfo->DeviceCount = Result;
- DPRINT1("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ DPRINT("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
+ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
}
NTSTATUS
ULONG BytesReturned;
PFILE_OBJECT FileObject;
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
- {
- DPRINT1("FIXME: only waveout devices are supported\n");
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
+ DPRINT("WdmAudControlDeviceState\n");
Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Error: invalid device handle provided %p\n", DeviceInfo->hDevice);
+ DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
}
Property.Id = KSPROPERTY_CONNECTION_STATE;
Property.Flags = KSPROPERTY_TYPE_SET;
- State = DeviceInfo->State;
+ State = DeviceInfo->u.State;
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesReturned);
ObDereferenceObject(FileObject);
- DPRINT1("WdmAudControlDeviceState Status %x\n", Status);
+ DPRINT("WdmAudControlDeviceState Status %x\n", Status);
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+}
+
+NTSTATUS
+WdmAudCapabilities(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo)
+{
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+ DPRINT("WdmAudCapabilities entered\n");
+
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+ {
+ Status = WdmAudMixerCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
+ }
+ else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ Status = WdmAudWaveCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
+ }
+
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}
NTSTATUS
NTAPI
-WdmAudWriteCompleted(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Ctx)
+WdmAudIoctlClose(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo)
{
- PWRITE_CONTEXT Context = (PWRITE_CONTEXT)Ctx;
+ ULONG Index;
- Context->Irp->IoStatus.Information = Context->Length;
- Context->Irp->IoStatus.Status = Irp->IoStatus.Status;
- IoCompleteRequest(Context->Irp, IO_SOUND_INCREMENT);
+ for(Index = 0; Index < ClientInfo->NumPins; Index++)
+ {
+ if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
+ {
+ DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
+ ZwClose(DeviceInfo->hDevice);
+ ClientInfo->hPins[Index].Handle = NULL;
+ SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+ return STATUS_SUCCESS;
+ }
+ else if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE)
+ {
+ if (ClientInfo->hPins[Index].NotifyEvent)
+ {
+ ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent);
+ ClientInfo->hPins[Index].NotifyEvent = NULL;
+ }
+ }
+ }
- ExFreePool(Context);
- return STATUS_SUCCESS;
+ SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
+ return STATUS_INVALID_PARAMETER;
}
NTSTATUS
-WdmAudControlWriteData(
+NTAPI
+WdmAudFrameSize(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo)
{
- PKSSTREAM_HEADER Packet;
- NTSTATUS Status = STATUS_SUCCESS;
PFILE_OBJECT FileObject;
- PWRITE_CONTEXT Context;
+ KSPROPERTY Property;
ULONG BytesReturned;
- PUCHAR Buffer;
+ KSALLOCATOR_FRAMING Framing;
+ NTSTATUS Status;
+ /* Get sysaudio pin file object */
Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Invalid buffer handle %x\n", DeviceInfo->hDevice);
+ DPRINT1("Invalid buffer handle %p\n", DeviceInfo->hDevice);
return SetIrpIoStatus(Irp, Status, 0);
}
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
- {
- DPRINT1("FIXME: only waveout devices are supported\n");
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
+ /* Setup get framing request */
+ Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+ Property.Set = KSPROPSETID_Connection;
- _SEH2_TRY
- {
- ProbeForRead(DeviceInfo->Buffer, DeviceInfo->BufferSize, TYPE_ALIGNMENT(char));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned);
+ /* Did we succeed */
+ if (NT_SUCCESS(Status))
{
- /* Exception, get the error code */
- Status = _SEH2_GetExceptionCode();
+ /* Store framesize */
+ DeviceInfo->u.FrameSize = Framing.FrameSize;
}
- _SEH2_END;
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid buffer supplied\n");
- return SetIrpIoStatus(Irp, Status, 0);
- }
+ /* Release file object */
+ ObDereferenceObject(FileObject);
- Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->BufferSize);
- if (!Buffer)
- {
- /* no memory */
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
- }
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+
+}
+
+NTSTATUS
+NTAPI
+WdmAudGetDeviceInterface(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo)
+{
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status;
+ LPWSTR Device;
+ LPWAVE_INFO WaveInfo;
+ ULONG Size, Length;
- RtlMoveMemory(Buffer, DeviceInfo->Buffer, DeviceInfo->BufferSize);
+ /* get device extension */
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ /* get device interface string input length */
+ Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize;
- Context = ExAllocatePool(NonPagedPool, sizeof(WRITE_CONTEXT));
- if (!Context)
+ if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ /* get wave info */
+ Status = GetWaveInfoByIndexAndType(DeviceObject, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType, &WaveInfo);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* invalid device id */
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ }
+
+ Status = GetSysAudioDevicePnpName(DeviceObject, WaveInfo->FilterId, &Device);
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* invalid device id */
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ }
+
+ /* calculate length */
+ Length = (wcslen(Device)+1) * sizeof(WCHAR);
+
+ if (!Size)
+ {
+ /* store device interface size */
+ DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+ }
+ else if (Size < Length)
+ {
+ /* buffer too small */
+ DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+ return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
+ }
+ else
+ {
+ //FIXME SEH
+ RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
+ }
+
+ ExFreePool(Device);
+ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+ }
+ else if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
- /* no memory */
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+ if (DeviceInfo->DeviceIndex >= DeviceExtension->MixerInfoCount)
+ {
+ /* invalid device id */
+ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
+ }
+
+ Status = GetSysAudioDevicePnpName(DeviceObject, DeviceExtension->MixerInfo[DeviceInfo->DeviceIndex].DeviceIndex, &Device);
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* invalid device id */
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ }
+
+ /* calculate length */
+ Length = (wcslen(Device)+1) * sizeof(WCHAR);
+
+ if (!Size)
+ {
+ /* store device interface size */
+ DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+ }
+ else if (Size < Length)
+ {
+ /* buffer too small */
+ DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+ return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
+ }
+ else
+ {
+ //FIXME SEH
+ RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
+ }
+
+ ExFreePool(Device);
+ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
}
- /* setup completion context */
- Context->Irp = Irp;
- Context->Length = DeviceInfo->BufferSize;
+ return SetIrpIoStatus(Irp, STATUS_INVALID_DEVICE_REQUEST, sizeof(WDMAUD_DEVICE_INFO));
+}
- /* setup stream context */
- Packet = (PKSSTREAM_HEADER)ExAllocatePool(NonPagedPool, sizeof(KSSTREAM_HEADER));
- Packet->Data = Buffer;
- Packet->FrameExtent = DeviceInfo->BufferSize;
- Packet->DataUsed = DeviceInfo->BufferSize;
- Packet->Size = sizeof(KSSTREAM_HEADER);
- Packet->PresentationTime.Numerator = 1;
- Packet->PresentationTime.Denominator = 1;
- ASSERT(FileObject->FsContext != NULL);
+NTSTATUS
+NTAPI
+WdmAudResetStream(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo)
+{
+ KSRESET ResetStream;
+ NTSTATUS Status;
+ ULONG BytesReturned;
+ PFILE_OBJECT FileObject;
+ DPRINT("WdmAudResetStream\n");
- Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, (PVOID)Packet, sizeof(KSSTREAM_HEADER), NULL, 0, &BytesReturned);
+ Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ }
- DPRINT1("KsSynchronousIoControlDevice result %x\n", Status);
+ ResetStream = DeviceInfo->u.ResetStream;
+ ASSERT(ResetStream == KSRESET_BEGIN || ResetStream == KSRESET_END);
- IoMarkIrpPending(Irp);
- Irp->IoStatus.Information = DeviceInfo->BufferSize;
- Irp->IoStatus.Status = Status;
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_RESET_STATE, (PVOID)&ResetStream, sizeof(KSRESET), NULL, 0, &BytesReturned);
- ExFreePool(Buffer);
+ ObDereferenceObject(FileObject);
- return Status;
+ DPRINT("WdmAudResetStream Status %x\n", Status);
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}
-
-
NTSTATUS
NTAPI
WdmAudDeviceControl(
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT1("WdmAudDeviceControl entered\n");
- DbgBreakPoint();
+ DPRINT("WdmAudDeviceControl entered\n");
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO))
{
}
ClientInfo = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
- DPRINT1("WdmAudDeviceControl entered\n");
+ DPRINT("WdmAudDeviceControl entered\n");
switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
{
return WdmAudControlDeviceType(DeviceObject, Irp, DeviceInfo, ClientInfo);
case IOCTL_SETDEVICE_STATE:
return WdmAudControlDeviceState(DeviceObject, Irp, DeviceInfo, ClientInfo);
- case IOCTL_WRITEDATA:
- return WdmAudControlWriteData(DeviceObject, Irp, DeviceInfo, ClientInfo);
-
+ case IOCTL_GETCAPABILITIES:
+ return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo);
case IOCTL_CLOSE_WDMAUD:
+ return WdmAudIoctlClose(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_GETFRAMESIZE:
+ return WdmAudFrameSize(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_GETLINEINFO:
+ return WdmAudGetLineInfo(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_GETLINECONTROLS:
+ return WdmAudGetLineControls(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_SETCONTROLDETAILS:
+ return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_GETCONTROLDETAILS:
+ return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_QUERYDEVICEINTERFACESTRING:
+ return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo);
+ case IOCTL_GET_MIXER_EVENT:
+ return WdmAudGetMixerEvent(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_RESET_STREAM:
+ return WdmAudResetStream(DeviceObject, Irp, DeviceInfo);
+ case IOCTL_GETPOS:
case IOCTL_GETDEVID:
case IOCTL_GETVOLUME:
case IOCTL_SETVOLUME:
- case IOCTL_GETCAPABILITIES:
+
DPRINT1("Unhandeled %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
break;
}
return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0);
}
+
+
+NTSTATUS
+NTAPI
+WdmAudReadWrite(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ NTSTATUS Status;
+ PWDMAUD_DEVICE_INFO DeviceInfo;
+ PFILE_OBJECT FileObject;
+ PIO_STACK_LOCATION IoStack;
+ ULONG Length;
+ PMDL Mdl;
+ BOOLEAN Read = TRUE;
+
+ /* get current irp stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* store the input buffer in UserBuffer - as KsProbeStreamIrp operates on IRP_MJ_DEVICE_CONTROL */
+ Irp->UserBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
+
+ /* sanity check */
+ ASSERT(Irp->UserBuffer);
+
+ /* get the length of the request length */
+ Length = IoStack->Parameters.Write.Length;
+
+ /* store outputbuffer length */
+ IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
+
+ /* store mdl address */
+ Mdl = Irp->MdlAddress;
+
+ /* remove mdladdress as KsProbeStreamIrp will interprete it as an already probed audio buffer */
+ Irp->MdlAddress = NULL;
+
+ /* check for success */
+
+ if (IoStack->MajorFunction == IRP_MJ_WRITE)
+ {
+ /* probe the write stream irp */
+ Read = FALSE;
+ Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
+ }
+ else
+ {
+ /* probe the read stream irp */
+ Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMREAD | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
+ }
+
+ /* now free the mdl */
+ IoFreeMdl(Mdl);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("KsProbeStreamIrp failed with Status %x Cancel %u\n", Status, Irp->Cancel);
+ return SetIrpIoStatus(Irp, Status, 0);
+ }
+
+ /* get device info */
+ DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
+ ASSERT(DeviceInfo);
+
+ /* now get sysaudio file object */
+ Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Invalid pin handle %p\n", DeviceInfo->hDevice);
+ return SetIrpIoStatus(Irp, Status, 0);
+ }
+
+ /* skip current irp stack location */
+ IoSkipCurrentIrpStackLocation(Irp);
+
+ /* 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);
+ /* call the driver */
+ Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
+
+ /* dereference file object */
+ ObDereferenceObject(FileObject);
+
+ return Status;
+}