<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>
<include base="libsamplerate">.</include>
<library>setupapi</library>
<library>libsamplerate</library>
if (Gap > BufferLength)
{
// insert silence samples
- DPRINT("Inserting Silence Buffer Offset %lu GapLength %lu\n", m_CommonBufferOffset, BufferLength);
+ DPRINT1("Inserting Silence Buffer Offset %lu GapLength %lu\n", m_CommonBufferOffset, BufferLength);
m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength);
m_CommonBufferOffset += BufferLength;
if (Gap > BufferLength)
{
// insert silence samples
- DPRINT("Overlap Inserting Silence Buffer Size %lu Offset %lu Gap %lu Position %lu\n", m_CommonBufferSize, m_CommonBufferOffset, Gap, Position);
+ DPRINT1("Overlap Inserting Silence Buffer Size %lu Offset %lu Gap %lu Position %lu\n", m_CommonBufferSize, m_CommonBufferOffset, Gap, Position);
m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength);
m_CommonBufferOffset += BufferLength;
<directory name="legacy">
<xi:include href="legacy/directory.rbuild" />
</directory>
- <directory name="sysaudio">
- <xi:include href="sysaudio/sysaudio.rbuild" />
- </directory>
</group>
<?xml version="1.0"?>
<!DOCTYPE group SYSTEM "../../../../tools/rbuild/project.dtd">
<group xmlns:xi="http://www.w3.org/2001/XInclude">
- <directory name="kmixer">
- <xi:include href="kmixer/kmixer.rbuild" />
- </directory>
<!--<directory name="splitter">
<xi:include href="splitter/splitter.rbuild" />
</directory>-->
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/filters/kmixer/filter.c
- * PURPOSE: Filter File Context Header header
- * PROGRAMMER: Johannes Anderwald
- */
-
-#include "kmixer.h"
-
-NTSTATUS
-NTAPI
-Dispatch_fnDeviceIoControl(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
-
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- UNIMPLEMENTED
-
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-NTAPI
-Dispatch_fnClose(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- UNIMPLEMENTED
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-}
-
-static KSDISPATCH_TABLE DispatchTable =
-{
- Dispatch_fnDeviceIoControl,
- KsDispatchInvalidDeviceRequest,
- KsDispatchInvalidDeviceRequest,
- KsDispatchInvalidDeviceRequest,
- Dispatch_fnClose,
- KsDispatchInvalidDeviceRequest,
- KsDispatchInvalidDeviceRequest,
- KsDispatchFastIoDeviceControlFailure,
- KsDispatchFastWriteFailure,
- KsDispatchFastWriteFailure,
-};
-
-NTSTATUS
-NTAPI
-DispatchCreateKMixPin(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- NTSTATUS Status;
-
- DPRINT("DispatchCreateKMix entered\n");
-
- /* create the pin */
- Status = CreatePin(Irp);
-
- /* save result */
- Irp->IoStatus.Status = Status;
- /* complete the request */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- /* done */
- return Status;
-}
-
-NTSTATUS
-NTAPI
-DispatchCreateKMixAllocator(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- NTSTATUS Status;
-
- /* create the allocator */
- Status = KsCreateDefaultAllocator(Irp);
-
- /* save result */
- Irp->IoStatus.Status = Status;
- /* complete the request */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- /* done */
- return Status;
-}
-
-NTSTATUS
-NTAPI
-DispatchCreateKMix(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- NTSTATUS Status;
- KSOBJECT_HEADER ObjectHeader;
- PKSOBJECT_CREATE_ITEM CreateItem;
- PKMIXER_DEVICE_EXT DeviceExtension;
-
- DPRINT("DispatchCreateKMix entered\n");
-
- /* check if the request was from usermode */
- if (Irp->RequestorMode == UserMode)
- {
- /* deny access from usermode */
- Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_INVALID_DEVICE_REQUEST;
- }
-
- /* get device extension */
- DeviceExtension = (PKMIXER_DEVICE_EXT)DeviceObject->DeviceExtension;
-
-#if 0
- /* reference the software bus object */
- Status = KsReferenceSoftwareBusObject(DeviceExtension->KsDeviceHeader);
-
- if (!NT_SUCCESS(Status))
- {
- /* failed to reference bus object */
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
-#endif
-
- /* allocate create item */
- CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 2);
- if (!CreateItem)
- {
- /* not enough memory */
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* zero create struct */
- RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM) * 2);
-
- /* initialize pin create item */
- CreateItem[0].Create = DispatchCreateKMixPin;
- RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Pin);
- CreateItem[1].Create = DispatchCreateKMixAllocator;
- RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Allocator);
-
- /* allocate object header */
- Status = KsAllocateObjectHeader(&ObjectHeader, 2, CreateItem, Irp, &DispatchTable);
-
- if (!NT_SUCCESS(Status))
- {
- /* failed to allocate object header */
- ExFreePool(CreateItem);
- KsDereferenceSoftwareBusObject(DeviceExtension->KsDeviceHeader);
- }
-
- DPRINT("KsAllocateObjectHeader result %x\n", Status);
- /* complete the irp */
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
-}
-
-NTSTATUS
-NTAPI
-KMixAllocateDeviceHeader(
- IN PKMIXER_DEVICE_EXT DeviceExtension)
-{
- NTSTATUS Status;
- PKSOBJECT_CREATE_ITEM CreateItem;
-
- /* allocate create item */
- CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 2);
- if (!CreateItem)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* initialize create item struct */
- RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM) * 2);
- CreateItem[0].Create = DispatchCreateKMix;
- RtlInitUnicodeString(&CreateItem[0].ObjectClass, L"GLOBAL");
- CreateItem[1].Create = DispatchCreateKMix;
- RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Filter);
-
- Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
- 2,
- CreateItem);
- return Status;
-}
-
+++ /dev/null
-/*
- * PROJECT: ReactOS Kernel Streaming Mixer
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/wdm/audio/filters/kmixer/kmixer.c
- * PURPOSE: main entry point
- * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
- */
-
-#include "kmixer.h"
-
-NTSTATUS
-NTAPI
-KMix_Pnp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IrpStack;
-
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
-
- DPRINT("KMix_Pnp called for func %x\n", IrpStack->MinorFunction);
-
- if (IrpStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
- {
- Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
- }
-
- return KsDefaultDispatchPnp(DeviceObject, Irp);
-}
-
-VOID
-NTAPI
-KMix_Unload(IN PDRIVER_OBJECT DriverObject)
-{
- DPRINT1("SysAudio_Unload called\n");
-}
-
-NTSTATUS
-NTAPI
-KMix_InstallDevice(
- IN PDRIVER_OBJECT DriverObject)
-{
- NTSTATUS Status;
- UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\kmixer");
- PDEVICE_OBJECT DeviceObject;
- PKMIXER_DEVICE_EXT DeviceExtension;
-
- DPRINT1("KMix_InstallDevice called\n");
-
- /* create the device */
- Status = IoCreateDevice(DriverObject,
- sizeof(KMIXER_DEVICE_EXT),
- &DeviceName,
- FILE_DEVICE_KS,
- 0,
- FALSE,
- &DeviceObject);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Failed to create \\Device\\kmixer !\n");
- return Status;
- }
-
- DeviceExtension = (PKMIXER_DEVICE_EXT)DeviceObject->DeviceExtension;
- /* initialize device extension */
- RtlZeroMemory(DeviceExtension, sizeof(KMIXER_DEVICE_EXT));
-
-
- Status = KMixAllocateDeviceHeader(DeviceExtension);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("KMixAllocateDeviceHeader failed with %x\n", Status);
- goto cleanup;
- }
-
- /* set io flags */
- DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
- /* clear initializing flag */
- DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
-
- DPRINT("KMix_InstallDevice result %x\n", Status);
- return STATUS_SUCCESS;
-
-cleanup:
-
- IoDeleteDevice(DeviceObject);
- return Status;
-}
-
-
-NTSTATUS
-NTAPI
-DriverEntry(
- PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegistryPathName)
-{
- DPRINT1("KMixer.sys loaded\n");
-
- KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE);
- KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
- KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);
- KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
-
- DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
- DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
- DriverObject->MajorFunction[IRP_MJ_PNP] = KMix_Pnp;
- DriverObject->DriverUnload = KMix_Unload;
-
- return KMix_InstallDevice(DriverObject);
-}
+++ /dev/null
-#pragma once
-
-#include <ntddk.h>
-#include <portcls.h>
-#include <ks.h>
-#include <ksmedia.h>
-#include <swenum.h>
-#define YDEBUG
-#include <debug.h>
-
-#include <samplerate.h>
-#include <float_cast.h>
-
-typedef struct
-{
- KSDEVICE_HEADER KsDeviceHeader;
-
-
-}KMIXER_DEVICE_EXT, *PKMIXER_DEVICE_EXT;
-
-typedef struct
-{
- KSPIN_LOCK Lock;
-
-
-}SUM_NODE_CONTEXT, *PSUM_NODE_CONTEXT;
-
-
-NTSTATUS
-NTAPI
-KMixAllocateDeviceHeader(
- IN PKMIXER_DEVICE_EXT DeviceExtension);
-
-NTSTATUS
-CreatePin(
- IN PIRP Irp);
+++ /dev/null
-<?xml version="1.0"?>
-<!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd">
-<module name="kmixer" type="kernelmodedriver" installbase="system32/drivers" installname="kmixer.sys">
- <include base="kmixer">.</include>
- <include base="libsamplerate">.</include>
- <library>ntoskrnl</library>
- <library>ks</library>
- <library>hal</library>
- <library>libcntpr</library>
- <library>libsamplerate</library>
- <file>kmixer.c</file>
- <file>filter.c</file>
- <file>pin.c</file>
-</module>
+++ /dev/null
-/*
- * PROJECT: ReactOS Kernel Streaming Mixer
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/wdm/audio/filters/kmixer/kmixer.c
- * PURPOSE: Pin functions
- * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
- */
-
-#include "kmixer.h"
-
-const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
-
-NTSTATUS
-PerformSampleRateConversion(
- PUCHAR Buffer,
- ULONG BufferLength,
- ULONG OldRate,
- ULONG NewRate,
- ULONG BytesPerSample,
- ULONG NumChannels,
- PVOID * Result,
- PULONG ResultLength)
-{
- KFLOATING_SAVE FloatSave;
- NTSTATUS Status;
- ULONG Index;
- SRC_STATE * State;
- SRC_DATA Data;
- PUCHAR ResultOut;
- int error;
- PFLOAT FloatIn, FloatOut;
- ULONG NumSamples;
- ULONG NewSamples;
-
- DPRINT("PerformSampleRateConversion OldRate %u NewRate %u BytesPerSample %u NumChannels %u Irql %u\n", OldRate, NewRate, BytesPerSample, NumChannels, KeGetCurrentIrql());
-
- ASSERT(BytesPerSample == 1 || BytesPerSample == 2 || BytesPerSample == 4);
-
- /* first acquire float save context */
- Status = KeSaveFloatingPointState(&FloatSave);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("KeSaveFloatingPointState failed with %x\n", Status);
- return Status;
- }
-
- NumSamples = BufferLength / (BytesPerSample * NumChannels);
-
- FloatIn = ExAllocatePool(NonPagedPool, NumSamples * NumChannels * sizeof(FLOAT));
- if (!FloatIn)
- {
- KeRestoreFloatingPointState(&FloatSave);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- NewSamples = lrintf(((FLOAT)NumSamples * ((FLOAT)NewRate / (FLOAT)OldRate))) + 2;
-
- FloatOut = ExAllocatePool(NonPagedPool, NewSamples * NumChannels * sizeof(FLOAT));
- if (!FloatOut)
- {
- ExFreePool(FloatIn);
- KeRestoreFloatingPointState(&FloatSave);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- ResultOut = ExAllocatePool(NonPagedPool, NewSamples * NumChannels * BytesPerSample);
- if (!ResultOut)
- {
- ExFreePool(FloatIn);
- ExFreePool(FloatOut);
- KeRestoreFloatingPointState(&FloatSave);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- State = src_new(SRC_SINC_FASTEST, NumChannels, &error);
- if (!State)
- {
- DPRINT1("KeSaveFloatingPointState failed with %x\n", Status);
- KeRestoreFloatingPointState(&FloatSave);
- ExFreePool(FloatIn);
- ExFreePool(FloatOut);
- ExFreePool(ResultOut);
- return STATUS_UNSUCCESSFUL;
- }
-
- /* fixme use asm */
- if (BytesPerSample == 1)
- {
- for(Index = 0; Index < NumSamples * NumChannels; Index++)
- FloatIn[Index] = (float)(Buffer[Index] / (1.0 * 0x80));
- }
- else if (BytesPerSample == 2)
- {
- src_short_to_float_array((short*)Buffer, FloatIn, NumSamples * NumChannels);
- }
- else if (BytesPerSample == 4)
- {
- src_int_to_float_array((int*)Buffer, FloatIn, NumSamples * NumChannels);
- }
-
- Data.data_in = FloatIn;
- Data.data_out = FloatOut;
- Data.input_frames = NumSamples;
- Data.output_frames = NewSamples;
- Data.src_ratio = (double)NewRate / (double)OldRate;
-
- error = src_process(State, &Data);
- if (error)
- {
- DPRINT1("src_process failed with %x\n", error);
- KeRestoreFloatingPointState(&FloatSave);
- ExFreePool(FloatIn);
- ExFreePool(FloatOut);
- ExFreePool(ResultOut);
- return STATUS_UNSUCCESSFUL;
- }
-
- if (BytesPerSample == 1)
- {
- /* FIXME perform over/under clipping */
-
- for(Index = 0; Index < Data.output_frames_gen * NumChannels; Index++)
- ResultOut[Index] = (lrintf(FloatOut[Index]) >> 24);
- }
- else if (BytesPerSample == 2)
- {
- PUSHORT Res = (PUSHORT)ResultOut;
-
- src_float_to_short_array(FloatOut, (short*)Res, Data.output_frames_gen * NumChannels);
- }
- else if (BytesPerSample == 4)
- {
- PULONG Res = (PULONG)ResultOut;
-
- src_float_to_int_array(FloatOut, (int*)Res, Data.output_frames_gen * NumChannels);
- }
-
-
- *Result = ResultOut;
- *ResultLength = Data.output_frames_gen * BytesPerSample * NumChannels;
- ExFreePool(FloatIn);
- ExFreePool(FloatOut);
- src_delete(State);
- KeRestoreFloatingPointState(&FloatSave);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-PerformChannelConversion(
- PUCHAR Buffer,
- ULONG BufferLength,
- ULONG OldChannels,
- ULONG NewChannels,
- ULONG BitsPerSample,
- PVOID * Result,
- PULONG ResultLength)
-{
- ULONG Samples;
- ULONG NewIndex, OldIndex;
-
- Samples = BufferLength / (BitsPerSample / 8) / OldChannels;
-
- if (NewChannels > OldChannels)
- {
- if (BitsPerSample == 8)
- {
- PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels);
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
- {
- ULONG SubIndex = 0;
-
- RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(UCHAR));
-
- do
- {
- /* 2 channel stretched to 4 looks like LRLR */
- BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)];
- }while(SubIndex++ < NewChannels - OldChannels);
- }
- *Result = BufferOut;
- *ResultLength = Samples * NewChannels;
- }
- else if (BitsPerSample == 16)
- {
- PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels);
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
- {
- ULONG SubIndex = 0;
-
- RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(USHORT));
-
- do
- {
- BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)];
- }while(SubIndex++ < NewChannels - OldChannels);
- }
- *Result = BufferOut;
- *ResultLength = Samples * NewChannels;
- }
- else if (BitsPerSample == 24)
- {
- PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels);
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
- {
- ULONG SubIndex = 0;
-
- RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * 3);
-
- do
- {
- RtlMoveMemory(&BufferOut[(NewIndex+OldChannels + SubIndex) * 3], &Buffer[(OldIndex + (SubIndex % OldChannels)) * 3], 3);
- }while(SubIndex++ < NewChannels - OldChannels);
- }
- *Result = BufferOut;
- *ResultLength = Samples * NewChannels;
- }
- else if (BitsPerSample == 32)
- {
- PULONG BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels);
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
- {
- ULONG SubIndex = 0;
-
- RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(ULONG));
-
- do
- {
- BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)];
- }while(SubIndex++ < NewChannels - OldChannels);
- }
- *Result = BufferOut;
- *ResultLength = Samples * NewChannels;
- }
-
- }
- else
- {
- PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels);
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
- {
- /* TODO
- * mix stream instead of just dumping part of it ;)
- */
- RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], NewChannels * (BitsPerSample/8));
- }
-
- *Result = BufferOut;
- *ResultLength = Samples * NewChannels;
- }
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-PerformQualityConversion(
- PUCHAR Buffer,
- ULONG BufferLength,
- ULONG OldWidth,
- ULONG NewWidth,
- PVOID * Result,
- PULONG ResultLength)
-{
- ULONG Samples;
- ULONG Index;
-
- ASSERT(OldWidth != NewWidth);
-
- Samples = BufferLength / (OldWidth / 8);
- //DPRINT("Samples %u BufferLength %u\n", Samples, BufferLength);
-
- if (OldWidth == 8 && NewWidth == 16)
- {
- USHORT Sample;
- PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(USHORT));
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(Index = 0; Index < Samples; Index++)
- {
- Sample = Buffer[Index];
- Sample *= 2;
-#ifdef _X86_
- Sample = _byteswap_ushort(Sample);
-#endif
- BufferOut[Index] = Sample;
- }
- *Result = BufferOut;
- *ResultLength = Samples * sizeof(USHORT);
- }
- else if (OldWidth == 8 && NewWidth == 32)
- {
- ULONG Sample;
- PULONG BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(ULONG));
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(Index = 0; Index < Samples; Index++)
- {
- Sample = Buffer[Index];
- Sample *= 16777216;
-#ifdef _X86_
- Sample = _byteswap_ulong(Sample);
-#endif
- BufferOut[Index] = Sample;
- }
- *Result = BufferOut;
- *ResultLength = Samples * sizeof(ULONG);
- }
- else if (OldWidth == 16 && NewWidth == 32)
- {
- ULONG Sample;
- PUSHORT BufferIn = (PUSHORT)Buffer;
- PULONG BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(ULONG));
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(Index = 0; Index < Samples; Index++)
- {
- Sample = BufferIn[Index];
- Sample *= 65536;
-#ifdef _X86_
- Sample = _byteswap_ulong(Sample);
-#endif
- BufferOut[Index] = Sample;
- }
- *Result = BufferOut;
- *ResultLength = Samples * sizeof(ULONG);
- }
-
- else if (OldWidth == 16 && NewWidth == 8)
- {
- USHORT Sample;
- PUSHORT BufferIn = (PUSHORT)Buffer;
- PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(UCHAR));
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(Index = 0; Index < Samples; Index++)
- {
- Sample = BufferIn[Index];
-#ifdef _X86_
- Sample = _byteswap_ushort(Sample);
-#endif
- Sample /= 256;
- BufferOut[Index] = (Sample & 0xFF);
- }
- *Result = BufferOut;
- *ResultLength = Samples * sizeof(UCHAR);
- }
- else if (OldWidth == 32 && NewWidth == 8)
- {
- ULONG Sample;
- PULONG BufferIn = (PULONG)Buffer;
- PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(UCHAR));
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(Index = 0; Index < Samples; Index++)
- {
- Sample = BufferIn[Index];
-#ifdef _X86_
- Sample = _byteswap_ulong(Sample);
-#endif
- Sample /= 16777216;
- BufferOut[Index] = (Sample & 0xFF);
- }
- *Result = BufferOut;
- *ResultLength = Samples * sizeof(UCHAR);
- }
- else if (OldWidth == 32 && NewWidth == 16)
- {
- USHORT Sample;
- PULONG BufferIn = (PULONG)Buffer;
- PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(USHORT));
- if (!BufferOut)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- for(Index = 0; Index < Samples; Index++)
- {
- Sample = BufferIn[Index];
-#ifdef _X86_
- Sample = _byteswap_ulong(Sample);
-#endif
- Sample /= 65536;
- BufferOut[Index] = (Sample & 0xFFFF);
- }
- *Result = BufferOut;
- *ResultLength = Samples * sizeof(USHORT);
- }
- else
- {
- DPRINT1("Not implemented conversion OldWidth %u NewWidth %u\n", OldWidth, NewWidth);
- return STATUS_NOT_IMPLEMENTED;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-NTAPI
-Pin_fnDeviceIoControl(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
- PKSP_PIN Property;
- //DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
-
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- if (IoStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(KSP_PIN) && IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSDATAFORMAT_WAVEFORMATEX))
- {
- Property = (PKSP_PIN)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
-
- if (IsEqualGUIDAligned(&Property->Property.Set, &KSPROPSETID_Connection))
- {
- if (Property->Property.Id == KSPROPERTY_CONNECTION_DATAFORMAT && Property->Property.Flags == KSPROPERTY_TYPE_SET)
- {
- PKSDATAFORMAT_WAVEFORMATEX Formats;
- PKSDATAFORMAT_WAVEFORMATEX WaveFormat;
-
- Formats = (PKSDATAFORMAT_WAVEFORMATEX)IoStack->FileObject->FsContext2;
- WaveFormat = (PKSDATAFORMAT_WAVEFORMATEX)Irp->UserBuffer;
-
- ASSERT(Property->PinId == 0 || Property->PinId == 1);
- ASSERT(Formats);
- ASSERT(WaveFormat);
-
- Formats[Property->PinId].WaveFormatEx.nChannels = WaveFormat->WaveFormatEx.nChannels;
- Formats[Property->PinId].WaveFormatEx.wBitsPerSample = WaveFormat->WaveFormatEx.wBitsPerSample;
- Formats[Property->PinId].WaveFormatEx.nSamplesPerSec = WaveFormat->WaveFormatEx.nSamplesPerSec;
-
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- }
- }
- DPRINT1("Size %u Expected %u\n",IoStack->Parameters.DeviceIoControl.OutputBufferLength, sizeof(KSDATAFORMAT_WAVEFORMATEX));
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-NTAPI
-Pin_fnRead(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- UNIMPLEMENTED
-
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-NTAPI
-Pin_fnWrite(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- UNIMPLEMENTED
-
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-Pin_fnFlush(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- UNIMPLEMENTED
-
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-NTAPI
-Pin_fnClose(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- UNIMPLEMENTED
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-Pin_fnQuerySecurity(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- UNIMPLEMENTED
-
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-NTAPI
-Pin_fnSetSecurity(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
-
- UNIMPLEMENTED
-
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
-}
-
-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)
-{
- UNIMPLEMENTED
-
-
- 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)
-{
- UNIMPLEMENTED
- 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)
-{
- PKSSTREAM_HEADER StreamHeader;
- PVOID BufferOut;
- ULONG BufferLength;
- NTSTATUS Status = STATUS_SUCCESS;
- PKSDATAFORMAT_WAVEFORMATEX Formats;
- PKSDATAFORMAT_WAVEFORMATEX InputFormat, OutputFormat;
-
- DPRINT("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
-
- Formats = (PKSDATAFORMAT_WAVEFORMATEX)FileObject->FsContext2;
-
- InputFormat = Formats;
- OutputFormat = (Formats + 1);
- StreamHeader = (PKSSTREAM_HEADER)Buffer;
-
-
- DPRINT("Num Channels %u Old Channels %u\n SampleRate %u Old SampleRate %u\n BitsPerSample %u Old BitsPerSample %u\n",
- InputFormat->WaveFormatEx.nChannels, OutputFormat->WaveFormatEx.nChannels,
- InputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.nSamplesPerSec,
- InputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.wBitsPerSample);
-
- if (InputFormat->WaveFormatEx.wBitsPerSample != OutputFormat->WaveFormatEx.wBitsPerSample)
- {
- Status = PerformQualityConversion(StreamHeader->Data,
- StreamHeader->DataUsed,
- InputFormat->WaveFormatEx.wBitsPerSample,
- OutputFormat->WaveFormatEx.wBitsPerSample,
- &BufferOut,
- &BufferLength);
- if (NT_SUCCESS(Status))
- {
- ExFreePool(StreamHeader->Data);
- StreamHeader->Data = BufferOut;
- StreamHeader->DataUsed = BufferLength;
- }
- }
-
- if (InputFormat->WaveFormatEx.nChannels != OutputFormat->WaveFormatEx.nChannels)
- {
- Status = PerformChannelConversion(StreamHeader->Data,
- StreamHeader->DataUsed,
- InputFormat->WaveFormatEx.nChannels,
- OutputFormat->WaveFormatEx.nChannels,
- OutputFormat->WaveFormatEx.wBitsPerSample,
- &BufferOut,
- &BufferLength);
-
- if (NT_SUCCESS(Status))
- {
- ExFreePool(StreamHeader->Data);
- StreamHeader->Data = BufferOut;
- StreamHeader->DataUsed = BufferLength;
- }
- }
-
- if (InputFormat->WaveFormatEx.nSamplesPerSec != OutputFormat->WaveFormatEx.nSamplesPerSec)
- {
- Status = PerformSampleRateConversion(StreamHeader->Data,
- StreamHeader->DataUsed,
- InputFormat->WaveFormatEx.nSamplesPerSec,
- OutputFormat->WaveFormatEx.nSamplesPerSec,
- OutputFormat->WaveFormatEx.wBitsPerSample / 8,
- OutputFormat->WaveFormatEx.nChannels,
- &BufferOut,
- &BufferLength);
- if (NT_SUCCESS(Status))
- {
- ExFreePool(StreamHeader->Data);
- StreamHeader->Data = BufferOut;
- StreamHeader->DataUsed = BufferLength;
- }
- }
-
- IoStatus->Status = Status;
-
- if (NT_SUCCESS(Status))
- return TRUE;
- else
- return TRUE;
-}
-
-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
-CreatePin(
- IN PIRP Irp)
-{
- NTSTATUS Status;
- KSOBJECT_HEADER ObjectHeader;
- PKSDATAFORMAT DataFormat;
- PIO_STACK_LOCATION IoStack;
-
-
- DataFormat = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX) * 2);
- if (!DataFormat)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- RtlZeroMemory(DataFormat, sizeof(KSDATAFORMAT_WAVEFORMATEX) * 2);
-
- IoStack = IoGetCurrentIrpStackLocation(Irp);
- IoStack->FileObject->FsContext2 = (PVOID)DataFormat;
-
- /* allocate object header */
- Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable);
- return Status;
-}
-
-void * calloc(size_t Elements, size_t ElementSize)
-{
- ULONG Index;
- PUCHAR Block = ExAllocatePool(NonPagedPool, Elements * ElementSize);
- if (!Block)
- return NULL;
-
- for(Index = 0; Index < Elements * ElementSize; Index++)
- Block[Index] = 0;
-
- return Block;
-}
-
-void free(PVOID Block)
-{
- ExFreePool(Block);
-}
<?xml version="1.0"?>
<!DOCTYPE group SYSTEM "../../../../tools/rbuild/project.dtd">
<group xmlns:xi="http://www.w3.org/2001/XInclude">
- <directory name="wdmaud">
- <xi:include href="wdmaud/wdmaud.rbuild" />
- </directory>
<!--<directory name="stream">
<xi:include href="stream/stream.rbuild" />
</directory>-->
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/legacy/wdmaud/deviface.c
- * PURPOSE: System Audio graph builder
- * PROGRAMMER: Andrew Greenwood
- * Johannes Anderwald
- */
-#include "wdmaud.h"
-
-const GUID KSPROPSETID_Sysaudio = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
-
-NTSTATUS
-WdmAudControlOpen(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
- {
- return WdmAudControlOpenMixer(DeviceObject, Irp, DeviceInfo, ClientInfo);
- }
-
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
- {
- return WdmAudControlOpenWave(DeviceObject, Irp, DeviceInfo, ClientInfo);
- }
-
- if (DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE)
- {
- return WdmAudControlOpenMidi(DeviceObject, Irp, DeviceInfo, ClientInfo);
- }
-
-
- return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-WdmAudControlDeviceType(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- ULONG Result = 0;
- NTSTATUS Status = STATUS_SUCCESS;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
-
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
- {
- Result = WdmAudGetMixerDeviceCount();
- }
- else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
- {
- Result = WdmAudGetWaveInDeviceCount();
- }
- else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
- {
- Result = WdmAudGetWaveOutDeviceCount();
- }
- else if (DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE)
- {
- Result = WdmAudGetMidiInDeviceCount();
- }
- else if (DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE)
- {
- Result = WdmAudGetMidiOutDeviceCount();
- }
-
-
- /* store result count */
- DeviceInfo->DeviceCount = Result;
-
- DPRINT("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, 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;
-
- DPRINT("WdmAudControlDeviceState\n");
-
- Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
-
- Property.Set = KSPROPSETID_Connection;
- Property.Id = KSPROPERTY_CONNECTION_STATE;
- Property.Flags = KSPROPERTY_TYPE_SET;
-
- State = DeviceInfo->u.State;
-
- Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesReturned);
-
- ObDereferenceObject(FileObject);
-
- DPRINT("WdmAudControlDeviceState Status %x\n", Status);
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-WdmAudCapabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
-
- DPRINT("WdmAudCapabilities entered\n");
-
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
- {
- Status = WdmAudMixerCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
- }
- else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
- {
- Status = WdmAudWaveCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
- }
- else if (DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE || DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE)
- {
- Status = WdmAudMidiCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
- }
-
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-NTAPI
-WdmAudIoctlClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- ULONG Index;
-
- for(Index = 0; Index < ClientInfo->NumPins; Index++)
- {
- if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
- {
- DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
- ZwClose(DeviceInfo->hDevice);
- ClientInfo->hPins[Index].Handle = NULL;
- SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- return STATUS_SUCCESS;
- }
- else if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE)
- {
- if (ClientInfo->hPins[Index].NotifyEvent)
- {
- ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent);
- ClientInfo->hPins[Index].NotifyEvent = NULL;
- }
- }
- }
-
- SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
- return STATUS_INVALID_PARAMETER;
-}
-
-NTSTATUS
-NTAPI
-WdmAudFrameSize(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- PFILE_OBJECT FileObject;
- KSPROPERTY Property;
- ULONG BytesReturned;
- KSALLOCATOR_FRAMING Framing;
- NTSTATUS Status;
-
- /* Get sysaudio pin file object */
- Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid buffer handle %p\n", DeviceInfo->hDevice);
- return SetIrpIoStatus(Irp, Status, 0);
- }
-
- /* Setup get framing request */
- Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING;
- Property.Flags = KSPROPERTY_TYPE_GET;
- Property.Set = KSPROPSETID_Connection;
-
- Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned);
- /* Did we succeed */
- if (NT_SUCCESS(Status))
- {
- /* Store framesize */
- DeviceInfo->u.FrameSize = Framing.FrameSize;
- }
-
- /* Release file object */
- ObDereferenceObject(FileObject);
-
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
-
-}
-
-NTSTATUS
-NTAPI
-WdmAudGetDeviceInterface(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo)
-{
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- NTSTATUS Status;
- LPWSTR Device;
- ULONG Size, Length;
-
- /* get device extension */
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- /* get device interface string input length */
- Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize;
-
- /* get mixer info */
- Status = WdmAudGetPnpNameByIndexAndType(DeviceInfo->DeviceIndex, DeviceInfo->DeviceType, &Device);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- /* invalid device id */
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
- }
-
- /* calculate length */
- Length = (wcslen(Device)+1) * sizeof(WCHAR);
-
- if (!Size)
- {
- /* store device interface size */
- DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
- }
- else if (Size < Length)
- {
- /* buffer too small */
- DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
- return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
- }
- else
- {
- //FIXME SEH
- RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
- }
-
- FreeItem(Device);
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-NTAPI
-WdmAudResetStream(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo)
-{
- KSRESET ResetStream;
- NTSTATUS Status;
- ULONG BytesReturned;
- PFILE_OBJECT FileObject;
-
- DPRINT("WdmAudResetStream\n");
-
- Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
-
- ResetStream = DeviceInfo->u.ResetStream;
- ASSERT(ResetStream == KSRESET_BEGIN || ResetStream == KSRESET_END);
-
- Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_RESET_STATE, (PVOID)&ResetStream, sizeof(KSRESET), NULL, 0, &BytesReturned);
-
- ObDereferenceObject(FileObject);
-
- DPRINT("WdmAudResetStream Status %x\n", Status);
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-NTAPI
-WdmAudDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
- PWDMAUD_DEVICE_INFO DeviceInfo;
- PWDMAUD_CLIENT ClientInfo;
-
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- DPRINT("WdmAudDeviceControl entered\n");
-
- if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO))
- {
- /* 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;
-
- DPRINT("WdmAudDeviceControl entered\n");
-
- switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_OPEN_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_GETCAPABILITIES:
- return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo);
- case IOCTL_CLOSE_WDMAUD:
- return WdmAudIoctlClose(DeviceObject, Irp, DeviceInfo, ClientInfo);
- case IOCTL_GETFRAMESIZE:
- return WdmAudFrameSize(DeviceObject, Irp, DeviceInfo, ClientInfo);
- case IOCTL_GETLINEINFO:
- return WdmAudGetLineInfo(DeviceObject, Irp, DeviceInfo, ClientInfo);
- case IOCTL_GETLINECONTROLS:
- return WdmAudGetLineControls(DeviceObject, Irp, DeviceInfo, ClientInfo);
- case IOCTL_SETCONTROLDETAILS:
- return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
- case IOCTL_GETCONTROLDETAILS:
- return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
- case IOCTL_QUERYDEVICEINTERFACESTRING:
- return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo);
- case IOCTL_GET_MIXER_EVENT:
- return WdmAudGetMixerEvent(DeviceObject, Irp, DeviceInfo, ClientInfo);
- case IOCTL_RESET_STREAM:
- return WdmAudResetStream(DeviceObject, Irp, DeviceInfo);
- case IOCTL_GETPOS:
- case IOCTL_GETDEVID:
- case IOCTL_GETVOLUME:
- case IOCTL_SETVOLUME:
-
- DPRINT1("Unhandeled %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
- break;
- }
-
- return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0);
-}
-
-NTSTATUS
-NTAPI
-IoCompletion (
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PVOID Ctx)
-{
- PKSSTREAM_HEADER Header;
- ULONG Length = 0;
- PMDL Mdl, NextMdl;
- PWDMAUD_COMPLETION_CONTEXT Context = (PWDMAUD_COMPLETION_CONTEXT)Ctx;
-
- /* get stream header */
- Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
-
- /* sanity check */
- ASSERT(Header);
-
- /* iterate through all stream headers and collect size */
- do
- {
- if (Context->Function == IOCTL_KS_READ_STREAM)
- {
- /* length is stored in DataUsed */
- Length += Header->DataUsed;
- }
- else
- {
- /* length stored in frameextend */
- Length += Header->FrameExtent;
- }
-
- /* subtract size */
- Context->Length -= Header->Size;
-
- /* move to next stream header */
- Header = (PKSSTREAM_HEADER)((ULONG_PTR)Header + Header->Size);
-
- }while(Context->Length);
-
- /* time to free all allocated mdls */
- Mdl = Irp->MdlAddress;
-
- while(Mdl)
- {
- /* get next mdl */
- NextMdl = Mdl->Next;
-
- /* unlock pages */
- MmUnlockPages(Mdl);
-
- /* grab next mdl */
- Mdl = NextMdl;
- }
-
- /* clear mdl list */
- Irp->MdlAddress = NULL;
-
- /* check if mdl is locked */
- if (Context->Mdl->MdlFlags & MDL_PAGES_LOCKED)
- {
- /* unlock pages */
- MmUnlockPages(Context->Mdl);
- }
-
- /* now free the mdl */
- IoFreeMdl(Context->Mdl);
-
- DPRINT("IoCompletion Irp %p IoStatus %lx Information %lx Length %lu\n", Irp, Irp->IoStatus.Status, Irp->IoStatus.Information, Length);
-
- if (Irp->IoStatus.Status == STATUS_SUCCESS)
- {
- /* store the length */
- Irp->IoStatus.Information = Length;
- }
- else
- {
- /* failed */
- Irp->IoStatus.Information = 0;
- }
-
- /* free context */
- FreeItem(Context);
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-NTAPI
-WdmAudReadWrite(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- NTSTATUS Status;
- PWDMAUD_DEVICE_INFO DeviceInfo;
- PFILE_OBJECT FileObject;
- PIO_STACK_LOCATION IoStack;
- ULONG Length;
- PMDL Mdl;
- BOOLEAN Read = TRUE;
- PWDMAUD_COMPLETION_CONTEXT Context;
-
- /* allocate completion context */
- Context = AllocateItem(NonPagedPool, sizeof(WDMAUD_COMPLETION_CONTEXT));
-
- if (!Context)
- {
- /* not enough memory */
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- /* done */
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* get current irp stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* store the input buffer in UserBuffer - as KsProbeStreamIrp operates on IRP_MJ_DEVICE_CONTROL */
- Irp->UserBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
-
- /* sanity check */
- ASSERT(Irp->UserBuffer);
-
- /* get the length of the request length */
- Length = IoStack->Parameters.Write.Length;
-
- /* store outputbuffer length */
- IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
-
- /* setup context */
- Context->Length = Length;
- Context->Function = (IoStack->MajorFunction == IRP_MJ_WRITE ? IOCTL_KS_WRITE_STREAM : IOCTL_KS_READ_STREAM);
- Context->Mdl = Irp->MdlAddress;
-
- /* store mdl address */
- Mdl = Irp->MdlAddress;
-
- /* remove mdladdress as KsProbeStreamIrp will interprete it as an already probed audio buffer */
- Irp->MdlAddress = NULL;
-
- /* check for success */
-
- if (IoStack->MajorFunction == IRP_MJ_WRITE)
- {
- /* probe the write stream irp */
- Read = FALSE;
- Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
- }
- else
- {
- /* probe the read stream irp */
- Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMREAD | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
- }
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("KsProbeStreamIrp failed with Status %x Cancel %u\n", Status, Irp->Cancel);
- Irp->MdlAddress = Mdl;
- return SetIrpIoStatus(Irp, Status, 0);
- }
-
- /* get device info */
- DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
- ASSERT(DeviceInfo);
-
- /* now get sysaudio file object */
- Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid pin handle %p\n", DeviceInfo->hDevice);
- return SetIrpIoStatus(Irp, Status, 0);
- }
-
- /* skip current irp stack location */
- IoSkipCurrentIrpStackLocation(Irp);
-
- /* get next stack location */
- IoStack = IoGetNextIrpStackLocation(Irp);
-
- if (Read)
- {
- IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_READ_STREAM;
- }
- else
- {
- IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM;
- }
-
- /* attach file object */
- IoStack->FileObject = FileObject;
- IoStack->Parameters.Write.Length = Length;
- IoStack->MajorFunction = IRP_MJ_WRITE;
-
- IoSetCompletionRoutine(Irp, IoCompletion, (PVOID)Context, TRUE, TRUE, TRUE);
-
-
- /* mark irp as pending */
-// IoMarkIrpPending(Irp);
- /* call the driver */
- Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
-
- /* dereference file object */
- ObDereferenceObject(FileObject);
-
- return Status;
-}
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/legacy/wdmaud/deviface.c
- * PURPOSE: System Audio graph builder
- * PROGRAMMER: Andrew Greenwood
- * Johannes Anderwald
- */
-#include "wdmaud.h"
-
-NTSTATUS
-WdmAudOpenSysAudioDevice(
- IN LPWSTR DeviceName,
- OUT PHANDLE Handle)
-{
- UNICODE_STRING SymbolicLink;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- NTSTATUS Status;
-
- RtlInitUnicodeString(&SymbolicLink, DeviceName);
- InitializeObjectAttributes(&ObjectAttributes, &SymbolicLink, OBJ_OPENIF | OBJ_KERNEL_HANDLE, NULL, NULL);
-
- Status = IoCreateFile(Handle,
- SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- 0,
- 0,
- FILE_OPEN,
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0,
- CreateFileTypeNone,
- NULL,
- IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);
-
- return Status;
-}
-
-NTSTATUS
-NTAPI
-DeviceInterfaceChangeCallback(
- IN PVOID NotificationStructure,
- IN PVOID Context)
-{
- DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
-
- DPRINT1("DeviceInterfaceChangeCallback called %p\n", Event);
- DbgBreakPoint();
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-WdmAudOpenSysAudioDeviceInterfaces(
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
- IN LPWSTR SymbolicLinkList)
-{
- SYSAUDIO_ENTRY * Entry;
- ULONG Length;
-
- DPRINT1("WdmAudOpenSysAudioDeviceInterfaces called\n");
-
- while(*SymbolicLinkList)
- {
- Length = wcslen(SymbolicLinkList) + 1;
- Entry = (SYSAUDIO_ENTRY*)AllocateItem(NonPagedPool, sizeof(SYSAUDIO_ENTRY) + Length * sizeof(WCHAR));
- if (!Entry)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Entry->SymbolicLink.Length = Length * sizeof(WCHAR);
- Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR);
- Entry->SymbolicLink.Buffer = (LPWSTR) (Entry + 1);
- wcscpy(Entry->SymbolicLink.Buffer, SymbolicLinkList);
-
- InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
-
- DeviceExtension->NumSysAudioDevices++;
- SymbolicLinkList += Length;
- }
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-WdmAudOpenSysAudioDevices(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- LPWSTR SymbolicLinkList;
- SYSAUDIO_ENTRY * Entry;
- ULONG Length;
- HANDLE hSysAudio;
- PFILE_OBJECT FileObject;
- UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio\\GLOBAL");
-
- if (DeviceExtension->DeviceInterfaceSupport)
- {
- Status = IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO,
- NULL,
- 0,
- &SymbolicLinkList);
-
- if (NT_SUCCESS(Status))
- {
- WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension, SymbolicLinkList);
- FreeItem(SymbolicLinkList);
- }
-
-
- Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
- PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
- (PVOID)&KSCATEGORY_SYSAUDIO,
- DeviceObject->DriverObject,
- DeviceInterfaceChangeCallback,
- (PVOID)DeviceExtension,
- &DeviceExtension->SysAudioNotification);
- }
- else
- {
- Entry = (SYSAUDIO_ENTRY*)AllocateItem(NonPagedPool, sizeof(SYSAUDIO_ENTRY));
- if (!Entry)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
-
- Length = wcslen(DeviceName.Buffer) + 1;
- Entry->SymbolicLink.Length = 0;
- Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR);
- Entry->SymbolicLink.Buffer = AllocateItem(NonPagedPool, Entry->SymbolicLink.MaximumLength);
-
- if (!Entry->SymbolicLink.Buffer)
- {
- FreeItem(Entry);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Status = RtlAppendUnicodeStringToString(&Entry->SymbolicLink, &DeviceName);
-
- if (!NT_SUCCESS(Status))
- {
- FreeItem(Entry->SymbolicLink.Buffer);
- FreeItem(Entry);
- return Status;
- }
-
- InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
- DeviceExtension->NumSysAudioDevices++;
-
- DPRINT("Opening device %S\n", Entry->SymbolicLink.Buffer);
- Status = WdmAudOpenSysAudioDevice(Entry->SymbolicLink.Buffer, &hSysAudio);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to open sysaudio %x\n", Status);
- return Status;
- }
-
- /* get the file object */
- Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reference FileObject %x\n", Status);
- ZwClose(hSysAudio);
- return Status;
- }
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- DeviceExtension->hSysAudio = hSysAudio;
- DeviceExtension->FileObject = FileObject;
- }
-
- return Status;
-}
-
-NTSTATUS
-WdmAudRegisterDeviceInterface(
- IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
-{
- NTSTATUS Status;
- UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
- UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
- UNICODE_STRING SymbolicLinkName;
-
- Status = IoRegisterDeviceInterface(PhysicalDeviceObject, &KSCATEGORY_WDMAUD, NULL, &SymbolicLinkName);
- if (NT_SUCCESS(Status))
- {
- IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
- RtlFreeUnicodeString(&SymbolicLinkName);
- DeviceExtension->DeviceInterfaceSupport = TRUE;
- return Status;
- }
-
- /* failed to register device interface
- * create a symbolic link instead
- */
- DeviceExtension->DeviceInterfaceSupport = FALSE;
-
- Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
- if (!NT_SUCCESS(Status))
- {
- IoDeleteDevice(PhysicalDeviceObject); //FIXME
- DPRINT("Failed to create wdmaud symlink!\n");
- return Status;
- }
-
- return Status;
-}
-
-NTSTATUS
-WdmAudOpenSysaudio(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_CLIENT *pClient)
-{
- PWDMAUD_CLIENT Client;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
-
- /* get device extension */
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- if (!DeviceExtension->NumSysAudioDevices)
- {
- /* wdmaud failed to open sysaudio */
- return STATUS_UNSUCCESSFUL;
- }
-
- /* sanity check */
- ASSERT(!IsListEmpty(&DeviceExtension->SysAudioDeviceList));
-
- /* allocate client context struct */
- Client = AllocateItem(NonPagedPool, sizeof(WDMAUD_CLIENT));
-
- /* check for allocation failure */
- if (!Client)
- {
- /* not enough memory */
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* zero client context struct */
- RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT));
-
- /* initialize mixer event list */
- InitializeListHead(&Client->MixerEventList);
-
- /* store result */
- *pClient = Client;
-
- /* insert client into list */
- ExInterlockedInsertTailList(&DeviceExtension->WdmAudClientList, &Client->Entry, &DeviceExtension->Lock);
-
- /* done */
- return STATUS_SUCCESS;
-}
-
-
-
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/legacy/wdmaud/main.c
- * PURPOSE: System Audio graph builder
- * PROGRAMMER: Andrew Greenwood
- * Johannes Anderwald
- */
-#include "wdmaud.h"
-
-const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
-const GUID KSCATEGORY_WDMAUD = {0x3E227E76L, 0x690D, 0x11D2, {0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1}};
-
-NTSTATUS
-NTAPI
-WdmAudInstallDevice(
- IN PDRIVER_OBJECT DriverObject)
-{
- UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
- UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
- PDEVICE_OBJECT DeviceObject;
- NTSTATUS Status;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
-
- DPRINT("WdmAudInstallDevice called\n");
-
- Status = IoCreateDevice(DriverObject,
- sizeof(WDMAUD_DEVICE_EXTENSION),
- &DeviceName,
- FILE_DEVICE_KS,
- 0,
- FALSE,
- &DeviceObject);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IoCreateDevice failed with %x\n", Status);
- return Status;
- }
-
- /* clear device extension */
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION));
-
- /* register device interfaces */
- Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status);
- IoDeleteDevice(DeviceObject);
- return Status;
- }
-
- /* initialize sysaudio device list */
- InitializeListHead(&DeviceExtension->SysAudioDeviceList);
-
- /* initialize client context device list */
- InitializeListHead(&DeviceExtension->WdmAudClientList);
-
- /* initialize spinlock */
- KeInitializeSpinLock(&DeviceExtension->Lock);
-
- /* find available sysaudio devices */
- Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
- IoDeleteSymbolicLink(&SymlinkName);
- IoDeleteDevice(DeviceObject);
- return Status;
- }
- /* allocate ks device header */
- Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
- IoDeleteSymbolicLink(&SymlinkName);
- IoDeleteDevice(DeviceObject);
- return Status;
- }
-
- Status = WdmAudMixerInitialize(DeviceObject);
- DPRINT("WdmAudMixerInitialize Status %x WaveIn %lu WaveOut %lu Mixer %lu\n", Status, WdmAudGetWaveInDeviceCount(), WdmAudGetWaveOutDeviceCount(), WdmAudGetMixerDeviceCount());
-
- DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
- DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
-
- return STATUS_SUCCESS;
-}
-
-VOID
-NTAPI
-WdmAudUnload(
- IN PDRIVER_OBJECT driver)
-{
- DPRINT("WdmAudUnload called\n");
-}
-
-NTSTATUS
-NTAPI
-WdmAudPnp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IrpStack;
-
- DPRINT("WdmAudPnp called\n");
-
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
-
- if (IrpStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
- {
- Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
- return KsDefaultDispatchPnp(DeviceObject, Irp);
- }
- return KsDefaultDispatchPnp(DeviceObject, Irp);
-}
-
-
-NTSTATUS
-NTAPI
-WdmAudCreate(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- NTSTATUS Status;
- PIO_STACK_LOCATION IoStack;
- PWDMAUD_CLIENT pClient;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
-
- /* get device extension */
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-#if KS_IMPLEMENTED
- Status = KsReferenceSoftwareBusObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("KsReferenceSoftwareBusObject failed with %x\n", Status);
- return Status;
- }
-#endif
-
- Status = WdmAudOpenSysaudio(DeviceObject, &pClient);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to open sysaudio!\n");
-
- /* complete and forget */
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- /* done */
- return STATUS_UNSUCCESSFUL;
- }
-
- IoStack = IoGetCurrentIrpStackLocation(Irp);
- ASSERT(IoStack->FileObject);
-
- /* store client context in file object */
- IoStack->FileObject->FsContext = pClient;
- Status = STATUS_SUCCESS;
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return Status;
-}
-
-NTSTATUS
-NTAPI
-WdmAudClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- /* nothing to do complete request */
-#if KS_IMPLEMENTED
- Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
-
- if (NT_SUCCESS(Status))
- {
- if (DeviceExtension->SysAudioNotification)
- Status = IoUnregisterPlugPlayNotification(DeviceExtension->SysAudioNotification);
- }
-#endif
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- /* done */
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-WdmAudCleanup(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
- PWDMAUD_CLIENT pClient;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- ULONG Index;
- KIRQL OldIrql;
-
- /* get device extension */
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- /* get current irp stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* sanity check */
- ASSERT(IoStack->FileObject);
-
- /* get client context struct */
- pClient = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
-
- /* sanity check */
- ASSERT(pClient);
-
- /* acquire client context list lock */
- KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql);
-
- /* remove entry */
- RemoveEntryList(&pClient->Entry);
-
- /* release lock */
- KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql);
-
- /* check if all audio pins have been closed */
- for (Index = 0; Index < pClient->NumPins; Index++)
- {
- DPRINT("Index %u Pin %p Type %x\n", Index, pClient->hPins[Index].Handle, pClient->hPins[Index].Type);
- if (pClient->hPins[Index].Handle && pClient->hPins[Index].Type != MIXER_DEVICE_TYPE)
- {
- /* found an still open audio pin */
- ZwClose(pClient->hPins[Index].Handle);
- }
- }
-
- /* free pin array */
- if (pClient->hPins)
- FreeItem(pClient->hPins);
-
- /* free client context struct */
- FreeItem(pClient);
-
- /* clear old client pointer */
- IoStack->FileObject->FsContext = NULL;
-
- /* complete request */
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- /* done */
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-DriverEntry(
- IN PDRIVER_OBJECT Driver,
- IN PUNICODE_STRING Registry_path
-)
-{
- DPRINT("Wdmaud.sys loaded\n");
-
- Driver->DriverUnload = WdmAudUnload;
-
- Driver->MajorFunction[IRP_MJ_CREATE] = WdmAudCreate;
- Driver->MajorFunction[IRP_MJ_CLOSE] = WdmAudClose;
- Driver->MajorFunction[IRP_MJ_PNP] = WdmAudPnp;
- Driver->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
- Driver->MajorFunction[IRP_MJ_CLEANUP] = WdmAudCleanup;
- Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WdmAudDeviceControl;
- Driver->MajorFunction[IRP_MJ_WRITE] = WdmAudReadWrite;
- Driver->MajorFunction[IRP_MJ_READ] = WdmAudReadWrite;
- Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
-
- return WdmAudInstallDevice(Driver);
-}
+++ /dev/null
-#pragma once
-
-///
-/// WDMAUD Interface Definition
-///
-/// History: 12/02/2008 Created
-
-// These are now in sndtypes.h
-/*
-typedef enum
-{
- DEVICE_TYPE_NONE = 0,
- DEVICE_TYPE_WAVE_OUT,
- DEVICE_TYPE_WAVE_IN,
- DEVICE_TYPE_MIDI_IN,
- DEVICE_TYPE_MIDI_OUT,
- DEVICE_TYPE_AUX_IN,
- DEVICE_TYPE_AUX_OUT
-
-}AUDIO_DEVICE_TYPE;
-*/
-
-#include <sndtypes.h>
-
-typedef struct
-{
- KSSTREAM_HEADER Header;
- SOUND_DEVICE_TYPE DeviceType;
- ULONG_PTR DeviceIndex;
-
- HANDLE hDevice;
- ULONG DeviceCount;
- ULONG Flags;
-
- union
- {
- MIXERCAPSW MixCaps;
- MIXERCONTROLDETAILS MixDetails;
- MIXERLINECONTROLSW MixControls;
- MIXERLINEW MixLine;
- WAVEFORMATEX WaveFormatEx;
- WAVEOUTCAPSW WaveOutCaps;
- AUXCAPSW AuxCaps;
- WAVEINCAPSW WaveInCaps;
- MIDIINCAPSW MidiInCaps;
- MIDIOUTCAPSW MidiOutCaps;
- ULONGLONG Position;
- struct
- {
- LPWSTR DeviceInterfaceString;
- ULONG DeviceInterfaceStringSize;
- }Interface;
-
- struct
- {
- HANDLE hMixer;
- ULONG NotificationType;
- ULONG Value;
- }MixerEvent;
- KSSTATE State;
- KSRESET ResetStream;
- ULONG Volume;
- ULONG FrameSize;
- HANDLE hNotifyEvent;
- }u;
-
-}WDMAUD_DEVICE_INFO, *PWDMAUD_DEVICE_INFO;
-
-
-
-/// IOCTL_OPEN_WDMAUD
-///
-/// Description: This IOCTL informs wdmaud that an application whats to use wdmsys for a waveOut / waveIn / aux operation
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: DeviceType identifies the device type, DeviceIndex the index, WaveFormatEx the device details
-/// Result: is returned in hDevice
-/// Return Code: STATUS_SUCCESS indicates success, otherwise appropiate error code
-/// Prequsites: none
-
-#define IOCTL_OPEN_WDMAUD \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 0, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_CLOSE_WDMAUD
-///
-/// Description: This IOCTL informs that an application has finished with wdmsys and closes the connection
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: DeviceType, DeviceIndex and hDevice must be set
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: openend device
-
-#define IOCTL_CLOSE_WDMAUD \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 1, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) \
-
-
-/// IOCTL_GETNUMDEVS_TYPE
-///
-/// Description: This IOCTL queries the number of devices currently present of a specific type. The caller passes a WDMAUD_DEVICE_INFO structure.
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType contains the requested device type.
-/// Result: The result is returned in DeviceCount
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: none
-
-#define IOCTL_GETNUMDEVS_TYPE \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 2, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_SETDEVICE_STATE
-///
-/// Description: This IOCTL sets an opened waveOut / waveIn / midiIn / midiOut / aux device to specific state
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType, DeviceIndex, hDevice and State member must be set. State determines the new state
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_SETDEVICE_STATE \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 3, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_GETDEVID
-///
-/// Description: This IOCTL returns the device index by its provided handle
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType and hDevice must be set
-/// Result: The result is returned in DeviceIndex
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_GETDEVID \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 4, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_GETVOLUME
-///
-/// Description: This IOCTL returns the volume a device
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType and hDevice must be set
-/// Result: The result is returned in Volume
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_GETVOLUME \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 5, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_SETVOLUME
-///
-/// Description: This IOCTL sets the volume a device
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType, hDevice and Volume must be set
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_SETVOLUME \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 6, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_GETCAPABILTIES
-///
-/// Description: This IOCTL retrieves the capabilties of an specific device
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType and DeviceIndex must be set
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: none
-
-#define IOCTL_GETCAPABILITIES \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 7, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_WRITEDATA
-///
-/// Description: This IOCTL writes data to specified device
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType, DeviceIndex, hDevice, BufferSize and Buffer must be set
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_WRITEDATA \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 8, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-/// IOCTL_GETPOS
-///
-/// Description: This IOCTL retrieves the current playback / write position
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType and hDevice must be set
-/// Result: The result is returned in Position
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_GETPOS \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 9, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-/// IOCTL_GETFRAMESIZE
-///
-/// Description: This IOCTL retrieves the frame size requirements for an audio pin
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType and hDevice must be set
-/// Result: The result is returned in FrameSize
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_GETFRAMESIZE \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 10, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-/// IOCTL_GETLINEINFO
-///
-/// Description: This IOCTL retrieves information on a mixerline
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The hDevice member must be set
-/// Result: The result is returned in MixLine
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_GETLINEINFO \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 11, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_GETLINECONTROLS
-///
-/// Description: This IOCTL retrieves controls of a mixerline
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The hDevice member must be set
-/// Result: The result is returned in MixControls
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_GETLINECONTROLS \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 12, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_SETCONTROLDETAILS
-///
-/// Description: This IOCTL sets details of a control of a mixerline
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The hDevice member must be set
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_SETCONTROLDETAILS \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 13, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_GETCONTROLDETAILS
-///
-/// Description: This IOCTL gets details of a control of a mixerline
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The hDevice member must be set
-/// Result: The result is returned in MixDetails
-/// ReturnCode: STATUS_SUCCESS indicates success
-/// Prequsites: opened device
-
-#define IOCTL_GETCONTROLDETAILS \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 14, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-
-/// IOCTL_QUERYDEVICEINTERFACESTRING
-///
-/// Description: This IOCTL queries the mixer / playback / recording device for its device interface string
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The DeviceType, DeviceIndex must be set
-/// Result: The size is returned in Interface.DeviceInterfaceStringSize and if a buffer is supplied in Interface.DeviceInterfaceString
-/// the device interface string is stored
-/// ReturnCode: STATUS_SUCCESS indicates success
-
-#define IOCTL_QUERYDEVICEINTERFACESTRING \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 15, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-/// IOCTL_GET_MIXER_EVENT
-///
-/// Description: This IOCTL queries for wdmaud driver if there any new kernel streaming events available
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The hDevice member must be set
-/// Result: The result is returned in the struct MixerInfo
-/// ReturnCode: STATUS_SUCCESS indicates success
-
-#define IOCTL_GET_MIXER_EVENT \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 16, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
-
-/// IOCTL_RESET_STREAM
-///
-/// Description: This IOCTL instructs wdmaud to reset a stream
-///
-/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
-/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
-/// Note: The hDevice member must be set and DeviceType
-/// ReturnCode: STATUS_SUCCESS indicates success
-
-#define IOCTL_RESET_STREAM \
- CTL_CODE(FILE_DEVICE_SOUND, \
- 17, \
- METHOD_BUFFERED, \
- FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/legacy/wdmaud/mmixer.c
- * PURPOSE: WDM Legacy Mixer
- * PROGRAMMER: Johannes Anderwald
- */
-
-#include "wdmaud.h"
-
-
-PVOID Alloc(ULONG NumBytes);
-MIXER_STATUS Close(HANDLE hDevice);
-VOID Free(PVOID Block);
-VOID Copy(PVOID Src, PVOID Dst, ULONG NumBytes);
-MIXER_STATUS Open(IN LPWSTR DevicePath, OUT PHANDLE hDevice);
-MIXER_STATUS Control(IN HANDLE hMixer, IN ULONG dwIoControlCode, IN PVOID lpInBuffer, IN ULONG nInBufferSize, OUT PVOID lpOutBuffer, ULONG nOutBufferSize, PULONG lpBytesReturned);
-MIXER_STATUS Enum(IN PVOID EnumContext, IN ULONG DeviceIndex, OUT LPWSTR * DeviceName, OUT PHANDLE OutHandle, OUT PHANDLE OutKey);
-MIXER_STATUS OpenKey(IN HANDLE hKey, IN LPWSTR SubKey, IN ULONG DesiredAccess, OUT PHANDLE OutKey);
-MIXER_STATUS CloseKey(IN HANDLE hKey);
-MIXER_STATUS QueryKeyValue(IN HANDLE hKey, IN LPWSTR KeyName, OUT PVOID * ResultBuffer, OUT PULONG ResultLength, OUT PULONG KeyType);
-PVOID AllocEventData(IN ULONG ExtraSize);
-VOID FreeEventData(IN PVOID EventData);
-
-MIXER_CONTEXT MixerContext =
-{
- sizeof(MIXER_CONTEXT),
- NULL,
- Alloc,
- Control,
- Free,
- Open,
- Close,
- Copy,
- OpenKey,
- QueryKeyValue,
- CloseKey,
- AllocEventData,
- FreeEventData
-};
-
-GUID CategoryGuid = {STATIC_KSCATEGORY_AUDIO};
-
-MIXER_STATUS
-QueryKeyValue(
- IN HANDLE hKey,
- IN LPWSTR lpKeyName,
- OUT PVOID * ResultBuffer,
- OUT PULONG ResultLength,
- OUT PULONG KeyType)
-{
- NTSTATUS Status;
- UNICODE_STRING KeyName;
- ULONG Length;
- PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
-
- /* initialize key name */
- RtlInitUnicodeString(&KeyName, lpKeyName);
-
- /* now query MatchingDeviceId key */
- Status = ZwQueryValueKey(hKey, &KeyName, KeyValuePartialInformation, NULL, 0, &Length);
-
- /* check for success */
- if (Status != STATUS_BUFFER_TOO_SMALL)
- return MM_STATUS_UNSUCCESSFUL;
-
- /* allocate a buffer for key data */
- PartialInformation = AllocateItem(NonPagedPool, Length);
-
- if (!PartialInformation)
- return MM_STATUS_NO_MEMORY;
-
-
- /* now query MatchingDeviceId key */
- Status = ZwQueryValueKey(hKey, &KeyName, KeyValuePartialInformation, PartialInformation, Length, &Length);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- FreeItem(PartialInformation);
- return MM_STATUS_UNSUCCESSFUL;
- }
-
- if (KeyType)
- {
- /* return key type */
- *KeyType = PartialInformation->Type;
- }
-
- if (ResultLength)
- {
- /* return data length */
- *ResultLength = PartialInformation->DataLength;
- }
-
- *ResultBuffer = AllocateItem(NonPagedPool, PartialInformation->DataLength);
- if (!*ResultBuffer)
- {
- /* not enough memory */
- FreeItem(PartialInformation);
- return MM_STATUS_NO_MEMORY;
- }
-
- /* copy key value */
- RtlMoveMemory(*ResultBuffer, PartialInformation->Data, PartialInformation->DataLength);
-
- /* free key info */
- FreeItem(PartialInformation);
-
- return MM_STATUS_SUCCESS;
-}
-
-MIXER_STATUS
-OpenKey(
- IN HANDLE hKey,
- IN LPWSTR lpSubKeyName,
- IN ULONG DesiredAccess,
- OUT PHANDLE OutKey)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING SubKeyName;
- NTSTATUS Status;
-
- /* initialize sub key name */
- RtlInitUnicodeString(&SubKeyName, lpSubKeyName);
-
- /* initialize key attributes */
- InitializeObjectAttributes(&ObjectAttributes, &SubKeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, hKey, NULL);
-
- /* open the key */
- Status = ZwOpenKey(OutKey, DesiredAccess, &ObjectAttributes);
-
- if (NT_SUCCESS(Status))
- return MM_STATUS_SUCCESS;
- else
- return MM_STATUS_UNSUCCESSFUL;
-}
-
-MIXER_STATUS
-CloseKey(
- IN HANDLE hKey)
-{
- if (ZwClose(hKey) == STATUS_SUCCESS)
- return MM_STATUS_SUCCESS;
- else
- return MM_STATUS_UNSUCCESSFUL;
-}
-
-
-PVOID Alloc(ULONG NumBytes)
-{
- return AllocateItem(NonPagedPool, NumBytes);
-}
-
-MIXER_STATUS
-Close(HANDLE hDevice)
-{
- if (ZwClose(hDevice) == STATUS_SUCCESS)
- return MM_STATUS_SUCCESS;
- else
- return MM_STATUS_UNSUCCESSFUL;
-}
-
-VOID
-Free(PVOID Block)
-{
- FreeItem(Block);
-}
-
-VOID
-Copy(PVOID Src, PVOID Dst, ULONG NumBytes)
-{
- RtlMoveMemory(Src, Dst, NumBytes);
-}
-
-MIXER_STATUS
-Open(
- IN LPWSTR DevicePath,
- OUT PHANDLE hDevice)
-{
- if (WdmAudOpenSysAudioDevice(DevicePath, hDevice) == STATUS_SUCCESS)
- return MM_STATUS_SUCCESS;
- else
- return MM_STATUS_UNSUCCESSFUL;
-}
-
-MIXER_STATUS
-Control(
- IN HANDLE hMixer,
- IN ULONG dwIoControlCode,
- IN PVOID lpInBuffer,
- IN ULONG nInBufferSize,
- OUT PVOID lpOutBuffer,
- ULONG nOutBufferSize,
- PULONG lpBytesReturned)
-{
- NTSTATUS Status;
- PFILE_OBJECT FileObject;
-
- /* get file object */
- Status = ObReferenceObjectByHandle(hMixer, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("failed to reference %p with %lx\n", hMixer, Status);
- return MM_STATUS_UNSUCCESSFUL;
- }
-
- /* perform request */
- Status = KsSynchronousIoControlDevice(FileObject, KernelMode, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned);
-
- /* release object reference */
- ObDereferenceObject(FileObject);
-
- if (Status == STATUS_MORE_ENTRIES || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
- {
- /* more data is available */
- return MM_STATUS_MORE_ENTRIES;
- }
- else if (Status == STATUS_SUCCESS)
- {
- /* operation succeeded */
- return MM_STATUS_SUCCESS;
- }
- else
- {
- DPRINT("Failed with %lx\n", Status);
- return MM_STATUS_UNSUCCESSFUL;
- }
-}
-
-MIXER_STATUS
-Enum(
- IN PVOID EnumContext,
- IN ULONG DeviceIndex,
- OUT LPWSTR * DeviceName,
- OUT PHANDLE OutHandle,
- OUT PHANDLE OutKey)
-{
- PDEVICE_OBJECT DeviceObject;
- ULONG DeviceCount;
- NTSTATUS Status;
- UNICODE_STRING KeyName;
-
- /* get enumeration context */
- DeviceObject = (PDEVICE_OBJECT)EnumContext;
-
- /* get device count */
- DeviceCount = GetSysAudioDeviceCount(DeviceObject);
-
- if (DeviceIndex >= DeviceCount)
- {
- /* no more devices */
- return MM_STATUS_NO_MORE_DEVICES;
- }
-
- /* get device name */
- Status = GetSysAudioDevicePnpName(DeviceObject, DeviceIndex, DeviceName);
-
- if (!NT_SUCCESS(Status))
- {
- /* failed to retrieve device name */
- return MM_STATUS_UNSUCCESSFUL;
- }
-
- /* intialize key name */
- RtlInitUnicodeString(&KeyName, *DeviceName);
-
- /* open device interface key */
- Status = IoOpenDeviceInterfaceRegistryKey(&KeyName, GENERIC_READ | GENERIC_WRITE, OutKey);
-#if 0
- if (!NT_SUCCESS(Status))
- {
- /* failed to open key */
- DPRINT("IoOpenDeviceInterfaceRegistryKey failed with %lx\n", Status);
- FreeItem(*DeviceName);
- return MM_STATUS_UNSUCCESSFUL;
- }
-#endif
-
- /* open device handle */
- Status = OpenDevice(*DeviceName, OutHandle, NULL);
- if (!NT_SUCCESS(Status))
- {
- /* failed to open device */
- return MM_STATUS_UNSUCCESSFUL;
- }
-
- return MM_STATUS_SUCCESS;
-}
-
-PVOID
-AllocEventData(
- IN ULONG ExtraSize)
-{
- PKSEVENTDATA Data = (PKSEVENTDATA)AllocateItem(NonPagedPool, sizeof(KSEVENTDATA) + ExtraSize);
- if (!Data)
- return NULL;
-
- Data->EventObject.Event = AllocateItem(NonPagedPool, sizeof(KEVENT));
- if (!Data->EventHandle.Event)
- {
- FreeItem(Data);
- return NULL;
- }
-
- KeInitializeEvent(Data->EventObject.Event, NotificationEvent, FALSE);
-
- Data->NotificationType = KSEVENTF_EVENT_HANDLE;
- return Data;
-}
-
-VOID
-FreeEventData(IN PVOID EventData)
-{
- PKSEVENTDATA Data = (PKSEVENTDATA)EventData;
-
- FreeItem(Data->EventHandle.Event);
- FreeItem(Data);
-}
-
-VOID
-EventCallback(
- IN PVOID MixerEventContext,
- IN HANDLE hMixer,
- IN ULONG NotificationType,
- IN ULONG Value)
-{
- PWDMAUD_CLIENT ClientInfo;
- PEVENT_ENTRY Entry;
- ULONG Index;
-
- /* get client context */
- ClientInfo = (PWDMAUD_CLIENT)MixerEventContext;
-
- /* now search for the mixer which originated the request */
- for(Index = 0; Index < ClientInfo->NumPins; Index++)
- {
- if (ClientInfo->hPins[Index].Handle == hMixer && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE)
- {
- if (ClientInfo->hPins[Index].NotifyEvent)
- {
- /* allocate event entry */
- Entry = AllocateItem(NonPagedPool, sizeof(EVENT_ENTRY));
- if (!Entry)
- {
- /* no memory */
- break;
- }
-
- /* setup event entry */
- Entry->NotificationType = NotificationType;
- Entry->Value = Value;
- Entry->hMixer = hMixer;
-
- /* insert entry */
- InsertTailList(&ClientInfo->MixerEventList, &Entry->Entry);
-
- /* now notify the client */
- KeSetEvent(ClientInfo->hPins[Index].NotifyEvent, 0, FALSE);
- }
- /* done */
- break;
- }
- }
-}
-
-
-NTSTATUS
-WdmAudMixerInitialize(
- IN PDEVICE_OBJECT DeviceObject)
-{
- MIXER_STATUS Status;
-
- /* initialize the mixer library */
- Status = MMixerInitialize(&MixerContext, Enum, (PVOID)DeviceObject);
-
- if (Status != MM_STATUS_SUCCESS)
- {
- /* failed to initialize mmixer library */
- DPRINT("MMixerInitialize failed with %lx\n", Status);
- }
-
- return Status;
-}
-
-NTSTATUS
-WdmAudMixerCapabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
-{
- if (MMixerGetCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.MixCaps) == MM_STATUS_SUCCESS)
- return STATUS_SUCCESS;
-
- return STATUS_INVALID_PARAMETER;
-}
-
-NTSTATUS
-WdmAudControlOpenMixer(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- HANDLE hMixer;
- PWDMAUD_HANDLE Handles;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- NTSTATUS Status;
- PKEVENT EventObject = NULL;
-
- DPRINT("WdmAudControlOpenMixer\n");
-
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- if (DeviceInfo->u.hNotifyEvent)
- {
- Status = ObReferenceObjectByHandle(DeviceInfo->u.hNotifyEvent, EVENT_MODIFY_STATE, ExEventObjectType, UserMode, (LPVOID*)&EventObject, NULL);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid notify event passed %p from client %p\n", DeviceInfo->u.hNotifyEvent, ClientInfo);
- DbgBreakPoint();
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
- }
-
- if (MMixerOpen(&MixerContext, DeviceInfo->DeviceIndex, ClientInfo, EventCallback, &hMixer) != MM_STATUS_SUCCESS)
- {
- ObDereferenceObject(EventObject);
- DPRINT1("Failed to open mixer\n");
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
-
-
- Handles = AllocateItem(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1));
-
- if (Handles)
- {
- if (ClientInfo->NumPins)
- {
- RtlMoveMemory(Handles, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins);
- FreeItem(ClientInfo->hPins);
- }
-
- ClientInfo->hPins = Handles;
- ClientInfo->hPins[ClientInfo->NumPins].Handle = hMixer;
- ClientInfo->hPins[ClientInfo->NumPins].Type = MIXER_DEVICE_TYPE;
- ClientInfo->hPins[ClientInfo->NumPins].NotifyEvent = EventObject;
- ClientInfo->NumPins++;
- }
- else
- {
- ObDereferenceObject(EventObject);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
- }
-
- DeviceInfo->hDevice = hMixer;
-
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-NTAPI
-WdmAudGetControlDetails(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- MIXER_STATUS Status;
-
- /* clear hmixer type flag */
- DeviceInfo->Flags &= ~MIXER_OBJECTF_HMIXER;
-
- /* query mmixer library */
- Status = MMixerGetControlDetails(&MixerContext, DeviceInfo->hDevice, DeviceInfo->Flags, &DeviceInfo->u.MixDetails);
-
- if (Status == MM_STATUS_SUCCESS)
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- else
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-NTAPI
-WdmAudGetLineInfo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- MIXER_STATUS Status;
-
- /* clear hmixer type flag */
- DeviceInfo->Flags &= ~MIXER_OBJECTF_HMIXER;
-
- /* query mixer library */
- Status = MMixerGetLineInfo(&MixerContext, DeviceInfo->hDevice, DeviceInfo->Flags, &DeviceInfo->u.MixLine);
-
- if (Status == MM_STATUS_SUCCESS)
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- else
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-NTAPI
-WdmAudGetLineControls(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- MIXER_STATUS Status;
-
- /* clear hmixer type flag */
- DeviceInfo->Flags &= ~MIXER_OBJECTF_HMIXER;
-
- /* query mixer library */
- Status = MMixerGetLineControls(&MixerContext, DeviceInfo->hDevice, DeviceInfo->Flags, &DeviceInfo->u.MixControls);
-
- if (Status == MM_STATUS_SUCCESS)
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- else
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
-
-
-}
-
-NTSTATUS
-NTAPI
-WdmAudSetControlDetails(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- MIXER_STATUS Status;
-
- /* clear hmixer type flag */
- DeviceInfo->Flags &= ~MIXER_OBJECTF_HMIXER;
-
- /* query mixer library */
- Status = MMixerSetControlDetails(&MixerContext, DeviceInfo->hDevice, DeviceInfo->Flags, &DeviceInfo->u.MixDetails);
-
- if (Status == MM_STATUS_SUCCESS)
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- else
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-NTAPI
-WdmAudGetMixerEvent(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- PLIST_ENTRY Entry;
- PEVENT_ENTRY EventEntry;
-
- /* enumerate event list and check if there is a new event */
- Entry = ClientInfo->MixerEventList.Flink;
-
- while(Entry != &ClientInfo->MixerEventList)
- {
- /* grab event entry */
- EventEntry = (PEVENT_ENTRY)CONTAINING_RECORD(Entry, EVENT_ENTRY, Entry);
-
- if (EventEntry->hMixer == DeviceInfo->hDevice)
- {
- /* found an entry */
- DeviceInfo->u.MixerEvent.hMixer = EventEntry->hMixer;
- DeviceInfo->u.MixerEvent.NotificationType = EventEntry->NotificationType;
- DeviceInfo->u.MixerEvent.Value = EventEntry->Value;
-
- /* remove entry from list */
- RemoveEntryList(&EventEntry->Entry);
-
- /* free event entry */
- FreeItem(EventEntry);
-
- /* done */
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- }
-
- /* move to next */
- Entry = Entry->Flink;
- }
-
- /* no event entry available */
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-ULONG
-WdmAudGetMixerDeviceCount()
-{
- return MMixerGetCount(&MixerContext);
-}
-
-ULONG
-WdmAudGetWaveInDeviceCount()
-{
- return MMixerGetWaveInCount(&MixerContext);
-}
-
-ULONG
-WdmAudGetWaveOutDeviceCount()
-{
- return MMixerGetWaveOutCount(&MixerContext);
-}
-
-ULONG
-WdmAudGetMidiInDeviceCount()
-{
- return MMixerGetMidiInCount(&MixerContext);
-}
-
-ULONG
-WdmAudGetMidiOutDeviceCount()
-{
- return MMixerGetWaveOutCount(&MixerContext);
-}
-
-NTSTATUS
-WdmAudGetPnpNameByIndexAndType(
- IN ULONG DeviceIndex,
- IN SOUND_DEVICE_TYPE DeviceType,
- OUT LPWSTR *DevicePath)
-{
- if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
- {
- if (MMixerGetWaveDevicePath(&MixerContext, DeviceType == WAVE_IN_DEVICE_TYPE, DeviceIndex, DevicePath) == MM_STATUS_SUCCESS)
- return STATUS_SUCCESS;
- else
- return STATUS_UNSUCCESSFUL;
- }
- else if (DeviceType == MIDI_IN_DEVICE_TYPE || DeviceType == MIDI_OUT_DEVICE_TYPE)
- {
- if (MMixerGetMidiDevicePath(&MixerContext, DeviceType == MIDI_IN_DEVICE_TYPE, DeviceIndex, DevicePath) == MM_STATUS_SUCCESS)
- return STATUS_SUCCESS;
- else
- return STATUS_UNSUCCESSFUL;
- }
- else if (DeviceType == MIXER_DEVICE_TYPE)
- {
- UNIMPLEMENTED;
- }
-
- return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-WdmAudWaveCapabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
-{
- MIXER_STATUS Status = MM_STATUS_UNSUCCESSFUL;
-
- if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
- {
- /* get capabilities */
- Status = MMixerWaveInCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.WaveInCaps);
- }
- else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
- {
- /* get capabilities */
- Status = MMixerWaveOutCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.WaveOutCaps);
- }
-
- if (Status == MM_STATUS_SUCCESS)
- return STATUS_SUCCESS;
- else
- return Status;
-}
-
-NTSTATUS
-WdmAudMidiCapabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
-{
- MIXER_STATUS Status = MM_STATUS_UNSUCCESSFUL;
-
- if (DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE)
- {
- /* get capabilities */
- Status = MMixerMidiInCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.MidiInCaps);
- }
- else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
- {
- /* get capabilities */
- Status = MMixerMidiOutCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.MidiOutCaps);
- }
-
- if (Status == MM_STATUS_SUCCESS)
- return STATUS_SUCCESS;
- else
- return STATUS_UNSUCCESSFUL;
-}
-
-
-MIXER_STATUS
-CreatePinCallback(
- IN PVOID Ctx,
- IN ULONG VirtualDeviceId,
- IN ULONG PinId,
- IN HANDLE hFilter,
- IN PKSPIN_CONNECT PinConnect,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE PinHandle)
-{
- ULONG BytesReturned;
- SYSAUDIO_INSTANCE_INFO InstanceInfo;
- NTSTATUS Status;
- ULONG FreeIndex;
- PPIN_CREATE_CONTEXT Context = (PPIN_CREATE_CONTEXT)Ctx;
-
- /* setup property request */
- InstanceInfo.Property.Set = KSPROPSETID_Sysaudio;
- InstanceInfo.Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO;
- InstanceInfo.Property.Flags = KSPROPERTY_TYPE_SET;
- InstanceInfo.Flags = 0;
- InstanceInfo.DeviceNumber = VirtualDeviceId;
-
- /* attach to virtual device */
- Status = KsSynchronousIoControlDevice(Context->DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned);
-
- if (!NT_SUCCESS(Status))
- return MM_STATUS_UNSUCCESSFUL;
-
- /* close existing pin */
- FreeIndex = ClosePin(Context->ClientInfo, VirtualDeviceId, PinId, Context->DeviceType);
-
- /* now create the pin */
- Status = KsCreatePin(Context->DeviceExtension->hSysAudio, PinConnect, DesiredAccess, PinHandle);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- return MM_STATUS_UNSUCCESSFUL;
-
- /* store the handle */
- Status = InsertPinHandle(Context->ClientInfo, VirtualDeviceId, PinId, Context->DeviceType, *PinHandle, FreeIndex);
- if (!NT_SUCCESS(Status))
- {
- /* failed to insert handle */
- ZwClose(*PinHandle);
- return MM_STATUS_UNSUCCESSFUL;
- }
-
- return MM_STATUS_SUCCESS;
-}
-
-NTSTATUS
-WdmAudControlOpenWave(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- MIXER_STATUS Status;
- PIN_CREATE_CONTEXT Context;
-
- Context.ClientInfo = ClientInfo;
- Context.DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- Context.DeviceType = DeviceInfo->DeviceType;
-
- Status = MMixerOpenWave(&MixerContext, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE, &DeviceInfo->u.WaveFormatEx, CreatePinCallback, &Context, &DeviceInfo->hDevice);
-
- if (Status == MM_STATUS_SUCCESS)
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- else
- return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-WdmAudControlOpenMidi(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- MIXER_STATUS Status;
- PIN_CREATE_CONTEXT Context;
-
- Context.ClientInfo = ClientInfo;
- Context.DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- Context.DeviceType = DeviceInfo->DeviceType;
-
- Status = MMixerOpenMidi(&MixerContext, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE, CreatePinCallback, &Context, &DeviceInfo->hDevice);
-
- if (Status == MM_STATUS_SUCCESS)
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- else
- return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
-}
-
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/legacy/wdmaud/sup.c
- * PURPOSE: Misc support routines
- * PROGRAMMER: Andrew Greenwood
- * Johannes Anderwald
- */
-#include "wdmaud.h"
-
-PVOID
-AllocateItem(
- IN POOL_TYPE PoolType,
- IN SIZE_T NumberOfBytes)
-{
- PVOID Item = ExAllocatePool(PoolType, NumberOfBytes);
- if (!Item)
- return Item;
-
- RtlZeroMemory(Item, NumberOfBytes);
- return Item;
-}
-
-VOID
-FreeItem(
- IN PVOID Item)
-{
- ExFreePool(Item);
-}
-
-
-
-ULONG
-GetSysAudioDeviceCount(
- IN PDEVICE_OBJECT DeviceObject)
-{
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- KSPROPERTY Pin;
- ULONG Count, BytesReturned;
- NTSTATUS Status;
-
- /* setup the query request */
- Pin.Set = KSPROPSETID_Sysaudio;
- Pin.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
- Pin.Flags = KSPROPERTY_TYPE_GET;
-
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- /* query sysaudio for the device count */
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
- if (!NT_SUCCESS(Status))
- return 0;
-
- return Count;
-}
-
-
-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;
-
-}
-
-ULONG
-ClosePin(
- IN PWDMAUD_CLIENT ClientInfo,
- IN ULONG FilterId,
- IN ULONG PinId,
- IN SOUND_DEVICE_TYPE DeviceType)
-{
- ULONG Index;
-
- for(Index = 0; Index < ClientInfo->NumPins; Index++)
- {
- if (ClientInfo->hPins[Index].FilterId == FilterId && ClientInfo->hPins[Index].PinId == PinId && ClientInfo->hPins[Index].Handle && ClientInfo->hPins[Index].Type == DeviceType)
- {
- if (ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
- {
- ZwClose(ClientInfo->hPins[Index].Handle);
- }
- ClientInfo->hPins[Index].Handle = NULL;
- return Index;
- }
- }
- return MAXULONG;
-}
-
-NTSTATUS
-InsertPinHandle(
- IN PWDMAUD_CLIENT ClientInfo,
- IN ULONG FilterId,
- IN ULONG PinId,
- IN SOUND_DEVICE_TYPE DeviceType,
- IN HANDLE PinHandle,
- IN ULONG FreeIndex)
-{
- PWDMAUD_HANDLE Handles;
-
- if (FreeIndex != MAXULONG)
- {
- /* re-use a free index */
- ClientInfo->hPins[FreeIndex].Handle = PinHandle;
- ClientInfo->hPins[FreeIndex].FilterId = FilterId;
- ClientInfo->hPins[FreeIndex].PinId = PinId;
- ClientInfo->hPins[FreeIndex].Type = DeviceType;
-
- return STATUS_SUCCESS;
- }
-
- Handles = AllocateItem(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1));
-
- if (!Handles)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- if (ClientInfo->NumPins)
- {
- RtlMoveMemory(Handles, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins);
- FreeItem(ClientInfo->hPins);
- }
-
- ClientInfo->hPins = Handles;
- ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
- ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceType;
- ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId;
- ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId;
- ClientInfo->NumPins++;
-
- return STATUS_SUCCESS;
-}
-
-PKEY_VALUE_PARTIAL_INFORMATION
-ReadKeyValue(
- IN HANDLE hSubKey,
- IN PUNICODE_STRING KeyName)
-{
- NTSTATUS Status;
- ULONG Length;
- PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
-
- /* now query MatchingDeviceId key */
- Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, NULL, 0, &Length);
-
- /* check for success */
- if (Status != STATUS_BUFFER_TOO_SMALL)
- return NULL;
-
- /* allocate a buffer for key data */
- PartialInformation = AllocateItem(NonPagedPool, Length);
-
- if (!PartialInformation)
- return NULL;
-
-
- /* now query MatchingDeviceId key */
- Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, PartialInformation, Length, &Length);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- FreeItem(PartialInformation);
- return NULL;
- }
-
- if (PartialInformation->Type != REG_SZ)
- {
- /* invalid key type */
- FreeItem(PartialInformation);
- return NULL;
- }
-
- return PartialInformation;
-}
-
-
-NTSTATUS
-CompareProductName(
- IN HANDLE hSubKey,
- IN LPWSTR PnpName,
- IN ULONG ProductNameSize,
- OUT LPWSTR ProductName)
-{
- PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
- UNICODE_STRING DriverDescName = RTL_CONSTANT_STRING(L"DriverDesc");
- UNICODE_STRING MatchingDeviceIdName = RTL_CONSTANT_STRING(L"MatchingDeviceId");
- ULONG Length;
- LPWSTR DeviceName;
-
- /* read MatchingDeviceId value */
- PartialInformation = ReadKeyValue(hSubKey, &MatchingDeviceIdName);
-
- if (!PartialInformation)
- return STATUS_UNSUCCESSFUL;
-
-
- /* extract last '&' */
- DeviceName = wcsrchr((LPWSTR)PartialInformation->Data, L'&');
- ASSERT(DeviceName);
- /* terminate it */
- DeviceName[0] = L'\0';
-
- Length = wcslen((LPWSTR)PartialInformation->Data);
-
- DPRINT("DeviceName %S PnpName %S Length %u\n", (LPWSTR)PartialInformation->Data, PnpName, Length);
-
- if (_wcsnicmp((LPWSTR)PartialInformation->Data, &PnpName[4], Length))
- {
- FreeItem(PartialInformation);
- return STATUS_NO_MATCH;
- }
-
- /* free buffer */
- FreeItem(PartialInformation);
-
- /* read DriverDescName value */
- PartialInformation = ReadKeyValue(hSubKey, &DriverDescName);
-
- if (!PartialInformation)
- {
- /* failed to read driver desc key */
- return STATUS_UNSUCCESSFUL;
- }
-
- /* copy key name */
- Length = min(ProductNameSize * sizeof(WCHAR), PartialInformation->DataLength);
- RtlMoveMemory(ProductName, (PVOID)PartialInformation->Data, Length);
-
- /* zero terminate it */
- ProductName[ProductNameSize-1] = L'\0';
-
- /* free buffer */
- FreeItem(PartialInformation);
-
- return STATUS_SUCCESS;
-}
-
-
-
-NTSTATUS
-FindProductName(
- IN LPWSTR PnpName,
- IN ULONG ProductNameSize,
- OUT LPWSTR ProductName)
-{
- UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E96C-E325-11CE-BFC1-08002BE10318}");
-
- UNICODE_STRING SubKeyName;
- WCHAR SubKey[20];
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE hKey, hSubKey;
- NTSTATUS Status;
- ULONG Length, Index;
- PKEY_FULL_INFORMATION KeyInformation;
-
- for(Index = 0; Index < wcslen(PnpName); Index++)
- {
- if (PnpName[Index] == '#')
- PnpName[Index] = L'\\';
- }
-
-
- /* initialize key attributes */
- InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, NULL, NULL);
-
- /* open the key */
- Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- return Status;
-
- /* query num of subkeys */
- Status = ZwQueryKey(hKey, KeyFullInformation, NULL, 0, &Length);
-
- if (Status != STATUS_BUFFER_TOO_SMALL)
- {
- DPRINT1("ZwQueryKey failed with %x\n", Status);
- /* failed */
- ZwClose(hKey);
- return Status;
- }
-
- /* allocate key information struct */
- KeyInformation = AllocateItem(NonPagedPool, Length);
- if (!KeyInformation)
- {
- /* no memory */
- ZwClose(hKey);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* query num of subkeys */
- Status = ZwQueryKey(hKey, KeyFullInformation, (PVOID)KeyInformation, Length, &Length);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ZwQueryKey failed with %x\n", Status);
- FreeItem(KeyInformation);
- ZwClose(hKey);
- return Status;
- }
-
- /* now iterate through all subkeys */
- for(Index = 0; Index < KeyInformation->SubKeys; Index++)
- {
- /* subkeys are always in the format 0000-XXXX */
- swprintf(SubKey, L"%04u", Index);
-
- /* initialize subkey name */
- RtlInitUnicodeString(&SubKeyName, SubKey);
-
- /* initialize key attributes */
- InitializeObjectAttributes(&ObjectAttributes, &SubKeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, hKey, NULL);
-
- /* open the sub key */
- Status = ZwOpenKey(&hSubKey, GENERIC_READ, &ObjectAttributes);
-
- /* check for success */
- if (NT_SUCCESS(Status))
- {
- /* compare product name */
- Status = CompareProductName(hSubKey, PnpName, ProductNameSize, ProductName);
-
- /* close subkey */
- ZwClose(hSubKey);
-
- if (NT_SUCCESS(Status))
- break;
- }
- }
-
- /* free buffer */
- FreeItem(KeyInformation);
-
- /* close key */
- ZwClose(hKey);
-
- /* no matching key found */
- return Status;
-}
-
-NTSTATUS
-GetSysAudioDevicePnpName(
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG DeviceIndex,
- OUT LPWSTR * Device)
-{
- ULONG BytesReturned;
- KSP_PIN Pin;
- NTSTATUS Status;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
-
- /* first check if the device index is within bounds */
- if (DeviceIndex >= GetSysAudioDeviceCount(DeviceObject))
- return STATUS_INVALID_PARAMETER;
-
- /* setup the query request */
- Pin.Property.Set = KSPROPSETID_Sysaudio;
- Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME;
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
- Pin.PinId = DeviceIndex;
-
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- /* query sysaudio for the device path */
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), NULL, 0, &BytesReturned);
-
- /* check if the request failed */
- if (Status != STATUS_BUFFER_TOO_SMALL || BytesReturned == 0)
- return STATUS_UNSUCCESSFUL;
-
- /* allocate buffer for the device */
- *Device = AllocateItem(NonPagedPool, BytesReturned);
- if (!Device)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* query sysaudio again for the device path */
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), (PVOID)*Device, BytesReturned, &BytesReturned);
-
- if (!NT_SUCCESS(Status))
- {
- /* failed */
- FreeItem(*Device);
- return Status;
- }
-
- return Status;
-}
-
-NTSTATUS
-OpenDevice(
- IN LPWSTR Device,
- OUT PHANDLE DeviceHandle,
- OUT PFILE_OBJECT * FileObject)
-{
- NTSTATUS Status;
- HANDLE hDevice;
-
- /* now open the device */
- Status = WdmAudOpenSysAudioDevice(Device, &hDevice);
-
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- *DeviceHandle = hDevice;
-
- if (FileObject)
- {
- Status = ObReferenceObjectByHandle(hDevice, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)FileObject, NULL);
-
- if (!NT_SUCCESS(Status))
- {
- ZwClose(hDevice);
- }
- }
-
- return Status;
-
-}
+++ /dev/null
-#pragma once
-
-#include <pseh/pseh2.h>
-#include <ntddk.h>
-#include <portcls.h>
-#include <ks.h>
-#define NDEBUG
-#include <debug.h>
-#include <ksmedia.h>
-#include <mmreg.h>
-#include <mmsystem.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <wchar.h>
-#include "mmixer.h"
-
-#include "interface.h"
-
-typedef struct
-{
- PMDL Mdl;
- ULONG Length;
- ULONG Function;
-}WDMAUD_COMPLETION_CONTEXT, *PWDMAUD_COMPLETION_CONTEXT;
-
-
-typedef struct
-{
- HANDLE Handle;
- SOUND_DEVICE_TYPE Type;
- ULONG FilterId;
- ULONG PinId;
- PRKEVENT NotifyEvent;
-}WDMAUD_HANDLE, *PWDMAUD_HANDLE;
-
-typedef struct
-{
- LIST_ENTRY Entry;
- HANDLE hProcess;
- ULONG NumPins;
- WDMAUD_HANDLE * hPins;
-
- LIST_ENTRY MixerEventList;
-}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
-
-typedef struct
-{
- LIST_ENTRY Entry;
- ULONG NotificationType;
- ULONG Value;
- HANDLE hMixer;
-}EVENT_ENTRY, *PEVENT_ENTRY;
-
-typedef struct
-{
- LIST_ENTRY Entry;
- UNICODE_STRING SymbolicLink;
-}SYSAUDIO_ENTRY, *PSYSAUDIO_ENTRY;
-
-typedef struct
-{
- KSDEVICE_HEADER DeviceHeader;
- PVOID SysAudioNotification;
-
- BOOL DeviceInterfaceSupport;
-
- KSPIN_LOCK Lock;
- ULONG NumSysAudioDevices;
- LIST_ENTRY SysAudioDeviceList;
- HANDLE hSysAudio;
- PFILE_OBJECT FileObject;
-
- LIST_ENTRY WdmAudClientList;
-}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
-
-typedef struct
-{
- PWDMAUD_CLIENT ClientInfo;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- SOUND_DEVICE_TYPE DeviceType;
-}PIN_CREATE_CONTEXT, *PPIN_CREATE_CONTEXT;
-
-
-NTSTATUS
-NTAPI
-OpenWavePin(
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
- IN ULONG FilterId,
- IN ULONG PinId,
- IN LPWAVEFORMATEX WaveFormatEx,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE PinHandle);
-
-NTSTATUS
-WdmAudRegisterDeviceInterface(
- IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
-
-NTSTATUS
-WdmAudOpenSysAudioDevices(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
-
-NTSTATUS
-WdmAudOpenSysaudio(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_CLIENT *pClient);
-
-NTSTATUS
-NTAPI
-WdmAudDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-NTSTATUS
-NTAPI
-WdmAudReadWrite(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-NTSTATUS
-NTAPI
-WdmAudWrite(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-NTSTATUS
-WdmAudControlOpenMixer(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo);
-
-NTSTATUS
-WdmAudControlOpenWave(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo);
-
-NTSTATUS
-WdmAudControlOpenMidi(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo);
-
-ULONG
-GetNumOfMixerDevices(
- IN PDEVICE_OBJECT DeviceObject);
-
-NTSTATUS
-SetIrpIoStatus(
- IN PIRP Irp,
- IN NTSTATUS Status,
- IN ULONG Length);
-
-NTSTATUS
-WdmAudOpenSysAudioDevice(
- IN LPWSTR DeviceName,
- OUT PHANDLE Handle);
-
-NTSTATUS
-FindProductName(
- IN LPWSTR PnpName,
- IN ULONG ProductNameSize,
- OUT LPWSTR ProductName);
-
-NTSTATUS
-WdmAudMixerCapabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
-
-NTSTATUS
-WdmAudWaveCapabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
-
-NTSTATUS
-WdmAudMidiCapabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo,
- IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
-
-NTSTATUS
-NTAPI
-WdmAudFrameSize(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo);
-
-NTSTATUS
-NTAPI
-WdmAudGetLineInfo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo);
-
-NTSTATUS
-NTAPI
-WdmAudGetLineControls(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo);
-
-NTSTATUS
-NTAPI
-WdmAudSetControlDetails(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo);
-
-NTSTATUS
-NTAPI
-WdmAudGetMixerEvent(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo);
-
-NTSTATUS
-NTAPI
-WdmAudGetControlDetails(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo);
-
-NTSTATUS
-WdmAudMixerInitialize(
- IN PDEVICE_OBJECT DeviceObject);
-
-NTSTATUS
-NTAPI
-WdmAudWaveInitialize(
- IN PDEVICE_OBJECT DeviceObject);
-
-ULONG
-ClosePin(
- IN PWDMAUD_CLIENT ClientInfo,
- IN ULONG FilterId,
- IN ULONG PinId,
- IN SOUND_DEVICE_TYPE DeviceType);
-
-NTSTATUS
-InsertPinHandle(
- IN PWDMAUD_CLIENT ClientInfo,
- IN ULONG FilterId,
- IN ULONG PinId,
- IN SOUND_DEVICE_TYPE DeviceType,
- IN HANDLE PinHandle,
- IN ULONG FreeIndex);
-
-NTSTATUS
-GetSysAudioDevicePnpName(
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG DeviceIndex,
- OUT LPWSTR * Device);
-
-NTSTATUS
-OpenSysAudioDeviceByIndex(
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG DeviceIndex,
- IN PHANDLE DeviceHandle,
- IN PFILE_OBJECT * FileObject);
-
-NTSTATUS
-OpenDevice(
- IN LPWSTR Device,
- OUT PHANDLE DeviceHandle,
- OUT PFILE_OBJECT * FileObject);
-
-ULONG
-WdmAudGetMixerDeviceCount();
-
-ULONG
-WdmAudGetWaveInDeviceCount();
-
-ULONG
-WdmAudGetWaveOutDeviceCount();
-
-ULONG
-WdmAudGetMidiInDeviceCount();
-
-ULONG
-WdmAudGetMidiOutDeviceCount();
-
-NTSTATUS
-WdmAudGetPnpNameByIndexAndType(
- IN ULONG DeviceIndex,
- IN SOUND_DEVICE_TYPE DeviceType,
- OUT LPWSTR *Device);
-
-
-/* sup.c */
-
-ULONG
-GetSysAudioDeviceCount(
- IN PDEVICE_OBJECT DeviceObject);
-
-
-PVOID
-AllocateItem(
- IN POOL_TYPE PoolType,
- IN SIZE_T NumberOfBytes);
-
-VOID
-FreeItem(
- IN PVOID Item);
-
+++ /dev/null
-<?xml version="1.0"?>
-<!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd">
-<module name="wdmaud_kernel" type="kernelmodedriver" installbase="system32/drivers" installname="wdmaud.sys">
- <include base="wdmaud_kernel">.</include>
- <include base="mmixer">.</include>
- <include base="ReactOS">include/reactos/libs/sound</include>
- <define name="_COMDDK_" />
- <library>mmixer</library>
- <library>ntoskrnl</library>
- <library>libcntpr</library>
- <library>ks</library>
- <library>pseh</library>
- <library>hal</library>
- <file>control.c</file>
- <file>deviface.c</file>
- <file>entry.c</file>
- <file>mmixer.c</file>
- <file>sup.c</file>
- <file>wdmaud.rc</file>
-</module>
+++ /dev/null
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION "Reactos audio mapper driver\0"
-#define REACTOS_STR_INTERNAL_NAME "wdmaud\0"
-#define REACTOS_STR_ORIGINAL_FILENAME "wdmaud.sys\0"
-#include <reactos/version.rc>
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/sysaudio/control.c
- * PURPOSE: System Audio graph builder
- * PROGRAMMER: Johannes Anderwald
- */
-
-#include "sysaudio.h"
-
-const GUID KSPROPSETID_Sysaudio = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
-const GUID KSPROPSETID_Sysaudio_Pin = {0xA3A53220L, 0xC6E4, 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 KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
-const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
-const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {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;
- if (Status != STATUS_PENDING)
- {
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
- else
- {
- IoMarkIrpPending(Irp);
- }
- return Status;
-
-}
-
-PKSAUDIO_DEVICE_ENTRY
-GetListEntry(
- IN PLIST_ENTRY Head,
- IN ULONG Index)
-{
- PLIST_ENTRY Entry = Head->Flink;
-
- while(Index-- && Entry != Head)
- Entry = Entry->Flink;
-
- if (Entry == Head)
- return NULL;
-
- return (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
-}
-
-NTSTATUS
-SysAudioOpenVirtualDevice(
- IN PIRP Irp,
- IN ULONG DeviceNumber,
- PSYSAUDIODEVEXT DeviceExtension)
-{
- PKSAUDIO_DEVICE_ENTRY Entry;
- PIO_STACK_LOCATION IoStack;
-
- /* get current irp stack */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* sanity check */
- ASSERT(IoStack->FileObject);
-
- if (DeviceNumber >= DeviceExtension->NumberOfKsAudioDevices)
- {
- /* invalid device index */
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
-
- /* get device context */
- Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber);
- ASSERT(Entry != NULL);
-
- /* store device entry in FsContext
- * see pin.c DispatchCreateSysAudioPin for details
- */
- IoStack->FileObject->FsContext = (PVOID)Entry;
-
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
-}
-
-NTSTATUS
-HandleSysAudioFilterPinProperties(
- PIRP Irp,
- PKSPROPERTY Property,
- PSYSAUDIODEVEXT DeviceExtension)
-{
- PIO_STACK_LOCATION IoStack;
- NTSTATUS Status;
- PKSAUDIO_DEVICE_ENTRY Entry;
- ULONG BytesReturned;
-
- // in order to access pin properties of a sysaudio device
- // the caller must provide a KSP_PIN struct, where
- // Reserved member points to virtual device index
-
- IoStack = IoGetCurrentIrpStackLocation(Irp);
- if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_PIN))
- {
- /* too small buffer */
- return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY) + sizeof(ULONG));
- }
-
- Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, ((KSP_PIN*)Property)->Reserved);
- if (!Entry)
- {
- /* invalid device index */
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
-
- /* forward request to the filter implementing the property */
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY,
- (PVOID)IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
- IoStack->Parameters.DeviceIoControl.InputBufferLength,
- Irp->UserBuffer,
- IoStack->Parameters.DeviceIoControl.OutputBufferLength,
- &BytesReturned);
-
- return SetIrpIoStatus(Irp, Status, BytesReturned);
-}
-
-
-NTSTATUS
-ComputeCompatibleFormat(
- IN PKSAUDIO_DEVICE_ENTRY Entry,
- IN ULONG PinId,
- IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
- OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat)
-{
- BOOL bFound;
- ULONG BytesReturned;
- PKSP_PIN PinRequest;
- NTSTATUS Status;
- PKSMULTIPLE_ITEM MultipleItem;
- ULONG Length;
- PKSDATARANGE_AUDIO AudioRange;
- ULONG Index;
-
- Length = sizeof(KSP_PIN) + sizeof(KSMULTIPLE_ITEM) + ClientFormat->DataFormat.FormatSize;
- PinRequest = AllocateItem(NonPagedPool, Length);
- if (!PinRequest)
- return STATUS_UNSUCCESSFUL;
-
- PinRequest->PinId = PinId;
- PinRequest->Property.Set = KSPROPSETID_Pin;
- PinRequest->Property.Flags = KSPROPERTY_TYPE_GET;
- PinRequest->Property.Id = KSPROPERTY_PIN_DATAINTERSECTION;
-
- MultipleItem = (PKSMULTIPLE_ITEM)(PinRequest + 1);
- MultipleItem->Count = 1;
- MultipleItem->Size = ClientFormat->DataFormat.FormatSize;
-
- RtlMoveMemory(MultipleItem + 1, ClientFormat, ClientFormat->DataFormat.FormatSize);
- /* Query the miniport data intersection handler */
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)PinRequest, Length, (PVOID)MixerFormat, sizeof(KSDATAFORMAT_WAVEFORMATEX), &BytesReturned);
-
- DPRINT("Status %x\n", Status);
-
- if (NT_SUCCESS(Status))
- {
- FreeItem(PinRequest);
- return Status;
- }
-
- /* Setup request block */
- PinRequest->Property.Id = KSPROPERTY_PIN_DATARANGES;
- /* Query pin data ranges */
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)PinRequest, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
-
- if (Status != STATUS_MORE_ENTRIES)
- {
- /* Failed to get data ranges */
- return Status;
- }
-
- MultipleItem = AllocateItem(NonPagedPool, BytesReturned);
- if (!MultipleItem)
- {
- FreeItem(PinRequest);
- return STATUS_NO_MEMORY;
- }
-
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)PinRequest, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Property Request KSPROPERTY_PIN_DATARANGES failed with %x\n", Status);
- FreeItem(MultipleItem);
- FreeItem(PinRequest);
- return STATUS_UNSUCCESSFUL;
- }
-
- AudioRange = (PKSDATARANGE_AUDIO)(MultipleItem + 1);
- bFound = FALSE;
- for(Index = 0; Index < MultipleItem->Count; Index++)
- {
- if (AudioRange->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO))
- {
- UNIMPLEMENTED
- AudioRange = (PKSDATARANGE_AUDIO)((PUCHAR)AudioRange + AudioRange->DataRange.FormatSize);
- continue;
- }
- /* Select best quality available */
-
- MixerFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
- MixerFormat->DataFormat.Flags = 0;
- MixerFormat->DataFormat.Reserved = 0;
- MixerFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
- MixerFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- MixerFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
- MixerFormat->DataFormat.SampleSize = 4;
- MixerFormat->WaveFormatEx.wFormatTag = ClientFormat->WaveFormatEx.wFormatTag;
-#ifndef NO_AC97_HACK
- /* HACK: AC97 does not support mono render / record */
- MixerFormat->WaveFormatEx.nChannels = 2;
- /*HACK: AC97 only supports 16-Bit Bits */
- MixerFormat->WaveFormatEx.wBitsPerSample = 16;
-
-#else
- MixerFormat->WaveFormatEx.nChannels = min(ClientFormat->WaveFormatEx.nChannels, AudioRange->MaximumChannels);
- MixerFormat->WaveFormatEx.wBitsPerSample = AudioRange->MaximumBitsPerSample;
-#endif
-
-#ifdef KMIXER_RESAMPLING_IMPLEMENTED
- MixerFormat->WaveFormatEx.nSamplesPerSec = AudioRange->MaximumSampleFrequency;
-#else
- MixerFormat->WaveFormatEx.nSamplesPerSec = max(AudioRange->MinimumSampleFrequency, min(ClientFormat->WaveFormatEx.nSamplesPerSec, AudioRange->MaximumSampleFrequency));
-#endif
-
- MixerFormat->WaveFormatEx.cbSize = 0;
- MixerFormat->WaveFormatEx.nBlockAlign = (MixerFormat->WaveFormatEx.nChannels * MixerFormat->WaveFormatEx.wBitsPerSample) / 8;
- MixerFormat->WaveFormatEx.nAvgBytesPerSec = MixerFormat->WaveFormatEx.nChannels * MixerFormat->WaveFormatEx.nSamplesPerSec * (MixerFormat->WaveFormatEx.wBitsPerSample / 8);
-
- bFound = TRUE;
- break;
-
- AudioRange = (PKSDATARANGE_AUDIO)((PUCHAR)AudioRange + AudioRange->DataRange.FormatSize);
- }
-
-#if 0
- DPRINT1("\nNum Max Channels %u Channels %u Old Channels %u\n Max SampleRate %u SampleRate %u Old SampleRate %u\n Max BitsPerSample %u BitsPerSample %u Old BitsPerSample %u\n",
- AudioRange->MaximumChannels, MixerFormat->WaveFormatEx.nChannels, ClientFormat->WaveFormatEx.nChannels,
- AudioRange->MaximumSampleFrequency, MixerFormat->WaveFormatEx.nSamplesPerSec, ClientFormat->WaveFormatEx.nSamplesPerSec,
- AudioRange->MaximumBitsPerSample, MixerFormat->WaveFormatEx.wBitsPerSample, ClientFormat->WaveFormatEx.wBitsPerSample);
-
-
-#endif
-
- FreeItem(MultipleItem);
- FreeItem(PinRequest);
-
- if (bFound)
- return STATUS_SUCCESS;
- else
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-GetPinInstanceCount(
- PKSAUDIO_DEVICE_ENTRY Entry,
- PKSPIN_CINSTANCES PinInstances,
- PKSPIN_CONNECT PinConnect)
-{
- KSP_PIN PinRequest;
- ULONG BytesReturned;
-
- /* query the instance count */
- PinRequest.PinId = PinConnect->PinId;
- PinRequest.Property.Set = KSPROPSETID_Pin;
- PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
- PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
- ASSERT(Entry->FileObject);
- return KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
-
-}
-
-NTSTATUS
-SysAudioHandleProperty(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
- NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
- KSPROPERTY PropertyRequest;
- KSCOMPONENTID ComponentId;
- PULONG Index;
- PKSPROPERTY Property;
- PSYSAUDIODEVEXT DeviceExtension;
- PKSAUDIO_DEVICE_ENTRY Entry;
- PSYSAUDIO_INSTANCE_INFO InstanceInfo;
- ULONG BytesReturned;
- PKSOBJECT_CREATE_ITEM CreateItem;
- UNICODE_STRING GuidString;
- PKSP_PIN Pin;
- LPWSTR DeviceName;
-
- /* access the create item */
- CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
-
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
- {
- /* buffer must be at least of sizeof KSPROPERTY */
- return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY));
- }
-
- Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
- DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
-
- if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Pin))
- {
- return HandleSysAudioFilterPinProperties(Irp, Property, DeviceExtension);
- }
- else if(IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Topology))
- {
- if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_PIN))
- {
- /* too small buffer */
- return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSP_PIN));
- }
- Pin = (PKSP_PIN)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
- Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, Pin->Reserved);
- ASSERT(Entry != NULL);
-
- /* forward request to the filter implementing the property */
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY,
- (PVOID)IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
- IoStack->Parameters.DeviceIoControl.InputBufferLength,
- Irp->UserBuffer,
- IoStack->Parameters.DeviceIoControl.OutputBufferLength,
- &BytesReturned);
-
- return SetIrpIoStatus(Irp, Status, BytesReturned);
- }
- else if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio))
- {
- if (Property->Id == KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME)
- {
- if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY) + sizeof(ULONG))
- {
- /* invalid request */
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(KSPROPERTY) + sizeof(ULONG));
- }
- Index = (PULONG)(Property + 1);
-
- if (DeviceExtension->NumberOfKsAudioDevices <= *Index)
- {
- /* invalid index */
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
-
- Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, *Index);
- ASSERT(Entry != NULL);
-
- BytesReturned = Entry->DeviceName.Length + sizeof(WCHAR);
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < BytesReturned)
- {
- /* too small buffer */
- return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, BytesReturned);
- }
-
- /* copy device name */
- DeviceName = (LPWSTR)Irp->UserBuffer;
-
- RtlMoveMemory(DeviceName, Entry->DeviceName.Buffer, Entry->DeviceName.Length);
- DeviceName[Entry->DeviceName.Length / sizeof(WCHAR)] = L'\0';
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, BytesReturned);
- }
-
- if (Property->Id == KSPROPERTY_SYSAUDIO_COMPONENT_ID)
- {
- if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY) + sizeof(ULONG))
- {
- /* too small buffer */
- return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY) + sizeof(ULONG));
- }
-
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSCOMPONENTID))
- {
- /* too small buffer */
- return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSCOMPONENTID));
- }
-
- Index = (PULONG)(Property + 1);
-
- if (DeviceExtension->NumberOfKsAudioDevices <= *Index)
- {
- /* invalid index */
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
- Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, *Index);
- ASSERT(Entry != NULL);
-
- PropertyRequest.Set = KSPROPSETID_General;
- PropertyRequest.Id = KSPROPERTY_GENERAL_COMPONENTID;
- PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
-
- /* call the filter */
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("KsSynchronousIoControlDevice failed with %x for KSPROPERTY_GENERAL_COMPONENTID\n", Status);
- return SetIrpIoStatus(Irp, Status, 0);
- }
- RtlMoveMemory(Irp->UserBuffer, &ComponentId, sizeof(KSCOMPONENTID));
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(KSCOMPONENTID));
- }
- else if (Property->Id == KSPROPERTY_SYSAUDIO_DEVICE_COUNT)
- {
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
- {
- /* too small buffer */
- return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG));
- }
-
- *((PULONG)Irp->UserBuffer) = DeviceExtension->NumberOfKsAudioDevices;
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
- }
- else if (Property->Id == KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE)
- {
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
- {
- /* too small buffer */
- return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG));
- }
-
- if (Property->Flags & KSPROPERTY_TYPE_SET)
- {
- Index = (PULONG)Irp->UserBuffer;
- return SysAudioOpenVirtualDevice(Irp, *Index, DeviceExtension);
- }
- }
- else if (Property->Id == KSPROPERTY_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));
- }
-
- /* get input parameter */
- InstanceInfo = (PSYSAUDIO_INSTANCE_INFO)Property;
-
- if (Property->Flags & KSPROPERTY_TYPE_SET)
- {
- return SysAudioOpenVirtualDevice(Irp, InstanceInfo->DeviceNumber, DeviceExtension);
- }
- }
- }
-
- RtlStringFromGUID(&Property->Set, &GuidString);
- DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
- RtlFreeUnicodeString(&GuidString);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-}
+++ /dev/null
-/*
- * 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 "sysaudio.h"
-
-const GUID GUID_DEVICE_INTERFACE_ARRIVAL = {0xCB3A4004L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
-const GUID GUID_DEVICE_INTERFACE_REMOVAL = {0xCB3A4005L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
-const GUID KS_CATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
-const GUID KS_CATEGORY_TOPOLOGY = {0xDDA54A40, 0x1E4C, 0x11D1, {0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00}};
-const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
-
-NTSTATUS
-OpenDevice(
- IN PUNICODE_STRING DeviceName,
- IN PHANDLE HandleOut,
- IN PFILE_OBJECT * FileObjectOut)
-{
- NTSTATUS Status;
- HANDLE NodeHandle;
- PFILE_OBJECT FileObject;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
-
- InitializeObjectAttributes(&ObjectAttributes, DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- Status = ZwCreateFile(&NodeHandle,
- GENERIC_READ | GENERIC_WRITE,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- 0,
- 0,
- FILE_OPEN,
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0);
-
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwCreateFile failed with %x %S\n", Status, DeviceName->Buffer);
- return Status;
- }
-
- Status = ObReferenceObjectByHandle(NodeHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- ZwClose(NodeHandle);
- DPRINT("ObReferenceObjectByHandle failed with %x\n", Status);
- return Status;
- }
-
- *HandleOut = NodeHandle;
- *FileObjectOut = FileObject;
- return Status;
-}
-
-NTSTATUS
-InsertAudioDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PUNICODE_STRING DeviceName)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- PSYSAUDIODEVEXT DeviceExtension;
- PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL;
-
- /* a new device has arrived */
- DeviceEntry = AllocateItem(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
- if (!DeviceEntry)
- {
- /* no memory */
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* initialize audio device entry */
- RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY));
-
- /* set device name */
- DeviceEntry->DeviceName.Length = 0;
- DeviceEntry->DeviceName.MaximumLength = DeviceName->MaximumLength + 10 * sizeof(WCHAR);
-
- DeviceEntry->DeviceName.Buffer = AllocateItem(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
-
- if (!DeviceEntry->DeviceName.Buffer)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto cleanup;
- }
-
- RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\");
- RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, DeviceName);
-
- Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject);
-
- if (!NT_SUCCESS(Status))
- {
- goto cleanup;
- }
-
- /* fetch device extension */
- DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
- /* insert new audio device */
- ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock);
- InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices);
-
- DPRINT("Successfully opened audio device %u Device %S\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->DeviceName.Buffer);
- return Status;
-
-cleanup:
- if (DeviceEntry)
- {
- if (DeviceEntry->DeviceName.Buffer)
- FreeItem(DeviceEntry->DeviceName.Buffer);
-
- FreeItem(DeviceEntry);
- }
-
- return Status;
-
-}
-
-
-NTSTATUS
-NTAPI
-DeviceInterfaceChangeCallback(
- IN PVOID NotificationStructure,
- IN PVOID Context)
-{
- DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
- NTSTATUS Status = STATUS_SUCCESS;
- PSYSAUDIODEVEXT DeviceExtension;
- PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
-
- DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
-
- Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
-
- if (IsEqualGUIDAligned(&Event->Event,
- &GUID_DEVICE_INTERFACE_ARRIVAL))
- {
- Status = InsertAudioDevice(DeviceObject, Event->SymbolicLinkName);
- return Status;
- }
- else
- {
- DPRINT("Remove interface to audio device!\n");
- UNIMPLEMENTED
- return STATUS_SUCCESS;
- }
-
-
-}
-
-NTSTATUS
-SysAudioRegisterNotifications(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT DeviceObject)
-{
- NTSTATUS Status;
- PSYSAUDIODEVEXT DeviceExtension;
-
- DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
-
- Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
- PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
- (PVOID)&KS_CATEGORY_AUDIO,
- DriverObject,
- DeviceInterfaceChangeCallback,
- (PVOID)DeviceObject,
- (PVOID*)&DeviceExtension->KsAudioNotificationEntry);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoRegisterPlugPlayNotification failed with %x\n", Status);
- }
-
- Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
- PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
- (PVOID)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,
- DriverObject,
- DeviceInterfaceChangeCallback,
- (PVOID)DeviceObject,
- (PVOID*)&DeviceExtension->EchoCancelNotificationEntry);
-
- if (!NT_SUCCESS(Status))
- {
- /* ignore failure for now */
- DPRINT("IoRegisterPlugPlayNotification failed for DMOCATEGORY_ACOUSTIC_ECHO_CANCEL\n", Status);
- }
-
- return STATUS_SUCCESS;
-}
-
-
-
-NTSTATUS
-SysAudioRegisterDeviceInterfaces(
- IN PDEVICE_OBJECT DeviceObject)
-{
- NTSTATUS Status;
- UNICODE_STRING SymbolicLink;
-
- Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_MIDIOUT_DEVICE, NULL, &SymbolicLink);
- if (NT_SUCCESS(Status))
- {
- IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
- RtlFreeUnicodeString(&SymbolicLink);
- }
- else
- {
- DPRINT("Failed to register KSCATEGORY_PREFERRED_MIDIOUT_DEVICE interface Status %x\n", Status);
- return Status;
- }
-
- Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEIN_DEVICE, NULL, &SymbolicLink);
- if (NT_SUCCESS(Status))
- {
- IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
- RtlFreeUnicodeString(&SymbolicLink);
- }
- else
- {
- DPRINT("Failed to register KSCATEGORY_PREFERRED_WAVEIN_DEVICE interface Status %x\n", Status);
- return Status;
- }
-
- Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEOUT_DEVICE, NULL, &SymbolicLink);
- if (NT_SUCCESS(Status))
- {
- IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
- RtlFreeUnicodeString(&SymbolicLink);
- }
- else
- {
- DPRINT("Failed to register KSCATEGORY_PREFERRED_WAVEOUT_DEVICE interface Status %x\n", Status);
- }
-
- Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_SYSAUDIO, NULL, &SymbolicLink);
- if (NT_SUCCESS(Status))
- {
- IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
- RtlFreeUnicodeString(&SymbolicLink);
- }
- else
- {
- DPRINT("Failed to register KSCATEGORY_SYSAUDIO interface Status %x\n", Status);
- }
-
- return Status;
-}
-
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/sysaudio/dispatcher.c
- * PURPOSE: System Audio graph builder
- * PROGRAMMER: Johannes Anderwald
- */
-
-#include "sysaudio.h"
-
-NTSTATUS
-NTAPI
-Dispatch_fnDeviceIoControl(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
-
- IoStack = IoGetCurrentIrpStackLocation(Irp);
- if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
- {
- return SysAudioHandleProperty(DeviceObject, Irp);
- }
-
- /* unsupported request */
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-NTAPI
-Dispatch_fnClose(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- DPRINT("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-}
-
-static KSDISPATCH_TABLE DispatchTable =
-{
- Dispatch_fnDeviceIoControl,
- KsDispatchInvalidDeviceRequest,
- KsDispatchInvalidDeviceRequest,
- KsDispatchInvalidDeviceRequest,
- Dispatch_fnClose,
- KsDispatchInvalidDeviceRequest,
- KsDispatchInvalidDeviceRequest,
- KsDispatchFastIoDeviceControlFailure,
- KsDispatchFastReadFailure,
- KsDispatchFastWriteFailure,
-};
-
-NTSTATUS
-NTAPI
-DispatchCreateSysAudio(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- NTSTATUS Status;
- KSOBJECT_HEADER ObjectHeader;
- PKSOBJECT_CREATE_ITEM CreateItem;
-
- DPRINT("DispatchCreateSysAudio entered\n");
-
- /* allocate create item */
- CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
- if (!CreateItem)
- {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* zero create struct */
- RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
-
- /* setup create context */
- CreateItem->Create = DispatchCreateSysAudioPin;
- RtlInitUnicodeString(&CreateItem->ObjectClass, KSSTRING_Pin);
-
- /* allocate object header */
- Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
-
- DPRINT("KsAllocateObjectHeader result %x\n", Status);
- /* complete the irp */
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
-}
-
-NTSTATUS
-SysAudioAllocateDeviceHeader(
- IN SYSAUDIODEVEXT *DeviceExtension)
-{
- NTSTATUS Status;
- PKSOBJECT_CREATE_ITEM CreateItem;
-
- /* allocate create item */
- CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
- if (!CreateItem)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* initialize create item struct */
- RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
- CreateItem->Create = DispatchCreateSysAudio;
-
- /* FIXME Sysaudio doesnt need a named create item because it installs itself
- * via the device interface
- */
- RtlInitUnicodeString(&CreateItem->ObjectClass, L"GLOBAL");
- CreateItem->Flags = KSCREATE_ITEM_WILDCARD;
-
- Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
- 1,
- CreateItem);
- return Status;
-}
-
-NTSTATUS
-SysAudioOpenKMixer(
- IN SYSAUDIODEVEXT *DeviceExtension)
-{
- NTSTATUS Status;
- UNICODE_STRING DeviceInstanceName = RTL_CONSTANT_STRING(L"\\Device\\kmixer\\GLOBAL");
- UNICODE_STRING DevicePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\kmixer");
-
- Status = ZwLoadDriver(&DevicePath);
-
- if (NT_SUCCESS(Status))
- {
- Status = OpenDevice(&DeviceInstanceName, &DeviceExtension->KMixerHandle, &DeviceExtension->KMixerFileObject);
- if (!NT_SUCCESS(Status))
- {
- DeviceExtension->KMixerHandle = NULL;
- DeviceExtension->KMixerFileObject = NULL;
- }
- }
-
- DPRINT("Status %lx KMixerHandle %p KMixerFileObject %p\n", Status, DeviceExtension->KMixerHandle, DeviceExtension->KMixerFileObject);
- return STATUS_SUCCESS;
-}
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/sysaudio/main.c
- * PURPOSE: System Audio graph builder
- * PROGRAMMER: Andrew Greenwood
- * Johannes Anderwald
- * HISTORY:
- * 8 Jul 07 Started basic implementation
- */
-
-#include "sysaudio.h"
-
-
-const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
-const GUID KSCATEGORY_AUDIO_DEVICE = {0xFBF6F530L, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
-const GUID KSCATEGORY_PREFERRED_WAVEOUT_DEVICE = {0xD6C5066EL, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
-const GUID KSCATEGORY_PREFERRED_WAVEIN_DEVICE = {0xD6C50671L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
-const GUID KSCATEGORY_PREFERRED_MIDIOUT_DEVICE = {0xD6C50674L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
-
-PVOID
-AllocateItem(
- IN POOL_TYPE PoolType,
- IN SIZE_T NumberOfBytes)
-{
- PVOID Item = ExAllocatePool(PoolType, NumberOfBytes);
- if (!Item)
- return Item;
-
- RtlZeroMemory(Item, NumberOfBytes);
- return Item;
-}
-
-VOID
-FreeItem(
- IN PVOID Item)
-{
- ExFreePool(Item);
-}
-
-
-VOID
-NTAPI
-SysAudio_Unload(IN PDRIVER_OBJECT DriverObject)
-{
- DPRINT("SysAudio_Unload called\n");
-}
-
-NTSTATUS
-NTAPI
-SysAudio_Shutdown(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PKSAUDIO_DEVICE_ENTRY DeviceEntry;
- PSYSAUDIODEVEXT DeviceExtension;
- PLIST_ENTRY Entry;
-
- DPRINT("SysAudio_Shutdown called\n");
-
- DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
-
- while(!IsListEmpty(&DeviceExtension->KsAudioDeviceList))
- {
- Entry = RemoveHeadList(&DeviceExtension->KsAudioDeviceList);
- DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
-
- DPRINT("Freeing item %wZ\n", &DeviceEntry->DeviceName);
-
- /* dereference audio device file object */
- ObDereferenceObject(DeviceEntry->FileObject);
-
- /* close audio device handle */
- ZwClose(DeviceEntry->Handle);
-
- /* free device string */
- RtlFreeUnicodeString(&DeviceEntry->DeviceName);
-
- /* free audio device entry */
- FreeItem(DeviceEntry);
- }
-
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-NTAPI
-SysAudio_Pnp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IrpStack;
- UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio");
- SYSAUDIODEVEXT *DeviceExtension;
-
- /* Get current irp stack */
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* Fetch the device extension */
- DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
- ASSERT(DeviceExtension);
-
- if (IrpStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
- {
- /* Unregister the echo cancel hook */
- if (DeviceExtension->EchoCancelNotificationEntry)
- IoUnregisterPlugPlayNotification(DeviceExtension->EchoCancelNotificationEntry);
-
- /* Unregister the ks audio hook */
- if (DeviceExtension->KsAudioNotificationEntry)
- IoUnregisterPlugPlayNotification(DeviceExtension->KsAudioNotificationEntry);
-
- /* Destroy our symbolic link */
- IoDeleteSymbolicLink(&SymlinkName);
- }
- else if (IrpStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
- {
- /* Sysaudio can not be disabled */
- Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
- }
-
- /* Perform default pnp actions */
- return KsDefaultDispatchPnp(DeviceObject, Irp);
-}
-
-NTSTATUS
-NTAPI
-SysAudio_InstallDevice(
- IN PDRIVER_OBJECT DriverObject)
-{
- NTSTATUS Status;
- UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio");
- UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio");
- PDEVICE_OBJECT DeviceObject;
- SYSAUDIODEVEXT *DeviceExtension;
-
-
- DPRINT("SysAudio_InstallDevice called\n");
-
- /* Create the device */
- Status = IoCreateDevice(DriverObject,
- sizeof(SYSAUDIODEVEXT),
- &DeviceName,
- FILE_DEVICE_KS,
- 0,
- FALSE,
- &DeviceObject);
-
- /* Check for success */
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Failed to create \\Device\\sysaudio !\n");
- return Status;
- }
-
- /* Register device interfaces */
- Status = SysAudioRegisterDeviceInterfaces(DeviceObject);
- if (!NT_SUCCESS(Status))
- {
- /* Failed to register
- * Create a hack interface
- */
- Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
- if (!NT_SUCCESS(Status))
- {
- IoDeleteDevice(DeviceObject);
- DPRINT1("Failed to create sysaudio symlink!\n");
- return Status;
- }
- }
- /* Acquire device extension */
- DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
- /* Initialize device extension */
- RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT));
-
- /* Initialize the mutex */
- KeInitializeSpinLock(&DeviceExtension->Lock);
-
- /* Initialize the ks audio device list */
- InitializeListHead(&DeviceExtension->KsAudioDeviceList);
-
- /* Allocate kernel streaming device header */
- Status = SysAudioAllocateDeviceHeader(DeviceExtension);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
- goto cleanup;
- }
-
- /* Register device notification hooks */
- Status = SysAudioRegisterNotifications(DriverObject,
- DeviceObject);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to register device notifications\n");
- goto cleanup;
- }
-
- /* Load kmixer */
- Status = SysAudioOpenKMixer(DeviceExtension);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("SysAudioOpenKMixer failed with %x\n", Status);
- goto cleanup;
- }
-
- /* set io flags */
- DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
- /* clear initializing flag */
- DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
-
- /* register shutdown notfication */
- IoRegisterShutdownNotification(DeviceObject);
-
-
- /* Done */
- return STATUS_SUCCESS;
-
-cleanup:
-
- if (DeviceExtension->KsAudioNotificationEntry)
- IoUnregisterPlugPlayNotification(DeviceExtension->KsAudioNotificationEntry);
-
- if (DeviceExtension->EchoCancelNotificationEntry)
- IoUnregisterPlugPlayNotification(DeviceExtension->EchoCancelNotificationEntry);
-
- IoDeleteSymbolicLink(&SymlinkName);
- IoDeleteDevice(DeviceObject);
- return Status;
-}
-
-NTSTATUS
-NTAPI
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath)
-{
- DPRINT("System audio graph builder (sysaudio) started\n");
-
- /* Let ks handle these */
- KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE);
- KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
- KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);
- KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
-
- /* Let ks handle these */
- DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
- DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
-
- /* Use provided ks unload function */
- DriverObject->DriverUnload = KsNullDriverUnload;
-
- /* Sysaudio needs to do work on pnp, so handle it */
- DriverObject->MajorFunction[IRP_MJ_PNP] = SysAudio_Pnp;
- DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = SysAudio_Shutdown;
-
- /* Call our initialization function */
- return SysAudio_InstallDevice(DriverObject);
-}
+++ /dev/null
-/*
- * 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 "sysaudio.h"
-
-NTSTATUS
-NTAPI
-Pin_fnDeviceIoControl(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PDISPATCH_CONTEXT Context;
- NTSTATUS Status;
- ULONG BytesReturned;
- PFILE_OBJECT FileObject = NULL;
- PIO_STACK_LOCATION IoStack;
-
- DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject, Irp);
-
- /* Get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* The dispatch context is stored in the FsContext member */
- Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
-
- /* Sanity check */
- ASSERT(Context);
-
- /* acquire real pin file object */
- Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = Status;
- /* Complete the irp */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
-
- /* Re-dispatch the request to the real target pin */
- Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
- IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
- IoStack->Parameters.DeviceIoControl.InputBufferLength,
- Irp->UserBuffer,
- IoStack->Parameters.DeviceIoControl.OutputBufferLength,
- &BytesReturned);
- /* release file object */
- ObDereferenceObject(FileObject);
-
- /* Save status and information */
- Irp->IoStatus.Information = BytesReturned;
- Irp->IoStatus.Status = Status;
- /* Complete the irp */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- /* Done */
- return Status;
-}
-
-
-
-NTSTATUS
-NTAPI
-Pin_fnWrite(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PDISPATCH_CONTEXT Context;
- PIO_STACK_LOCATION IoStack;
- PFILE_OBJECT FileObject;
- NTSTATUS Status;
-
- /* Get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* The dispatch context is stored in the FsContext member */
- Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
-
- /* Sanity check */
- ASSERT(Context);
-
- if (Context->hMixerPin)
- {
- // FIXME
- // call kmixer to convert stream
- UNIMPLEMENTED
- }
-
- /* acquire real pin file object */
- Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("failed\n");
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = Status;
- /* Complete the irp */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
-
- /* skip current irp location */
- IoSkipCurrentIrpStackLocation(Irp);
-
- /* get next stack location */
- IoStack = IoGetNextIrpStackLocation(Irp);
- /* store file object of next device object */
- IoStack->FileObject = FileObject;
- IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
- //ASSERT(Irp->AssociatedIrp.SystemBuffer);
-
- /* now call the driver */
- Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
-
- /* dereference file object */
- ObDereferenceObject(FileObject);
-
- return Status;
-
-}
-
-NTSTATUS
-NTAPI
-Pin_fnClose(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PDISPATCH_CONTEXT Context;
- PIO_STACK_LOCATION IoStack;
-
- //DPRINT("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject, Irp);
-
- /* Get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* The dispatch context is stored in the FsContext member */
- Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
-
- if (Context->Handle)
- {
- ZwClose(Context->Handle);
- }
-
- if (Context->hMixerPin)
- {
- ZwClose(Context->hMixerPin);
- }
-
- FreeItem(Context);
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-}
-
-static KSDISPATCH_TABLE PinTable =
-{
- Pin_fnDeviceIoControl,
- KsDispatchInvalidDeviceRequest,
- Pin_fnWrite,
- KsDispatchInvalidDeviceRequest,
- Pin_fnClose,
- KsDispatchInvalidDeviceRequest,
- KsDispatchInvalidDeviceRequest,
- KsDispatchFastIoDeviceControlFailure,
- KsDispatchFastReadFailure,
- KsDispatchFastWriteFailure,
-};
-
-NTSTATUS
-SetMixerInputOutputFormat(
- IN PFILE_OBJECT FileObject,
- IN PKSDATAFORMAT InputFormat,
- IN PKSDATAFORMAT OutputFormat)
-{
- KSP_PIN PinRequest;
- ULONG BytesReturned;
- NTSTATUS Status;
-
- /* re-using pin */
- PinRequest.Property.Set = KSPROPSETID_Connection;
- PinRequest.Property.Flags = KSPROPERTY_TYPE_SET;
- PinRequest.Property.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
-
- /* set the input format */
- PinRequest.PinId = 0;
- DPRINT("InputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", InputFormat, InputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX));
- Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY,
- (PVOID)&PinRequest,
- sizeof(KSP_PIN),
- (PVOID)InputFormat,
- InputFormat->FormatSize,
- &BytesReturned);
- if (!NT_SUCCESS(Status))
- return Status;
-
- /* set the the output format */
- PinRequest.PinId = 1;
- DPRINT("OutputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", OutputFormat, OutputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX));
- Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY,
- (PVOID)&PinRequest,
- sizeof(KSP_PIN),
- (PVOID)OutputFormat,
- OutputFormat->FormatSize,
- &BytesReturned);
- return Status;
-}
-
-
-NTSTATUS
-CreateMixerPinAndSetFormat(
- IN HANDLE KMixerHandle,
- IN KSPIN_CONNECT *PinConnect,
- IN PKSDATAFORMAT InputFormat,
- IN PKSDATAFORMAT OutputFormat,
- OUT PHANDLE MixerPinHandle)
-{
- NTSTATUS Status;
- HANDLE PinHandle;
- PFILE_OBJECT FileObject = NULL;
-
- Status = KsCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create Mixer Pin with %x\n", Status);
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = ObReferenceObjectByHandle(PinHandle,
- GENERIC_READ | GENERIC_WRITE,
- IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get file object with %x\n", Status);
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = SetMixerInputOutputFormat(FileObject, InputFormat, OutputFormat);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(FileObject);
- ZwClose(PinHandle);
- return Status;
- }
-
- ObDereferenceObject(FileObject);
-
- *MixerPinHandle = PinHandle;
- return Status;
-}
-
-
-NTSTATUS
-NTAPI
-InstantiatePins(
- IN PKSAUDIO_DEVICE_ENTRY DeviceEntry,
- IN PKSPIN_CONNECT Connect,
- IN PDISPATCH_CONTEXT DispatchContext,
- IN PSYSAUDIODEVEXT DeviceExtension)
-{
- NTSTATUS Status;
- HANDLE RealPinHandle;
- PKSDATAFORMAT_WAVEFORMATEX InputFormat;
- PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL;
- PKSPIN_CONNECT MixerPinConnect = NULL;
- KSPIN_CINSTANCES PinInstances;
-
- DPRINT("InstantiatePins entered\n");
-
- /* query instance count */
- Status = GetPinInstanceCount(DeviceEntry, &PinInstances, Connect);
- if (!NT_SUCCESS(Status))
- {
- /* failed to query instance count */
- return Status;
- }
-
- /* can be the pin be instantiated */
- if (PinInstances.PossibleCount == 0)
- {
- /* caller wanted to open an instance-less pin */
- return STATUS_UNSUCCESSFUL;
- }
-
- /* has the maximum instance count been exceeded */
- if (PinInstances.CurrentCount == PinInstances.PossibleCount)
- {
- /* FIXME pin already exists
- * and kmixer infrastructure is not implemented
- */
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Fetch input format */
- InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1);
-
- /* Let's try to create the audio irp pin */
- Status = KsCreatePin(DeviceEntry->Handle, Connect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
-
- if (!NT_SUCCESS(Status))
- {
- /* FIXME disable kmixer
- */
- return STATUS_UNSUCCESSFUL;
- }
-#if 0
- if (!NT_SUCCESS(Status))
- {
- /* the audio irp pin didnt accept the input format
- * let's compute a compatible format
- */
- MixerPinConnect = AllocateItem(NonPagedPool, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX));
- if (!MixerPinConnect)
- {
- /* not enough memory */
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Zero pin connect */
- RtlZeroMemory(MixerPinConnect, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX));
-
- /* Copy initial connect details */
- RtlMoveMemory(MixerPinConnect, Connect, sizeof(KSPIN_CONNECT));
-
-
- OutputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(MixerPinConnect + 1);
-
- Status = ComputeCompatibleFormat(DeviceEntry, Connect->PinId, InputFormat, OutputFormat);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ComputeCompatibleFormat failed with %x\n", Status);
- FreeItem(MixerPinConnect);
- return Status;
- }
-
- /* Retry with Mixer format */
- Status = KsCreatePin(DeviceEntry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
- if (!NT_SUCCESS(Status))
- {
- /* This should not fail */
- DPRINT1("KsCreatePin failed with %x\n", Status);
- DPRINT1(" InputFormat: SampleRate %u Bits %u Channels %u\n", InputFormat->WaveFormatEx.nSamplesPerSec, InputFormat->WaveFormatEx.wBitsPerSample, InputFormat->WaveFormatEx.nChannels);
- DPRINT1("OutputFormat: SampleRate %u Bits %u Channels %u\n", OutputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.nChannels);
-
- FreeItem(MixerPinConnect);
- return Status;
- }
- }
-#endif
-
- //DeviceEntry->Pins[Connect->PinId].References = 0;
-
- /* initialize dispatch context */
- DispatchContext->Handle = RealPinHandle;
- DispatchContext->PinId = Connect->PinId;
- DispatchContext->AudioEntry = DeviceEntry;
-
-
- DPRINT("RealPinHandle %p\n", RealPinHandle);
-
- /* Do we need to transform the audio stream */
- if (OutputFormat != NULL)
- {
- /* Now create the mixer pin */
- Status = CreateMixerPinAndSetFormat(DeviceExtension->KMixerHandle,
- MixerPinConnect,
- (PKSDATAFORMAT)InputFormat,
- (PKSDATAFORMAT)OutputFormat,
- &DispatchContext->hMixerPin);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create Mixer Pin with %x\n", Status);
- FreeItem(MixerPinConnect);
- }
- }
- /* done */
- return Status;
-}
-
-NTSTATUS
-GetConnectRequest(
- IN PIRP Irp,
- OUT PKSPIN_CONNECT * Result)
-{
- PIO_STACK_LOCATION IoStack;
- ULONG ObjectLength, ParametersLength;
- PVOID Buffer;
-
- /* get current irp stack */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* get object class length */
- ObjectLength = (wcslen(KSSTRING_Pin) + 1) * sizeof(WCHAR);
-
- /* check for minium length requirement */
- if (ObjectLength + sizeof(KSPIN_CONNECT) > IoStack->FileObject->FileName.MaximumLength)
- return STATUS_UNSUCCESSFUL;
-
- /* extract parameters length */
- ParametersLength = IoStack->FileObject->FileName.MaximumLength - ObjectLength;
-
- /* allocate buffer */
- Buffer = AllocateItem(NonPagedPool, ParametersLength);
- if (!Buffer)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* copy parameters */
- RtlMoveMemory(Buffer, &IoStack->FileObject->FileName.Buffer[ObjectLength / sizeof(WCHAR)], ParametersLength);
-
- /* store result */
- *Result = (PKSPIN_CONNECT)Buffer;
-
- return STATUS_SUCCESS;
-}
-
-
-
-NTSTATUS
-NTAPI
-DispatchCreateSysAudioPin(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- PIO_STACK_LOCATION IoStack;
- PKSAUDIO_DEVICE_ENTRY DeviceEntry;
- PKSPIN_CONNECT Connect;
- PDISPATCH_CONTEXT DispatchContext;
-
- DPRINT("DispatchCreateSysAudioPin entered\n");
-
- /* get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* sanity checks */
- ASSERT(IoStack->FileObject);
- ASSERT(IoStack->FileObject->RelatedFileObject);
- ASSERT(IoStack->FileObject->RelatedFileObject->FsContext);
-
- /* get current attached virtual device */
- DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)IoStack->FileObject->RelatedFileObject->FsContext;
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- /* failed */
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
-
- /* get connect details */
- Status = GetConnectRequest(Irp, &Connect);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- /* failed to obtain connect details */
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
-
-
- /* allocate dispatch context */
- DispatchContext = AllocateItem(NonPagedPool, sizeof(DISPATCH_CONTEXT));
- if (!DispatchContext)
- {
- /* failed */
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* zero dispatch context */
- RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT));
-
- /* allocate object header */
- Status = KsAllocateObjectHeader(&DispatchContext->ObjectHeader, 0, NULL, Irp, &PinTable);
- if (!NT_SUCCESS(Status))
- {
- /* failed */
- FreeItem(DispatchContext);
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
-
- /* now instantiate the pins */
- Status = InstantiatePins(DeviceEntry, Connect, DispatchContext, (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension);
- if (!NT_SUCCESS(Status))
- {
- /* failed */
- KsFreeObjectHeader(DispatchContext->ObjectHeader);
- FreeItem(DispatchContext);
- }
- else
- {
- /* store dispatch context */
- IoStack->FileObject->FsContext = (PVOID)DispatchContext;
- }
-
-
- /* FIXME create items for clocks / allocators */
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
-}
+++ /dev/null
-#pragma once
-
-#include <ntifs.h>
-#include <ntddk.h>
-#include <portcls.h>
-#include <ks.h>
-#include <ksmedia.h>
-#include <math.h>
-#define NDEBUG
-#include <debug.h>
-#include <stdio.h>
-
-typedef struct
-{
- HANDLE PinHandle; // handle to audio irp pin
- ULONG References; // number of clients having a reference to this audio irp pin
-}PIN_INFO;
-
-typedef struct
-{
- LIST_ENTRY Entry; // device entry for KsAudioDeviceList
- UNICODE_STRING DeviceName; // symbolic link of audio device
-
- HANDLE Handle; // handle to audio device
- PFILE_OBJECT FileObject; // file objecto to audio device
-
- //PIN_INFO * Pins; // array of PIN_INFO
-}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
-
-typedef struct
-{
- KSDEVICE_HEADER KsDeviceHeader; // ks streaming header - must always be first item in device extension
- PDEVICE_OBJECT PhysicalDeviceObject; // pdo
- PDEVICE_OBJECT NextDeviceObject; // lower device object
- ULONG NumberOfKsAudioDevices; // number of audio devices
-
- LIST_ENTRY KsAudioDeviceList; // audio device list
- PVOID KsAudioNotificationEntry; // ks audio notification hook
- PVOID EchoCancelNotificationEntry; // ks echo cancel notification hook
- KSPIN_LOCK Lock; // audio device list mutex
-
- PFILE_OBJECT KMixerFileObject; // mixer file object
- HANDLE KMixerHandle; // mixer file handle
-
-}SYSAUDIODEVEXT, *PSYSAUDIODEVEXT;
-
-// struct DISPATCH_CONTEXT
-//
-// This structure is used to dispatch read / write / device io requests
-// It is stored in the file object FsContext2 member
-// Note: FsContext member is reserved for ks object header
-
-typedef struct
-{
- KSOBJECT_HEADER ObjectHeader; // pin object header
- HANDLE Handle; // audio irp pin handle
- ULONG PinId; // pin id of device
- PKSAUDIO_DEVICE_ENTRY AudioEntry; // pointer to audio device entry
-
- HANDLE hMixerPin; // handle to mixer pin
-}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
-
-NTSTATUS
-SysAudioAllocateDeviceHeader(
- IN SYSAUDIODEVEXT *DeviceExtension);
-
-NTSTATUS
-SysAudioRegisterDeviceInterfaces(
- IN PDEVICE_OBJECT DeviceObject);
-
-NTSTATUS
-SysAudioRegisterNotifications(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT DeviceObject);
-
-NTSTATUS
-SysAudioHandleProperty(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp);
-
-NTSTATUS
-SysAudioOpenKMixer(
- IN SYSAUDIODEVEXT *DeviceExtension);
-
-NTSTATUS
-OpenDevice(
- IN PUNICODE_STRING DeviceName,
- IN PHANDLE HandleOut,
- IN PFILE_OBJECT * FileObjectOut);
-
-PKSAUDIO_DEVICE_ENTRY
-GetListEntry(
- IN PLIST_ENTRY Head,
- IN ULONG Index);
-
-NTSTATUS
-NTAPI
-DispatchCreateSysAudioPin(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-ULONG
-GetDeviceCount(
- PSYSAUDIODEVEXT DeviceExtension,
- BOOL WaveIn);
-
-NTSTATUS
-GetPinInstanceCount(
- PKSAUDIO_DEVICE_ENTRY Entry,
- PKSPIN_CINSTANCES PinInstances,
- PKSPIN_CONNECT PinConnect);
-
-NTSTATUS
-ComputeCompatibleFormat(
- IN PKSAUDIO_DEVICE_ENTRY Entry,
- IN ULONG PinId,
- IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
- OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat);
-
-PVOID
-AllocateItem(
- IN POOL_TYPE PoolType,
- IN SIZE_T NumberOfBytes);
-
-VOID
-FreeItem(
- IN PVOID Item);
-
+++ /dev/null
-<?xml version="1.0"?>
-<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
-<module name="sysaudio" type="kernelmodedriver" installbase="system32/drivers" installname="sysaudio.sys">
- <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>
+++ /dev/null
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION "System Audio Graph Builder\0"
-#define REACTOS_STR_INTERNAL_NAME "sysaudio\0"
-#define REACTOS_STR_ORIGINAL_FILENAME "sysaudio.sys\0"
-#include <reactos/version.rc>