mirror of
https://github.com/reactos/reactos.git
synced 2024-07-12 07:35:10 +00:00
[PORTCLS]
- Implement support for submitting multiple stream headers at once - Return correct status code on error [WDMAUD_KERNEL] - Save correct length svn path=/trunk/; revision=43665
This commit is contained in:
parent
a5f9cb6d11
commit
6793ef9a7c
|
@ -57,6 +57,16 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
#define OFFSET_HEADERINDEX (0)
|
||||
#define OFFSET_STREAMHEADER (2)
|
||||
#define OFFSET_HEADERCOUNT (3)
|
||||
|
||||
|
||||
#define STREAMHEADER_INDEX(Irp) (PtrToUlong(Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX]))
|
||||
#define STREAMHEADER_COUNT(Irp) (PtrToUlong(Irp->Tail.Overlay.DriverContext[OFFSET_HEADERCOUNT]))
|
||||
#define STREAMHEADER_CURRENT(Irp) (Irp->Tail.Overlay.DriverContext[OFFSET_STREAMHEADER])
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CIrpQueue::QueryInterface(
|
||||
|
@ -107,6 +117,8 @@ CIrpQueue::AddMapping(
|
|||
PKSSTREAM_HEADER Header;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
ULONG NumHeaders, NumData, Index;
|
||||
PMDL Mdl;
|
||||
|
||||
PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||
|
||||
|
@ -132,31 +144,71 @@ CIrpQueue::AddMapping(
|
|||
return Status;
|
||||
}
|
||||
}
|
||||
// get the stream header
|
||||
|
||||
// get first stream header
|
||||
Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
|
||||
PC_ASSERT(Header);
|
||||
PC_ASSERT(Irp->MdlAddress);
|
||||
|
||||
DPRINT("Size %u DataUsed %u FrameExtent %u SizeHeader %u NumDataAvailable %u OutputLength %u\n", Header->Size, Header->DataUsed, Header->FrameExtent, sizeof(KSSTREAM_HEADER), m_NumDataAvailable, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
|
||||
// calculate num headers
|
||||
NumHeaders = IoStack->Parameters.DeviceIoControl.OutputBufferLength / Header->Size;
|
||||
|
||||
Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
PC_ASSERT(Header->Data);
|
||||
//PC_ASSERT(Header->Size == IoStack->Parameters.DeviceIoControl.OutputBufferLength);
|
||||
// assume headers of same length
|
||||
PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength % Header->Size == 0);
|
||||
|
||||
// HACK
|
||||
Irp->Tail.Overlay.DriverContext[2] = (PVOID)Header;
|
||||
|
||||
// sanity check
|
||||
PC_ASSERT(Header);
|
||||
// get first audio buffer
|
||||
Mdl = Irp->MdlAddress;
|
||||
|
||||
// dont exceed max frame size
|
||||
//PC_ASSERT(m_MaxFrameSize >= Header->DataUsed);
|
||||
|
||||
// increment num mappings
|
||||
InterlockedIncrement(&m_NumMappings);
|
||||
// store the current stream header
|
||||
Irp->Tail.Overlay.DriverContext[OFFSET_STREAMHEADER] = (PVOID)Header;
|
||||
// store header count
|
||||
Irp->Tail.Overlay.DriverContext[OFFSET_HEADERCOUNT] = UlongToPtr(NumHeaders);
|
||||
|
||||
// store current header index
|
||||
Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(0);
|
||||
|
||||
|
||||
NumData = 0;
|
||||
// prepare all headers
|
||||
for(Index = 0; Index < NumHeaders; Index++)
|
||||
{
|
||||
// sanity checks
|
||||
PC_ASSERT(Header);
|
||||
PC_ASSERT(Mdl);
|
||||
|
||||
Header->Data = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
|
||||
|
||||
if (!Header->Data)
|
||||
{
|
||||
// insufficient resources
|
||||
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
|
||||
Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
// complete and forget request
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// increment num mappings
|
||||
InterlockedIncrement(&m_NumMappings);
|
||||
|
||||
// increment available data
|
||||
InterlockedExchangeAdd((PLONG)&m_NumDataAvailable,
|
||||
(max(Header->DataUsed, Header->FrameExtent)));
|
||||
|
||||
NumData += max(Header->DataUsed, Header->FrameExtent);
|
||||
|
||||
// move to next header
|
||||
Header = (PKSSTREAM_HEADER)((ULONG_PTR)Header + Header->Size);
|
||||
|
||||
// move to next mdl
|
||||
Mdl = Mdl->Next;
|
||||
}
|
||||
|
||||
DPRINT("StreamHeaders %u NumData %u FrameSize %u NumDataAvailable %u\n", NumHeaders, NumData, m_MaxFrameSize, m_NumDataAvailable);
|
||||
|
||||
// increment num data available
|
||||
m_NumDataAvailable += Header->DataUsed;
|
||||
|
||||
// mark irp as pending
|
||||
IoMarkIrpPending(Irp);
|
||||
|
@ -206,6 +258,7 @@ CIrpQueue::GetMapping(
|
|||
if (!Irp)
|
||||
{
|
||||
DPRINT("NoIrp\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
// no irp available, use silence buffer
|
||||
*Buffer = (PUCHAR)m_SilenceBuffer;
|
||||
*BufferSize = m_MaxFrameSize;
|
||||
|
@ -216,16 +269,8 @@ CIrpQueue::GetMapping(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// get current irp stack location
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
// get stream header
|
||||
StreamHeader = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||
#else
|
||||
// HACK get stream header
|
||||
StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2];
|
||||
#endif
|
||||
|
||||
// sanity check
|
||||
PC_ASSERT(StreamHeader);
|
||||
|
@ -253,7 +298,7 @@ CIrpQueue::UpdateMapping(
|
|||
IN ULONG BytesWritten)
|
||||
{
|
||||
PKSSTREAM_HEADER StreamHeader;
|
||||
ULONG Size;
|
||||
ULONG Size, NumData, Index;
|
||||
|
||||
if (!m_Irp)
|
||||
{
|
||||
|
@ -262,7 +307,7 @@ CIrpQueue::UpdateMapping(
|
|||
}
|
||||
|
||||
// get stream header
|
||||
StreamHeader = (PKSSTREAM_HEADER)m_Irp->Tail.Overlay.DriverContext[2];
|
||||
StreamHeader = (PKSSTREAM_HEADER)STREAMHEADER_CURRENT(m_Irp);
|
||||
|
||||
// sanity check
|
||||
// ASSERT(StreamHeader);
|
||||
|
@ -282,20 +327,59 @@ CIrpQueue::UpdateMapping(
|
|||
|
||||
if (m_CurrentOffset >= Size)
|
||||
{
|
||||
if (STREAMHEADER_INDEX(m_Irp) + 1 < STREAMHEADER_COUNT(m_Irp))
|
||||
{
|
||||
// the irp has at least one more stream header
|
||||
m_Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(STREAMHEADER_INDEX(m_Irp) + 1);
|
||||
|
||||
// get next stream header
|
||||
StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size);
|
||||
|
||||
// store next stream header
|
||||
STREAMHEADER_CURRENT(m_Irp) = (PVOID)StreamHeader;
|
||||
|
||||
// reset current offset
|
||||
m_CurrentOffset = 0;
|
||||
|
||||
// done
|
||||
return;
|
||||
}
|
||||
|
||||
// irp has been processed completly
|
||||
|
||||
NumData = 0;
|
||||
StreamHeader = (PKSSTREAM_HEADER)m_Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
// loop all stream headers
|
||||
for(Index = 0; Index < STREAMHEADER_COUNT(m_Irp); Index++)
|
||||
{
|
||||
PC_ASSERT(StreamHeader);
|
||||
|
||||
// add size of buffer
|
||||
// depends on if the buffer is input / output
|
||||
if (StreamHeader->DataUsed)
|
||||
Size = StreamHeader->DataUsed;
|
||||
else
|
||||
Size = StreamHeader->FrameExtent;
|
||||
|
||||
// increment size
|
||||
NumData += Size;
|
||||
|
||||
// get next stream header
|
||||
StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size);
|
||||
}
|
||||
|
||||
m_Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
m_Irp->IoStatus.Information = NumData;
|
||||
|
||||
// frame extend contains the original request size, DataUsed contains the real buffer size
|
||||
//is different when kmixer performs channel conversion, upsampling etc
|
||||
|
||||
m_Irp->IoStatus.Information = Size;
|
||||
|
||||
#if 0
|
||||
PC_ASSERT_IRQL(DISPATCH_LEVEL);
|
||||
MmUnlockPages(m_Irp->MdlAddress);
|
||||
IoFreeMdl(m_Irp->MdlAddress);
|
||||
m_Irp->MdlAddress = NULL;
|
||||
ExFreePool(m_Irp->AssociatedIrp.SystemBuffer);
|
||||
m_Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
#endif
|
||||
|
||||
// complete the request
|
||||
IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT);
|
||||
|
@ -391,6 +475,9 @@ CIrpQueue::GetMappingWithTag(
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
//FIXME support more than one stream header
|
||||
PC_ASSERT(STREAMHEADER_COUNT(Irp) == 1);
|
||||
|
||||
// HACK get stream header
|
||||
StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2];
|
||||
|
||||
|
|
|
@ -601,10 +601,11 @@ CPortPinWaveCyclic::HandleKsStream(
|
|||
else
|
||||
m_Position.WriteOffset += Header->DataUsed;
|
||||
|
||||
return STATUS_PENDING;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return STATUS_PENDING;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -976,6 +977,11 @@ CPortPinWaveCyclic::Init(
|
|||
|
||||
RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
|
||||
|
||||
PKSDATAFORMAT_WAVEFORMATEX Wave = (PKSDATAFORMAT_WAVEFORMATEX)m_Format;
|
||||
|
||||
DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n", Wave->WaveFormatEx.wBitsPerSample, Wave->WaveFormatEx.nSamplesPerSec, Wave->WaveFormatEx.nChannels, Wave->WaveFormatEx.wFormatTag, m_FrameSize);
|
||||
|
||||
|
||||
|
||||
Port->AddRef();
|
||||
Filter->AddRef();
|
||||
|
@ -985,9 +991,6 @@ CPortPinWaveCyclic::Init(
|
|||
|
||||
DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE));
|
||||
DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE));
|
||||
DPRINT("Setting state to run %x\n", m_Stream->SetState(KSSTATE_RUN));
|
||||
m_State = KSSTATE_RUN;
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -682,10 +682,10 @@ CPortPinWavePci::HandleKsStream(
|
|||
else
|
||||
m_Position.WriteOffset += Header->DataUsed;
|
||||
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
|
||||
return STATUS_PENDING;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -331,7 +331,7 @@ WdmAudReadWrite(
|
|||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("KsProbeStreamIrp failed with Status %x\n", Status);
|
||||
DPRINT1("KsProbeStreamIrp failed with Status %x Cancel %u\n", Status, Irp->Cancel);
|
||||
return SetIrpIoStatus(Irp, Status, 0);
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,7 @@ WdmAudReadWrite(
|
|||
|
||||
/* attach file object */
|
||||
IoStack->FileObject = FileObject;
|
||||
IoStack->Parameters.Write.Length = sizeof(KSSTREAM_HEADER);
|
||||
IoStack->Parameters.Write.Length = Length;
|
||||
IoStack->MajorFunction = IRP_MJ_WRITE;
|
||||
|
||||
/* mark irp as pending */
|
||||
|
|
Loading…
Reference in a new issue