Author: janderwald Date: Sat Feb 21 23:18:44 2009 New Revision: 39702
URL: http://svn.reactos.org/svn/reactos?rev=39702&view=rev Log: - Fix a bug in KsAllocateDeviceHeader which copied the create item to the wrong offset - Set Created status to true when create function is not zero - Partly implement KsStreamIo - Implement IOCTL for opening / setting state and writing wave data - Clear KSAUDIO_DEVICE_ENTRY - Open the pin in a worker context as IoCreateFile must be called at APC_LEVEL < - Add dispatcher object to sysaudio will dispatch the device requests to the real pin - Add a test application to play a wav sound - ReactOS can now play a wave tone
Added: trunk/reactos/drivers/wdm/audio/backpln/audio_test/ (with props) trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c (with props) trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild (with props) trunk/reactos/drivers/wdm/audio/sysaudio/pin.c (with props) Modified: trunk/reactos/drivers/ksfilter/ks/irp.c trunk/reactos/drivers/wdm/audio/backpln/directory.rbuild trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild trunk/reactos/drivers/wdm/audio/sysaudio/control.c trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild
Modified: trunk/reactos/drivers/ksfilter/ks/irp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?r... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -188,7 +188,11 @@ 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 @@ 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 @@
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 @@ } 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 @@
/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI KsStreamIo( IN PFILE_OBJECT FileObject, IN PKEVENT Event OPTIONAL, @@ -1065,8 +1071,52 @@ 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; }
/*
Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/ ------------------------------------------------------------------------------ --- bugtraq:logregex (added) +++ bugtraq:logregex Sat Feb 21 23:18:44 2009 @@ -1,0 +1,2 @@ +([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))? +(\d+)
Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/ ------------------------------------------------------------------------------ bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/ ------------------------------------------------------------------------------ bugtraq:url = http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/ ------------------------------------------------------------------------------ tsvn:logminsize = 10
Added: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/a... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c (added) +++ trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -1,0 +1,152 @@ +#define _UNICODE +#define UNICODE +#include <windows.h> +#include <mmsystem.h> +#include <stdio.h> +#include <math.h> + +#define _2pi 6.283185307179586476925286766559 + +#include <ks.h> +#include <ksmedia.h> +#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; +}
Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/a... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild (added) +++ trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -1,0 +1,11 @@ +<?xml version="1.0"?> +<!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd"> +<module name="audio_test" type="win32cui" installbase="system32" installname="audio_test.exe"> + <define name="PC_NO_IMPORTS" /> + <include base="ReactOS">include/reactos/libs/sound</include> + <include base="wdmaud_kernel">.</include> + <library>kernel32</library> + + <file>audio_test.c</file> + +</module>
Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/drivers/wdm/audio/backpln/directory.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/d... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/directory.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/directory.rbuild [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -1,6 +1,9 @@ <?xml version="1.0"?> <!DOCTYPE group SYSTEM "../../../../tools/rbuild/project.dtd"> <group xmlns:xi="http://www.w3.org/2001/XInclude"> + <directory name="audio_test"> + <xi:include href="audio_test/audio_test.rbuild" /> + </directory> <directory name="portcls"> <xi:include href="portcls/portcls.rbuild" /> </directory>
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -350,7 +350,7 @@ { PKSPROPERTY Property; NTSTATUS Status; - UNICODE_STRING GuidString, GuidString2; + UNICODE_STRING GuidString; PIO_STACK_LOCATION IoStack; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
@@ -413,6 +413,7 @@ 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 @@
} 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;
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -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 @@ 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); + 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_GETNUMDEVS_TYPE: - case IOCTL_SETDEVICE_STATE: 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); +}
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -120,7 +120,7 @@ NTSTATUS Status;
PIO_STACK_LOCATION IoStack; - WDMAUD_CLIENT *pClient; + PWDMAUD_CLIENT pClient;
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
@@ -189,11 +189,11 @@ 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;
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -44,7 +44,7 @@ WAVEINCAPS WaveInCaps; }u;
-}WDMAUD_DEVICE_INFO; +}WDMAUD_DEVICE_INFO, *PWDMAUD_DEVICE_INFO;
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -1,6 +1,7 @@ #ifndef WDMAUD_H__ #define WDMAUD_H__
+#include <pseh/pseh2.h> #include <ntddk.h> #include <portcls.h> #include <ks.h> @@ -86,6 +87,14 @@
}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,
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -6,6 +6,7 @@ <include base="ReactOS">include/reactos/libs/sound</include> <library>ntoskrnl</library> <library>ks</library> + <library>pseh</library> <file>control.c</file> <file>deviface.c</file> <file>entry.c</file>
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/control.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -29,6 +29,7 @@ { Irp->IoStatus.Information = Length; Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status;
} @@ -242,7 +243,7 @@ } 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));
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -52,6 +52,8 @@ 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);
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -175,6 +175,61 @@ 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 @@ 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 @@ /* 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 @@ if (!CreateItem) return STATUS_INSUFFICIENT_RESOURCES;
- - /* initialize create item struct */ RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM)); CreateItem->Create = DispatchCreateSysAudio; @@ -238,7 +364,6 @@ Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader, 1, CreateItem); - return Status; }
Added: trunk/reactos/drivers/wdm/audio/sysaudio/pin.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/pin.c (added) +++ trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -1,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 <ntifs.h> +#include <ntddk.h> +#include <portcls.h> +#include <ks.h> +#include <ksmedia.h> +#include <math.h> +#define YDEBUG +#include <debug.h> +#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; +}
Propchange: trunk/reactos/drivers/wdm/audio/sysaudio/pin.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -15,16 +15,19 @@ HANDLE Handle; PFILE_OBJECT FileObject; UNICODE_STRING DeviceName; + ULONG NumberOfClients;
- 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; @@ -32,6 +35,20 @@ PVOID EchoCancelNotificationEntry; 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( @@ -51,4 +68,15 @@ 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
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild [iso-8859-1] Sat Feb 21 23:18:44 2009 @@ -4,11 +4,13 @@ <include base="sysaudio">.</include> <library>ntoskrnl</library> <library>ks</library> + <library>hal</library> <library>libcntpr</library> <define name="_COMDDK_" /> <file>control.c</file> <file>deviface.c</file> <file>dispatcher.c</file> <file>main.c</file> + <file>pin.c</file> <file>sysaudio.rc</file> </module>