2009-03-04 21:13:10 +00:00
|
|
|
/*
|
|
|
|
* 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"
|
|
|
|
|
2009-03-11 09:30:33 +00:00
|
|
|
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
|
|
|
|
|
|
|
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);
|
2009-03-11 14:42:42 +00:00
|
|
|
//DPRINT("Samples %u BufferLength %u\n", Samples, BufferLength);
|
2009-03-11 09:30:33 +00:00
|
|
|
|
|
|
|
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];
|
2009-03-11 14:42:42 +00:00
|
|
|
Sample *= 2;
|
2009-03-11 19:02:06 +00:00
|
|
|
#ifdef _X86_
|
|
|
|
Sample = _byteswap_ushort(Sample);
|
|
|
|
#endif
|
|
|
|
BufferOut[Index] = Sample;
|
2009-03-11 09:30:33 +00:00
|
|
|
}
|
|
|
|
*Result = BufferOut;
|
|
|
|
*ResultLength = Samples * sizeof(USHORT);
|
|
|
|
}
|
|
|
|
else if (OldWidth == 8 && NewWidth == 32)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
ULONG Sample;
|
2009-03-11 09:30:33 +00:00
|
|
|
PULONG BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(ULONG));
|
|
|
|
if (!BufferOut)
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
|
|
|
for(Index = 0; Index < Samples; Index++)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
Sample = Buffer[Index];
|
|
|
|
Sample *= 16777216;
|
2009-03-11 19:02:06 +00:00
|
|
|
#ifdef _X86_
|
|
|
|
Sample = _byteswap_ulong(Sample);
|
|
|
|
#endif
|
|
|
|
BufferOut[Index] = Sample;
|
2009-03-11 09:30:33 +00:00
|
|
|
}
|
|
|
|
*Result = BufferOut;
|
|
|
|
*ResultLength = Samples * sizeof(ULONG);
|
|
|
|
}
|
|
|
|
else if (OldWidth == 16 && NewWidth == 32)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
ULONG Sample;
|
|
|
|
PUSHORT BufferIn = (PUSHORT)Buffer;
|
2009-03-11 09:30:33 +00:00
|
|
|
PULONG BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(ULONG));
|
|
|
|
if (!BufferOut)
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
|
|
|
for(Index = 0; Index < Samples; Index++)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
Sample = BufferIn[Index];
|
|
|
|
Sample *= 65536;
|
2009-03-11 19:02:06 +00:00
|
|
|
#ifdef _X86_
|
|
|
|
Sample = _byteswap_ulong(Sample);
|
|
|
|
#endif
|
|
|
|
BufferOut[Index] = Sample;
|
2009-03-11 09:30:33 +00:00
|
|
|
}
|
|
|
|
*Result = BufferOut;
|
|
|
|
*ResultLength = Samples * sizeof(ULONG);
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (OldWidth == 16 && NewWidth == 8)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
USHORT Sample;
|
|
|
|
PUSHORT BufferIn = (PUSHORT)Buffer;
|
2009-03-11 09:30:33 +00:00
|
|
|
PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(UCHAR));
|
|
|
|
if (!BufferOut)
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
|
|
|
for(Index = 0; Index < Samples; Index++)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
Sample = BufferIn[Index];
|
2009-03-11 19:02:06 +00:00
|
|
|
#ifdef _X86_
|
|
|
|
Sample = _byteswap_ushort(Sample);
|
|
|
|
#endif
|
2009-03-11 14:42:42 +00:00
|
|
|
Sample /= 256;
|
2009-03-11 19:02:06 +00:00
|
|
|
BufferOut[Index] = (Sample & 0xFF);
|
2009-03-11 09:30:33 +00:00
|
|
|
}
|
|
|
|
*Result = BufferOut;
|
|
|
|
*ResultLength = Samples * sizeof(UCHAR);
|
|
|
|
}
|
|
|
|
else if (OldWidth == 32 && NewWidth == 8)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
ULONG Sample;
|
|
|
|
PULONG BufferIn = (PULONG)Buffer;
|
2009-03-11 09:30:33 +00:00
|
|
|
PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(UCHAR));
|
|
|
|
if (!BufferOut)
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
|
|
|
for(Index = 0; Index < Samples; Index++)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
Sample = BufferIn[Index];
|
2009-03-11 19:02:06 +00:00
|
|
|
#ifdef _X86_
|
|
|
|
Sample = _byteswap_ulong(Sample);
|
|
|
|
#endif
|
2009-03-11 14:42:42 +00:00
|
|
|
Sample /= 16777216;
|
2009-03-11 19:02:06 +00:00
|
|
|
BufferOut[Index] = (Sample & 0xFF);
|
2009-03-11 09:30:33 +00:00
|
|
|
}
|
|
|
|
*Result = BufferOut;
|
|
|
|
*ResultLength = Samples * sizeof(UCHAR);
|
|
|
|
}
|
|
|
|
else if (OldWidth == 32 && NewWidth == 16)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
USHORT Sample;
|
|
|
|
PULONG BufferIn = (PULONG)Buffer;
|
2009-03-11 09:30:33 +00:00
|
|
|
PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(USHORT));
|
|
|
|
if (!BufferOut)
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
|
|
|
for(Index = 0; Index < Samples; Index++)
|
|
|
|
{
|
2009-03-11 14:42:42 +00:00
|
|
|
Sample = BufferIn[Index];
|
2009-03-11 19:02:06 +00:00
|
|
|
#ifdef _X86_
|
|
|
|
Sample = _byteswap_ulong(Sample);
|
|
|
|
#endif
|
2009-03-11 14:42:42 +00:00
|
|
|
Sample /= 65536;
|
2009-03-11 19:02:06 +00:00
|
|
|
BufferOut[Index] = (Sample & 0xFFFF);
|
2009-03-11 09:30:33 +00:00
|
|
|
}
|
|
|
|
*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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-05 13:50:54 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
Pin_fnDeviceIoControl(
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
|
|
|
PIRP Irp)
|
|
|
|
{
|
2009-03-11 09:30:33 +00:00
|
|
|
PIO_STACK_LOCATION IoStack;
|
2009-03-12 22:11:53 +00:00
|
|
|
PKSP_PIN Property;
|
|
|
|
//DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
|
2009-03-05 13:50:54 +00:00
|
|
|
|
2009-03-11 09:30:33 +00:00
|
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
|
2009-03-12 22:11:53 +00:00
|
|
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(KSP_PIN) && IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSDATAFORMAT_WAVEFORMATEX))
|
2009-03-11 09:30:33 +00:00
|
|
|
{
|
2009-03-12 22:11:53 +00:00
|
|
|
Property = (PKSP_PIN)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
|
2009-03-11 09:30:33 +00:00
|
|
|
|
2009-03-12 22:11:53 +00:00
|
|
|
if (IsEqualGUIDAligned(&Property->Property.Set, &KSPROPSETID_Connection))
|
2009-03-11 09:30:33 +00:00
|
|
|
{
|
2009-03-12 22:11:53 +00:00
|
|
|
if (Property->Property.Id == KSPROPERTY_CONNECTION_DATAFORMAT && Property->Property.Flags == KSPROPERTY_TYPE_SET)
|
2009-03-11 09:30:33 +00:00
|
|
|
{
|
2009-03-12 22:11:53 +00:00
|
|
|
PKSDATAFORMAT_WAVEFORMATEX Formats;
|
|
|
|
PKSDATAFORMAT_WAVEFORMATEX WaveFormat;
|
2009-03-11 09:30:33 +00:00
|
|
|
|
2009-03-12 22:11:53 +00:00
|
|
|
Formats = (PKSDATAFORMAT_WAVEFORMATEX)IoStack->FileObject->FsContext2;
|
|
|
|
WaveFormat = (PKSDATAFORMAT_WAVEFORMATEX)Irp->UserBuffer;
|
2009-03-11 09:30:33 +00:00
|
|
|
|
2009-03-12 22:11:53 +00:00
|
|
|
ASSERT(Property->PinId == 0 || Property->PinId == 1);
|
|
|
|
ASSERT(Formats);
|
|
|
|
ASSERT(WaveFormat);
|
2009-03-11 09:30:33 +00:00
|
|
|
|
2009-03-12 22:11:53 +00:00
|
|
|
Formats[Property->PinId].WaveFormatEx.nChannels = WaveFormat->WaveFormatEx.nChannels;
|
|
|
|
Formats[Property->PinId].WaveFormatEx.wBitsPerSample = WaveFormat->WaveFormatEx.wBitsPerSample;
|
|
|
|
Formats[Property->PinId].WaveFormatEx.nSamplesPerSec = WaveFormat->WaveFormatEx.nSamplesPerSec;
|
2009-03-11 09:30:33 +00:00
|
|
|
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-03-12 22:11:53 +00:00
|
|
|
DPRINT1("Size %u Expected %u\n",IoStack->Parameters.DeviceIoControl.OutputBufferLength, sizeof(KSDATAFORMAT_WAVEFORMATEX));
|
2009-03-05 13:50:54 +00:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
DPRINT1("Pin_fnRead called DeviceObject %p Irp %p\n", DeviceObject);
|
2009-03-04 21:13:10 +00:00
|
|
|
|
2009-03-05 13:50:54 +00:00
|
|
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
2009-03-04 21:13:10 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
2009-03-05 13:50:54 +00:00
|
|
|
NTAPI
|
|
|
|
PinWriteCompletionRoutine(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
IN PVOID Context)
|
|
|
|
{
|
|
|
|
PIRP CIrp = (PIRP)Context;
|
|
|
|
|
|
|
|
CIrp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
CIrp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(CIrp, IO_NO_INCREMENT);
|
2009-03-04 21:13:10 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2009-03-05 13:50:54 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
Pin_fnWrite(
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
|
|
|
PIRP Irp)
|
|
|
|
{
|
|
|
|
DPRINT1("Pin_fnWrite called DeviceObject %p Irp %p\n", DeviceObject);
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
DPRINT1("Pin_fnFlush called DeviceObject %p Irp %p\n", DeviceObject);
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
DPRINT1("Pin_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;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
Pin_fnQuerySecurity(
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
|
|
|
PIRP Irp)
|
|
|
|
{
|
|
|
|
DPRINT1("Pin_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject);
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
|
|
|
|
DPRINT1("Pin_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject);
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
DPRINT1("Pin_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
|
|
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
Pin_fnFastRead(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PLARGE_INTEGER FileOffset,
|
|
|
|
ULONG Length,
|
|
|
|
BOOLEAN Wait,
|
|
|
|
ULONG LockKey,
|
|
|
|
PVOID Buffer,
|
|
|
|
PIO_STATUS_BLOCK IoStatus,
|
|
|
|
PDEVICE_OBJECT DeviceObject)
|
|
|
|
{
|
|
|
|
DPRINT1("Pin_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
Pin_fnFastWrite(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PLARGE_INTEGER FileOffset,
|
|
|
|
ULONG Length,
|
|
|
|
BOOLEAN Wait,
|
|
|
|
ULONG LockKey,
|
|
|
|
PVOID Buffer,
|
|
|
|
PIO_STATUS_BLOCK IoStatus,
|
|
|
|
PDEVICE_OBJECT DeviceObject)
|
|
|
|
{
|
2009-03-11 09:30:33 +00:00
|
|
|
PKSSTREAM_HEADER StreamHeader;
|
|
|
|
PVOID BufferOut;
|
|
|
|
ULONG BufferLength;
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2009-03-12 22:11:53 +00:00
|
|
|
PKSDATAFORMAT_WAVEFORMATEX Formats;
|
|
|
|
PKSDATAFORMAT_WAVEFORMATEX InputFormat, OutputFormat;
|
2009-03-11 09:30:33 +00:00
|
|
|
|
2009-03-11 19:02:06 +00:00
|
|
|
//DPRINT1("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
|
2009-03-05 13:50:54 +00:00
|
|
|
|
2009-03-12 22:11:53 +00:00
|
|
|
Formats = (PKSDATAFORMAT_WAVEFORMATEX)FileObject->FsContext2;
|
2009-03-11 09:30:33 +00:00
|
|
|
|
2009-03-12 22:11:53 +00:00
|
|
|
InputFormat = Formats;
|
|
|
|
OutputFormat = (Formats + 1);
|
2009-03-11 09:30:33 +00:00
|
|
|
StreamHeader = (PKSSTREAM_HEADER)Buffer;
|
|
|
|
|
2009-03-11 19:02:06 +00:00
|
|
|
#if 0
|
2009-03-11 09:30:33 +00:00
|
|
|
DPRINT1("Num Channels %u Old Channels %u\n SampleRate %u Old SampleRate %u\n BitsPerSample %u Old BitsPerSample %u\n",
|
2009-03-12 22:11:53 +00:00
|
|
|
InputFormat->WaveFormatEx.nChannels, OutputFormat->WaveFormatEx.nChannels,
|
|
|
|
InputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.nSamplesPerSec,
|
|
|
|
InputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.wBitsPerSample);
|
2009-03-11 19:02:06 +00:00
|
|
|
#endif
|
2009-03-11 09:30:33 +00:00
|
|
|
|
2009-03-12 22:11:53 +00:00
|
|
|
if (InputFormat->WaveFormatEx.wBitsPerSample != OutputFormat->WaveFormatEx.wBitsPerSample)
|
2009-03-11 09:30:33 +00:00
|
|
|
{
|
|
|
|
Status = PerformQualityConversion(StreamHeader->Data,
|
|
|
|
StreamHeader->DataUsed,
|
2009-03-12 22:11:53 +00:00
|
|
|
InputFormat->WaveFormatEx.wBitsPerSample,
|
|
|
|
OutputFormat->WaveFormatEx.wBitsPerSample,
|
2009-03-11 09:30:33 +00:00
|
|
|
&BufferOut,
|
|
|
|
&BufferLength);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2009-03-11 19:02:06 +00:00
|
|
|
//DPRINT1("Old BufferSize %u NewBufferSize %u\n", StreamHeader->DataUsed, BufferLength);
|
2009-03-11 09:30:33 +00:00
|
|
|
ExFreePool(StreamHeader->Data);
|
|
|
|
StreamHeader->Data = BufferOut;
|
|
|
|
StreamHeader->DataUsed = BufferLength;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-12 22:11:53 +00:00
|
|
|
if (InputFormat->WaveFormatEx.nSamplesPerSec != OutputFormat->WaveFormatEx.nSamplesPerSec)
|
2009-03-11 09:30:33 +00:00
|
|
|
{
|
|
|
|
/* sample format conversion must be done in a deferred routine */
|
2009-03-12 22:11:53 +00:00
|
|
|
DPRINT1("SampleRate conversion not available yet %u %u\n", InputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.nSamplesPerSec);
|
2009-03-11 09:30:33 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
return TRUE;
|
2009-03-05 13:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2009-03-12 22:11:53 +00:00
|
|
|
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;
|
2009-03-05 13:50:54 +00:00
|
|
|
|
|
|
|
/* allocate object header */
|
|
|
|
Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable);
|
|
|
|
return Status;
|
|
|
|
}
|
2009-03-04 21:13:10 +00:00
|
|
|
|
|
|
|
void * calloc(size_t Elements, size_t ElementSize)
|
|
|
|
{
|
|
|
|
PVOID Block = ExAllocatePool(NonPagedPool, Elements * ElementSize);
|
|
|
|
if (Block)
|
|
|
|
RtlZeroMemory(Block, Elements * ElementSize);
|
|
|
|
|
|
|
|
return Block;
|
|
|
|
}
|
|
|
|
|
|
|
|
void free(PVOID Block)
|
|
|
|
{
|
|
|
|
ExFreePool(Block);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *memset(
|
|
|
|
void* dest,
|
|
|
|
int c,
|
|
|
|
size_t count)
|
|
|
|
{
|
|
|
|
RtlFillMemory(dest, count, c);
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
void * memcpy(
|
|
|
|
void* dest,
|
|
|
|
const void* src,
|
|
|
|
size_t count)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(dest, src, count);
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *memmove(
|
|
|
|
void* dest,
|
|
|
|
const void* src,
|
|
|
|
size_t count)
|
|
|
|
{
|
|
|
|
RtlMoveMemory(dest, src, count);
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|