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?…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/w…
==============================================================================
--- 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/w…
==============================================================================
--- 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/w…
==============================================================================
--- 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/w…
==============================================================================
--- 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/w…
==============================================================================
--- 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>