mirror of
https://github.com/reactos/reactos.git
synced 2025-01-02 20:43:18 +00:00
[PORTCLS]
- Portcls does not need to set the size of the audio buffer for completed irps. This is done in a completion callback in wdmaud. Verified with WinXP portcls [WDMAUD_KERNEL] - Free allocated mdls in the io completion routine. Also free the associated stream header. [KS] - Replace all ms portcls hacks by one. - MS Portcls is now working in ReactOS (which is nice for testing audio related bugs) svn path=/trunk/; revision=49417
This commit is contained in:
parent
a6e4c15192
commit
26895c3eac
5 changed files with 139 additions and 67 deletions
|
@ -898,10 +898,6 @@ ProbeMdl:
|
|||
goto ProbeMdl;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// HACK for MS PORTCLS
|
||||
HeaderSize = Length;
|
||||
#endif
|
||||
/* probe user mode buffers */
|
||||
if (Length && ( (!HeaderSize) || (Length % HeaderSize == 0) || ((ProbeFlags & KSPROBE_ALLOWFORMATCHANGE) && (Length == sizeof(KSSTREAM_HEADER))) ) )
|
||||
{
|
||||
|
@ -1370,7 +1366,7 @@ KsRemoveIrpFromCancelableQueue(
|
|||
PLIST_ENTRY CurEntry;
|
||||
KIRQL OldIrql;
|
||||
|
||||
//DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
|
||||
DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
|
||||
|
||||
/* check parameters */
|
||||
if (!QueueHead || !SpinLock)
|
||||
|
@ -1629,19 +1625,32 @@ KsAddIrpToCancelableQueue(
|
|||
PIO_STACK_LOCATION IoStack;
|
||||
KIRQL OldLevel;
|
||||
|
||||
DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead, SpinLock, Irp, ListLocation, DriverCancel);
|
||||
/* check for required parameters */
|
||||
if (!QueueHead || !SpinLock || !Irp)
|
||||
return;
|
||||
|
||||
/* get current irp stack */
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead, SpinLock, Irp, ListLocation, DriverCancel);
|
||||
|
||||
// HACK for ms portcls
|
||||
if (IoStack->MajorFunction == IRP_MJ_CREATE)
|
||||
{
|
||||
// complete the request
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!DriverCancel)
|
||||
{
|
||||
/* default to KsCancelRoutine */
|
||||
DriverCancel = KsCancelRoutine;
|
||||
}
|
||||
|
||||
/* get current irp stack */
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* acquire spinlock */
|
||||
KeAcquireSpinLock(SpinLock, &OldLevel);
|
||||
|
@ -1973,12 +1982,6 @@ KsSetMajorFunctionHandler(
|
|||
IN ULONG MajorFunction)
|
||||
{
|
||||
DPRINT("KsSetMajorFunctionHandler Function %x\n", MajorFunction);
|
||||
#if 1
|
||||
// HACK
|
||||
// for MS PORTCLS
|
||||
//
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = KspCreate;
|
||||
#endif
|
||||
|
||||
switch ( MajorFunction )
|
||||
{
|
||||
|
@ -2016,7 +2019,7 @@ KsDispatchIrp(
|
|||
PKSIDEVICE_HEADER DeviceHeader;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
//DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
|
||||
DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
|
|
@ -232,21 +232,21 @@ CInterruptSync::Connect()
|
|||
if (IsListEmpty(&m_ServiceRoutines))
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
DPRINT("Vector %u Level %u Flags %x Affinity %x\n", Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Level, Descriptor->Flags, Descriptor->u.Interrupt.Affinity);
|
||||
DPRINT1("Vector %u Level %u Flags %x Affinity %x\n", Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Level, Descriptor->Flags, Descriptor->u.Interrupt.Affinity);
|
||||
|
||||
Status = IoConnectInterrupt(&m_Interrupt,
|
||||
IInterruptServiceRoutine,
|
||||
(PVOID)this,
|
||||
&m_Lock,
|
||||
NULL, //&m_Lock,
|
||||
Descriptor->u.Interrupt.Vector,
|
||||
(KIRQL)Descriptor->u.Interrupt.Level,
|
||||
(KIRQL)Descriptor->u.Interrupt.Level,
|
||||
(KINTERRUPT_MODE)(Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED),
|
||||
(Descriptor->Flags != CM_RESOURCE_INTERRUPT_LATCHED),
|
||||
(Descriptor->ShareDisposition != CmResourceShareDeviceExclusive),
|
||||
Descriptor->u.Interrupt.Affinity,
|
||||
FALSE);
|
||||
|
||||
DPRINT("CInterruptSync::Connect result %x\n", Status);
|
||||
DPRINT1("CInterruptSync::Connect result %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -293,7 +293,6 @@ CIrpQueue::UpdateMapping(
|
|||
{
|
||||
PKSSTREAM_HEADER StreamHeader;
|
||||
ULONG Size, NumData, Index;
|
||||
//PMDL CurMdl, NextMdl;
|
||||
|
||||
if (!m_Irp)
|
||||
{
|
||||
|
@ -340,8 +339,7 @@ CIrpQueue::UpdateMapping(
|
|||
return;
|
||||
}
|
||||
|
||||
// irp has been processed completly
|
||||
|
||||
// irp has been processed completly
|
||||
NumData = 0;
|
||||
if (m_Irp->RequestorMode == KernelMode)
|
||||
StreamHeader = (PKSSTREAM_HEADER)m_Irp->UserBuffer;
|
||||
|
@ -385,44 +383,10 @@ CIrpQueue::UpdateMapping(
|
|||
// done
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
// now free allocated mdls
|
||||
CurMdl = m_Irp->MdlAddress;
|
||||
for(Index = 0; Index < STREAMHEADER_COUNT(m_Irp); Index++)
|
||||
{
|
||||
// sanity check
|
||||
ASSERT(CurMdl);
|
||||
|
||||
// get next mdl
|
||||
NextMdl = CurMdl->Next;
|
||||
|
||||
// check if mdl is locked
|
||||
if (CurMdl->MdlFlags & MDL_PAGES_LOCKED)
|
||||
{
|
||||
// unlock pages
|
||||
MmUnlockPages(CurMdl);
|
||||
}
|
||||
|
||||
// free mdl
|
||||
IoFreeMdl(CurMdl);
|
||||
|
||||
// proceed to next mdl
|
||||
CurMdl = NextMdl;
|
||||
}
|
||||
|
||||
// all mdls have been freed now
|
||||
m_Irp->MdlAddress = NULL;
|
||||
|
||||
// free allocated KSSTREAM_HEADER
|
||||
ExFreePool(m_Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
// is this really needed?
|
||||
m_Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
#endif
|
||||
|
||||
// store operation status
|
||||
m_Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
m_Irp->IoStatus.Information = NumData;
|
||||
m_Irp->IoStatus.Information = 0;
|
||||
|
||||
// complete the request
|
||||
IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT);
|
||||
|
|
|
@ -384,6 +384,91 @@ WdmAudDeviceControl(
|
|||
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);
|
||||
|
||||
/* now free the stream header */
|
||||
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* free context */
|
||||
FreeItem(Context);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -398,6 +483,20 @@ WdmAudReadWrite(
|
|||
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);
|
||||
|
@ -414,6 +513,11 @@ WdmAudReadWrite(
|
|||
/* 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;
|
||||
|
||||
|
@ -441,16 +545,6 @@ WdmAudReadWrite(
|
|||
return SetIrpIoStatus(Irp, Status, 0);
|
||||
}
|
||||
|
||||
/* check if mdl is locked */
|
||||
if (Mdl->MdlFlags & MDL_PAGES_LOCKED)
|
||||
{
|
||||
/* unlock pages */
|
||||
MmUnlockPages(Mdl);
|
||||
}
|
||||
|
||||
/* now free the mdl */
|
||||
IoFreeMdl(Mdl);
|
||||
|
||||
/* get device info */
|
||||
DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
ASSERT(DeviceInfo);
|
||||
|
@ -483,6 +577,9 @@ WdmAudReadWrite(
|
|||
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 */
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
|
||||
#include "interface.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PMDL Mdl;
|
||||
ULONG Length;
|
||||
ULONG Function;
|
||||
}WDMAUD_COMPLETION_CONTEXT, *PWDMAUD_COMPLETION_CONTEXT;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HANDLE Handle;
|
||||
|
|
Loading…
Reference in a new issue