diff --git a/reactos/drivers/ksfilter/ks/irp.c b/reactos/drivers/ksfilter/ks/irp.c index 05c1093c08e..f46bbb130da 100644 --- a/reactos/drivers/ksfilter/ks/irp.c +++ b/reactos/drivers/ksfilter/ks/irp.c @@ -188,7 +188,11 @@ KsAllocateDeviceHeader( for(Index = 0; Index < ItemsCount; Index++) { /* copy provided create items */ - RtlMoveMemory(&Header->ItemList[Index], &ItemsList[Index], sizeof(KSOBJECT_CREATE_ITEM)); + RtlMoveMemory(&Header->ItemList[Index].CreateItem, &ItemsList[Index], sizeof(KSOBJECT_CREATE_ITEM)); + if (ItemsList[Index].Create!= NULL) + { + Header->ItemList[Index].bCreated = TRUE; + } } Header->MaxItems = ItemsCount; } @@ -716,7 +720,7 @@ KsCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - PIO_STACK_LOCATION IoStack; + //PIO_STACK_LOCATION IoStack; PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; ULONG Index; @@ -725,7 +729,7 @@ KsCreate( DPRINT1("KS / CREATE\n"); /* get current stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); + //IoStack = IoGetCurrentIrpStackLocation(Irp); /* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; /* get device header */ @@ -856,7 +860,7 @@ KsWrite( } else { - DPRINT1("Expected Object Header\n"); + DPRINT1("Expected Object Header %p\n", IoStack->FileObject); KeBugCheckEx(0, 0, 0, 0, 0); return STATUS_SUCCESS; } @@ -1049,9 +1053,11 @@ KsDispatchIrp( /* - @unimplemented + @implemented */ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsStreamIo( IN PFILE_OBJECT FileObject, IN PKEVENT Event OPTIONAL, @@ -1065,8 +1071,52 @@ KsStreamIo( IN ULONG Flags, IN KPROCESSOR_MODE RequestorMode) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + PIRP Irp; + PIO_STACK_LOCATION IoStack; + PDEVICE_OBJECT DeviceObject; + ULONG Code; + NTSTATUS Status; + LARGE_INTEGER Offset; + + if (Flags == KSSTREAM_READ) + Code = IRP_MJ_READ; + else if (Flags == KSSTREAM_WRITE) + Code = IRP_MJ_WRITE; + else + return STATUS_INVALID_PARAMETER; + + DeviceObject = IoGetRelatedDeviceObject(FileObject); + if (!DeviceObject) + return STATUS_INVALID_PARAMETER; + + if (Event) + { + KeResetEvent(Event); + } + + Offset.QuadPart = 0LL; + Irp = IoBuildSynchronousFsdRequest(Code, DeviceObject, (PVOID)StreamHeaders, Length, &Offset, Event, IoStatusBlock); + if (!Irp) + { + return STATUS_UNSUCCESSFUL; + } + + + if (CompletionRoutine) + { + IoSetCompletionRoutine(Irp, + CompletionRoutine, + CompletionContext, + (CompletionInvocationFlags & KsInvokeOnSuccess), + (CompletionInvocationFlags & KsInvokeOnError), + (CompletionInvocationFlags & KsInvokeOnCancel)); + } + + IoStack = IoGetNextIrpStackLocation(Irp); + IoStack->FileObject = FileObject; + + Status = IoCallDriver(DeviceObject, Irp); + return Status; } /* diff --git a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c new file mode 100644 index 00000000000..c88ff1c9a60 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c @@ -0,0 +1,152 @@ +#define _UNICODE +#define UNICODE +#include +#include +#include +#include + +#define _2pi 6.283185307179586476925286766559 + +#include +#include +#include "interface.h" + +int +__cdecl +main(int argc, char* argv[]) +{ + ULONG Length; + PSHORT SoundBuffer; + ULONG i = 0; + BOOL Status; + OVERLAPPED Overlapped; + DWORD BytesReturned; + HANDLE hWdmAud; + WDMAUD_DEVICE_INFO DeviceInfo; + + + hWdmAud = CreateFileW(L"\\\\.\\wdmaud", + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + if (!hWdmAud) + { + printf("Failed to open wdmaud with %lx\n", GetLastError()); + return -1; + } + + printf("WDMAUD: opened\n"); + /* clear device info */ + RtlZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); + + ZeroMemory(&Overlapped, sizeof(OVERLAPPED)); + Overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + + DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; + + Status = DeviceIoControl(hWdmAud, IOCTL_GETNUMDEVS_TYPE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); + + if (!Status) + { + if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0) + { + printf("Failed to get num of wave out devices with %lx\n", GetLastError()); + CloseHandle(hWdmAud); + return -1; + } + } + + printf("WDMAUD: Num Devices %lu\n", DeviceInfo.DeviceCount); + if (!DeviceInfo.DeviceCount) + { + CloseHandle(hWdmAud); + return 0; + } + + DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); + DeviceInfo.u.WaveFormatEx.wFormatTag = 0x1; //WAVE_FORMAT_PCM; + DeviceInfo.u.WaveFormatEx.nChannels = 2; + DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 48000; + DeviceInfo.u.WaveFormatEx.nBlockAlign = 4; + DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4; + DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16; + + + + Status = DeviceIoControl(hWdmAud, IOCTL_OPEN_WDMAUD, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); + if (!Status) + { + if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0) + { + printf("Failed to open device with %lx\n", GetLastError()); + CloseHandle(hWdmAud); + return -1; + } + } + + // + // Allocate a buffer for 1 second + // + Length = 48000 * 4; + SoundBuffer = (PSHORT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length); + + // + // Fill the buffer with a 500 Hz sine tone + // + while (i < Length / 2) + { + // + // Generate the wave for each channel: + // Amplitude * sin( Sample * Frequency * 2PI / SamplesPerSecond ) + // + SoundBuffer[i] = 0x7FFF * sin(0.5 * (i - 1) * 500 * _2pi / 48000); + i++; + SoundBuffer[i] = 0x7FFF * sin((0.5 * i - 2) * 500 * _2pi / 48000); + i++; + } + + DeviceInfo.State = KSSTATE_RUN; + Status = DeviceIoControl(hWdmAud, IOCTL_SETDEVICE_STATE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); + if (!Status) + { + if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0) + { + printf("Failed to set device into run state %lx\n", GetLastError()); + CloseHandle(hWdmAud); + return -1; + } + } + + // + // Play our 1-second buffer + // + DeviceInfo.Buffer = (PUCHAR)SoundBuffer; + DeviceInfo.BufferSize = Length; + Status = DeviceIoControl(hWdmAud, IOCTL_WRITEDATA, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); + if (!Status) + { + if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0) + { + printf("Failed to play buffer %lx\n", GetLastError()); + CloseHandle(hWdmAud); + return -1; + } + } + + DeviceInfo.State = KSSTATE_STOP; + Status = DeviceIoControl(hWdmAud, IOCTL_SETDEVICE_STATE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); + if (!Status) + { + if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0) + { + printf("Failed to set device into stop state %lx\n", GetLastError()); + CloseHandle(hWdmAud); + return -1; + } + } + CloseHandle(hWdmAud); + return 0; +} diff --git a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild new file mode 100644 index 00000000000..7c88d3fdba5 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild @@ -0,0 +1,11 @@ + + + + + include/reactos/libs/sound + . + kernel32 + + audio_test.c + + diff --git a/reactos/drivers/wdm/audio/backpln/directory.rbuild b/reactos/drivers/wdm/audio/backpln/directory.rbuild index 5e6e3a1ec36..9a5c9c39157 100644 --- a/reactos/drivers/wdm/audio/backpln/directory.rbuild +++ b/reactos/drivers/wdm/audio/backpln/directory.rbuild @@ -1,6 +1,9 @@ + + + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c index 30bc29400ad..b219e761513 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c @@ -350,7 +350,7 @@ IPortPinWaveCyclic_HandleKsProperty( { PKSPROPERTY Property; NTSTATUS Status; - UNICODE_STRING GuidString, GuidString2; + UNICODE_STRING GuidString; PIO_STACK_LOCATION IoStack; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; @@ -413,6 +413,7 @@ IPortPinWaveCyclic_HandleKsProperty( This->State = *State; Irp->IoStatus.Information = sizeof(KSSTATE); Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } Irp->IoStatus.Status = Status; @@ -484,11 +485,9 @@ IPortPinWaveCyclic_HandleKsProperty( } RtlStringFromGUID(&Property->Set, &GuidString); - RtlStringFromGUID(&KSPROPSETID_Connection, &GuidString2); - DPRINT1("Unhandeled property Set |%S| |%S|Id %u Flags %x\n", GuidString.Buffer, GuidString2.Buffer, Property->Id, Property->Flags); + DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); DbgBreakPoint(); RtlFreeUnicodeString(&GuidString); - RtlFreeUnicodeString(&GuidString2); Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Information = 0; diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index f6dcfd39c6e..b16cd8ef653 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -8,6 +8,322 @@ */ #include "wdmaud.h" +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 KSINTERFACESETID_Standard = {0x1A8766A0L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +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}}; + + +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 PIRP Irp, + 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) + { + DPRINT1("FIXME: only waveout devices are supported\n"); + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } + + InstanceInfo = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT)); + if (!InstanceInfo) + { + /* no memory */ + return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + } + + 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)); +} + +NTSTATUS +WdmAudControlDeviceType( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + KSPROPERTY Property; + ULONG Result, BytesReturned; + NTSTATUS Status; + + if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE) + { + DPRINT1("FIXME: only waveout devices are supported\n"); + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } + + 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; + + DPRINT1("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount); + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); +} + +NTSTATUS +WdmAudControlDeviceState( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + KSPROPERTY Property; + KSSTATE State; + NTSTATUS Status; + 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); + } + + 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); + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } + + Property.Set = KSPROPSETID_Connection; + Property.Id = KSPROPERTY_CONNECTION_STATE; + Property.Flags = KSPROPERTY_TYPE_SET; + + State = DeviceInfo->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); + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); +} + +NTSTATUS +NTAPI +WdmAudWriteCompleted( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Ctx) +{ + PWRITE_CONTEXT Context = (PWRITE_CONTEXT)Ctx; + + Context->Irp->IoStatus.Information = Context->Length; + Context->Irp->IoStatus.Status = Irp->IoStatus.Status; + IoCompleteRequest(Context->Irp, IO_SOUND_INCREMENT); + + ExFreePool(Context); + return STATUS_SUCCESS; +} + +NTSTATUS +WdmAudControlWriteData( + 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; + ULONG BytesReturned; + PUCHAR Buffer; + + Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Invalid buffer handle %x\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); + } + + _SEH2_TRY + { + ProbeForRead(DeviceInfo->Buffer, DeviceInfo->BufferSize, TYPE_ALIGNMENT(char)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Exception, get the error code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Invalid buffer supplied\n"); + return SetIrpIoStatus(Irp, Status, 0); + } + + Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->BufferSize); + if (!Buffer) + { + /* no memory */ + return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + } + + RtlMoveMemory(Buffer, DeviceInfo->Buffer, DeviceInfo->BufferSize); + + + Context = ExAllocatePool(NonPagedPool, sizeof(WRITE_CONTEXT)); + if (!Context) + { + /* no memory */ + return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + } + + /* setup completion context */ + Context->Irp = Irp; + Context->Length = DeviceInfo->BufferSize; + + /* 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); + + + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, (PVOID)Packet, sizeof(KSSTREAM_HEADER), NULL, 0, &BytesReturned); + + DPRINT1("KsSynchronousIoControlDevice result %x\n", Status); + + IoMarkIrpPending(Irp); + Irp->IoStatus.Information = DeviceInfo->BufferSize; + Irp->IoStatus.Status = Status; + + ExFreePool(Buffer); + + return Status; +} + + NTSTATUS NTAPI @@ -16,42 +332,59 @@ WdmAudDeviceControl( IN PIRP Irp) { PIO_STACK_LOCATION IoStack; + PWDMAUD_DEVICE_INFO DeviceInfo; + PWDMAUD_CLIENT ClientInfo; IoStack = IoGetCurrentIrpStackLocation(Irp); + DPRINT1("WdmAudDeviceControl entered\n"); + DbgBreakPoint(); + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO)) { - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INVALID_PARAMETER; + /* invalid parameter */ + DPRINT1("Input buffer too small size %u expected %u\n", IoStack->Parameters.DeviceIoControl.InputBufferLength, sizeof(WDMAUD_DEVICE_INFO)); + return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); } + DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer; + + if (DeviceInfo->DeviceType < MIN_SOUND_DEVICE_TYPE || DeviceInfo->DeviceType > MAX_SOUND_DEVICE_TYPE) + { + /* invalid parameter */ + DPRINT1("Error: device type not set\n"); + return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); + } + + if (!IoStack->FileObject) + { + /* file object parameter */ + DPRINT1("Error: file object is not attached\n"); + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } + ClientInfo = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext; + DPRINT1("WdmAudDeviceControl entered\n"); switch(IoStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_OPEN_WDMAUD: - //return WdmAudDeviceControlOpen(DeviceObject, Irp); - case IOCTL_CLOSE_WDMAUD: + return WdmAudControlOpen(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_GETNUMDEVS_TYPE: + 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_CLOSE_WDMAUD: case IOCTL_GETDEVID: case IOCTL_GETVOLUME: case IOCTL_SETVOLUME: case IOCTL_GETCAPABILITIES: - case IOCTL_WRITEDATA: + DPRINT1("Unhandeled %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); break; } - - - - UNIMPLEMENTED - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; + return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0); } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c index dbb432ef590..7a5dc0915ca 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c @@ -120,7 +120,7 @@ WdmAudCreate( NTSTATUS Status; PIO_STACK_LOCATION IoStack; - WDMAUD_CLIENT *pClient; + PWDMAUD_CLIENT pClient; PWDMAUD_DEVICE_EXTENSION DeviceExtension; @@ -189,12 +189,12 @@ WdmAudClose( pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext; if (pClient) { + ObDereferenceObject(pClient->FileObject); ZwClose(pClient->hSysAudio); ExFreePool(pClient); IoStack->FileObject->FsContext = NULL; } - Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h index cad2eca3031..c547c5b2156 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h @@ -44,7 +44,7 @@ typedef struct WAVEINCAPS WaveInCaps; }u; -}WDMAUD_DEVICE_INFO; +}WDMAUD_DEVICE_INFO, *PWDMAUD_DEVICE_INFO; diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 7fc6ba6bf9f..9f23545d3e3 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -1,6 +1,7 @@ #ifndef WDMAUD_H__ #define WDMAUD_H__ +#include #include #include #include @@ -86,6 +87,14 @@ typedef struct }WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION; +typedef struct +{ + PIRP Irp; + IO_STATUS_BLOCK StatusBlock; + ULONG Length; +}WRITE_CONTEXT, *PWRITE_CONTEXT; + + NTSTATUS WdmAudRegisterDeviceInterface( IN PDEVICE_OBJECT PhysicalDeviceObject, diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild index 16568851e25..f912d02033b 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild @@ -6,6 +6,7 @@ include/reactos/libs/sound ntoskrnl ks + pseh control.c deviface.c entry.c diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index d885cb2ba9b..eaa3dd2bd67 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -29,6 +29,7 @@ SetIrpIoStatus( { Irp->IoStatus.Information = Length; Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } @@ -242,7 +243,7 @@ SysAudioHandleProperty( } else if (Property->Id == KSPROPERTY_SYSAUDIO_INSTANCE_INFO) { - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SYSAUDIO_INSTANCE_INFO)) + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SYSAUDIO_INSTANCE_INFO)) { /* too small buffer */ return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(SYSAUDIO_INSTANCE_INFO)); diff --git a/reactos/drivers/wdm/audio/sysaudio/deviface.c b/reactos/drivers/wdm/audio/sysaudio/deviface.c index 32d71c49c7f..c533453f4a6 100644 --- a/reactos/drivers/wdm/audio/sysaudio/deviface.c +++ b/reactos/drivers/wdm/audio/sysaudio/deviface.c @@ -52,6 +52,8 @@ DeviceInterfaceChangeCallback( DPRINT1("No Mem\n"); return STATUS_INSUFFICIENT_RESOURCES; } + + RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY)); DeviceEntry->DeviceName.Length = 0; DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 5 * sizeof(WCHAR); DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength); diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index 0def7c95477..969cb10f710 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -175,6 +175,61 @@ static KSDISPATCH_TABLE DispatchTable = Dispatch_fnFastWrite, }; +VOID +NTAPI +CreatePinWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + NTSTATUS Status; + HANDLE PinHandle; + HANDLE * Handels; + PFILE_OBJECT FileObject; + PIRP Irp; + PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context; + + Handels = ExAllocatePool(NonPagedPool, (WorkerContext->Entry->NumberOfPins + 1) * sizeof(HANDLE)); + if (!Handels) + { + DPRINT1("No Memory \n"); + WorkerContext->Irp->IoStatus.Status = STATUS_NO_MEMORY; + WorkerContext->Irp->IoStatus.Information = 0; + IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT); + return; + } + + + Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle); + DPRINT1("KsCreatePin status %x\n", Status); + + if (NT_SUCCESS(Status)) + { + Status = ObReferenceObjectByHandle(PinHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (NT_SUCCESS(Status)) + { + Status = CreateDispatcher(WorkerContext->Irp, PinHandle, FileObject); + DPRINT1("Pins %x\n", WorkerContext->Entry->NumberOfPins); + if (WorkerContext->Entry->NumberOfPins) + { + RtlMoveMemory(Handels, WorkerContext->Entry->Pins, WorkerContext->Entry->NumberOfPins * sizeof(HANDLE)); + ExFreePool(WorkerContext->Entry->Pins); + } + Handels[WorkerContext->Entry->NumberOfPins-1] = PinHandle; + WorkerContext->Entry->Pins = Handels; + WorkerContext->Entry->NumberOfPins++; + } + } + + DPRINT1("CreatePinWorkerRoutine completing irp\n"); + WorkerContext->Irp->IoStatus.Status = Status; + WorkerContext->Irp->IoStatus.Information = 0; + + Irp = WorkerContext->Irp; + ExFreePool(Context); + + IoCompleteRequest(Irp, IO_SOUND_INCREMENT); +} + NTSTATUS NTAPI DispatchCreateSysAudio( @@ -185,9 +240,79 @@ DispatchCreateSysAudio( KSOBJECT_HEADER ObjectHeader; PSYSAUDIO_CLIENT Client; PKSOBJECT_CREATE_ITEM CreateItem; + PIO_STACK_LOCATION IoStatus; + LPWSTR Buffer; + ULONG Length, DeviceIndex; + PSYSAUDIODEVEXT DeviceExtension; + PKSAUDIO_DEVICE_ENTRY Entry; + KSPIN_CONNECT * PinConnect; + PIO_WORKITEM WorkItem; + PPIN_WORKER_CONTEXT Context; + static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"; + + IoStatus = IoGetCurrentIrpStackLocation(Irp); + Buffer = IoStatus->FileObject->FileName.Buffer; DPRINT1("DispatchCreateSysAudio entered\n"); - DbgBreakPoint(); + + if (Buffer) + { + /* is the request for a new pin */ + if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN))) + { + Client = (PSYSAUDIO_CLIENT)Irp->Tail.Overlay.OriginalFileObject->FsContext2; + DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; + if (Client) + { + ASSERT(Client->NumDevices >= 1); + DeviceIndex = Client->Devices[Client->NumDevices-1]; + } + else + { + DPRINT1("Warning: using HACK\n"); + DeviceIndex = 0; + } + ASSERT(DeviceIndex < DeviceExtension->NumberOfKsAudioDevices); + Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceIndex); + ASSERT(Entry); + + Length = (IoStatus->FileObject->FileName.Length - ((wcslen(KS_NAME_PIN)+1) * sizeof(WCHAR))); + PinConnect = ExAllocatePool(NonPagedPool, Length); + if (!PinConnect) + { + Irp->IoStatus.Status = STATUS_NO_MEMORY; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NO_MEMORY; + } + RtlMoveMemory(PinConnect, IoStatus->FileObject->FileName.Buffer + (wcslen(KS_NAME_PIN)+1), Length); + Context = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT)); + if (!Context) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + Context->PinConnect = PinConnect; + Context->Entry = Entry; + Context->Irp = Irp; + + WorkItem = IoAllocateWorkItem(DeviceObject); + if (!WorkItem) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_PENDING; + IoMarkIrpPending(Irp); + return STATUS_PENDING; + } + } /* allocate create item */ CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); @@ -209,6 +334,9 @@ DispatchCreateSysAudio( /* store create context */ CreateItem->Context = (PVOID)Client; + /* store the object in FsContext */ + IoStatus->FileObject->FsContext2 = (PVOID)Client; + /* allocate object header */ Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable); @@ -228,8 +356,6 @@ SysAudioAllocateDeviceHeader( if (!CreateItem) return STATUS_INSUFFICIENT_RESOURCES; - - /* initialize create item struct */ RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM)); CreateItem->Create = DispatchCreateSysAudio; @@ -238,7 +364,6 @@ SysAudioAllocateDeviceHeader( Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader, 1, CreateItem); - return Status; } diff --git a/reactos/drivers/wdm/audio/sysaudio/pin.c b/reactos/drivers/wdm/audio/sysaudio/pin.c new file mode 100644 index 00000000000..2f9654c79b5 --- /dev/null +++ b/reactos/drivers/wdm/audio/sysaudio/pin.c @@ -0,0 +1,261 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/sysaudio/deviface.c + * PURPOSE: System Audio graph builder + * PROGRAMMER: Johannes Anderwald + */ + +#include +#include +#include +#include +#include +#include +#define YDEBUG +#include +#include "sysaudio.h" + +NTSTATUS +NTAPI +Pin_fnDeviceIoControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PDISPATCH_CONTEXT Context; + PKSOBJECT_CREATE_ITEM CreateItem; + NTSTATUS Status; + ULONG BytesReturned; + PIO_STACK_LOCATION IoStack; + + DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); + + /* access the create item */ + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + Context = (PDISPATCH_CONTEXT)CreateItem->Context; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode, + IoStack->Parameters.DeviceIoControl.Type3InputBuffer, + IoStack->Parameters.DeviceIoControl.InputBufferLength, + Irp->UserBuffer, + IoStack->Parameters.DeviceIoControl.OutputBufferLength, + &BytesReturned); + + DPRINT1("Status %x\n", Status); + + Irp->IoStatus.Information = BytesReturned; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +NTSTATUS +NTAPI +Pin_fnRead( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + DPRINT1("Pin_fnRead called DeviceObject %p Irp %p\n", DeviceObject); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PinWriteCompletionRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + PIRP CIrp = (PIRP)Context; + + CIrp->IoStatus.Status = STATUS_SUCCESS; + CIrp->IoStatus.Information = 0; + IoCompleteRequest(CIrp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +Pin_fnWrite( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PDISPATCH_CONTEXT Context; + PKSOBJECT_CREATE_ITEM CreateItem; + PIO_STACK_LOCATION IoStack; + ULONG BytesReturned; + NTSTATUS Status; + + DPRINT1("Pin_fnWrite called DeviceObject %p Irp %p\n", DeviceObject); + + /* access the create item */ + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + Context = (PDISPATCH_CONTEXT)CreateItem->Context; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, + IoStack->Parameters.DeviceIoControl.Type3InputBuffer, + IoStack->Parameters.DeviceIoControl.InputBufferLength, + Irp->UserBuffer, + IoStack->Parameters.DeviceIoControl.OutputBufferLength, + &BytesReturned); + + Irp->IoStatus.Information = BytesReturned; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +NTSTATUS +NTAPI +Pin_fnFlush( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + DPRINT1("Pin_fnFlush called DeviceObject %p Irp %p\n", DeviceObject); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +Pin_fnClose( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + DPRINT1("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject); + + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +Pin_fnQuerySecurity( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + DPRINT1("Pin_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject); + + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +Pin_fnSetSecurity( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + + DPRINT1("Pin_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject); + + return STATUS_SUCCESS; +} + +BOOLEAN +NTAPI +Pin_fnFastDeviceIoControl( + PFILE_OBJECT FileObject, + BOOLEAN Wait, + PVOID InputBuffer, + ULONG InputBufferLength, + PVOID OutputBuffer, + ULONG OutputBufferLength, + ULONG IoControlCode, + PIO_STATUS_BLOCK IoStatus, + PDEVICE_OBJECT DeviceObject) +{ + DPRINT1("Pin_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); + + + return FALSE; +} + + +BOOLEAN +NTAPI +Pin_fnFastRead( + PFILE_OBJECT FileObject, + PLARGE_INTEGER FileOffset, + ULONG Length, + BOOLEAN Wait, + ULONG LockKey, + PVOID Buffer, + PIO_STATUS_BLOCK IoStatus, + PDEVICE_OBJECT DeviceObject) +{ + DPRINT1("Pin_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject); + + return FALSE; + +} + +BOOLEAN +NTAPI +Pin_fnFastWrite( + PFILE_OBJECT FileObject, + PLARGE_INTEGER FileOffset, + ULONG Length, + BOOLEAN Wait, + ULONG LockKey, + PVOID Buffer, + PIO_STATUS_BLOCK IoStatus, + PDEVICE_OBJECT DeviceObject) +{ + DPRINT1("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject); + + return FALSE; +} + +static KSDISPATCH_TABLE PinTable = +{ + Pin_fnDeviceIoControl, + Pin_fnRead, + Pin_fnWrite, + Pin_fnFlush, + Pin_fnClose, + Pin_fnQuerySecurity, + Pin_fnSetSecurity, + Pin_fnFastDeviceIoControl, + Pin_fnFastRead, + Pin_fnFastWrite, +}; + +NTSTATUS +CreateDispatcher( + IN PIRP Irp, + IN HANDLE Handle, + IN PFILE_OBJECT FileObject) +{ + PKSOBJECT_CREATE_ITEM CreateItem; + NTSTATUS Status; + KSOBJECT_HEADER ObjectHeader; + PDISPATCH_CONTEXT Context; + + /* allocate create item */ + CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); + if (!CreateItem) + return STATUS_INSUFFICIENT_RESOURCES; + + Context = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT)); + if (!Context) + { + ExFreePool(CreateItem); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Context->Handle = Handle; + Context->FileObject = FileObject; + + + CreateItem->Context = (PVOID)Context; + + /* allocate object header */ + Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &PinTable); + return Status; +} diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h index a766e8e71df..3b933378330 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h @@ -15,16 +15,19 @@ typedef struct HANDLE Handle; PFILE_OBJECT FileObject; UNICODE_STRING DeviceName; - ULONG NumberOfClients; + + ULONG NumberOfPins; + HANDLE * Pins; + }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY; typedef struct { + KSDEVICE_HEADER KsDeviceHeader; PDEVICE_OBJECT PhysicalDeviceObject; PDEVICE_OBJECT NextDeviceObject; - KSDEVICE_HEADER KsDeviceHeader; ULONG NumberOfKsAudioDevices; LIST_ENTRY KsAudioDeviceList; @@ -33,6 +36,20 @@ typedef struct KMUTEX Mutex; }SYSAUDIODEVEXT, *PSYSAUDIODEVEXT; +typedef struct +{ + PIRP Irp; + PKSAUDIO_DEVICE_ENTRY Entry; + KSPIN_CONNECT * PinConnect; + +}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT; + +typedef struct +{ + HANDLE Handle; + PFILE_OBJECT FileObject; +}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT; + NTSTATUS SysAudioAllocateDeviceHeader( IN SYSAUDIODEVEXT *DeviceExtension); @@ -51,4 +68,15 @@ SysAudioHandleProperty( PDEVICE_OBJECT DeviceObject, PIRP Irp); +PKSAUDIO_DEVICE_ENTRY +GetListEntry( + IN PLIST_ENTRY Head, + IN ULONG Index); + +NTSTATUS +CreateDispatcher( + IN PIRP Irp, + IN HANDLE Handle, + IN PFILE_OBJECT FileObject); + #endif diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild b/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild index 44655a48cd8..5f69af6effa 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild @@ -4,11 +4,13 @@ . ntoskrnl ks + hal libcntpr control.c deviface.c dispatcher.c main.c + pin.c sysaudio.rc