Author: janderwald
Date: Mon Nov 1 22:21:24 2010
New Revision: 49417
URL:
http://svn.reactos.org/svn/reactos?rev=49417&view=rev
Log:
[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)
Modified:
trunk/reactos/drivers/ksfilter/ks/irp.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
Modified: trunk/reactos/drivers/ksfilter/ks/irp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Mon Nov 1 22:21:24 2010
@@ -898,10 +898,6 @@
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 @@
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 @@
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 @@
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 @@
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;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp [iso-8859-1] Mon Nov 1
22:21:24 2010
@@ -232,21 +232,21 @@
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;
}
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] Mon Nov 1
22:21:24 2010
@@ -293,7 +293,6 @@
{
PKSSTREAM_HEADER StreamHeader;
ULONG Size, NumData, Index;
- //PMDL CurMdl, NextMdl;
if (!m_Irp)
{
@@ -340,8 +339,7 @@
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 @@
// 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);
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Mon Nov 1
22:21:24 2010
@@ -384,6 +384,91 @@
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 @@
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);
@@ -413,6 +512,11 @@
/* 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;
@@ -440,16 +544,6 @@
Irp->MdlAddress = Mdl;
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;
@@ -483,6 +577,9 @@
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 */
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Mon Nov 1
22:21:24 2010
@@ -18,6 +18,14 @@
typedef struct
{
+ PMDL Mdl;
+ ULONG Length;
+ ULONG Function;
+}WDMAUD_COMPLETION_CONTEXT, *PWDMAUD_COMPLETION_CONTEXT;
+
+
+typedef struct
+{
HANDLE Handle;
SOUND_DEVICE_TYPE Type;
ULONG FilterId;