Author: janderwald Date: Sat Nov 28 18:01:46 2009 New Revision: 44309
URL: http://svn.reactos.org/svn/reactos?rev=44309&view=rev Log: [PORTCLS] - Store KSOBJECT_HEADER as the first member in a struct, which ks can use to access object header. Fixes initialization of ReactOS portcls in WinXP - Partly implement power querying / setting. Fixes bsod when shutting down the system in WinXP with ReactOS portcls - Change the pin state at PASSIVE_LEVEL - Implement IOCTL_KS_RESET for CPinWaveCyclic
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp [iso-8859-1] Sat Nov 28 18:01:46 2009 @@ -16,16 +16,16 @@ PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; - - // get current irp stack - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; - - // let IrpTarget handle request - return IrpTarget->DeviceIoControl(DeviceObject, Irp); + PDISPATCH_CONTEXT DispatchContext; + + // get current irp stack + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; + + // let IrpTarget handle request + return DispatchContext->Target->DeviceIoControl(DeviceObject, Irp); }
NTSTATUS @@ -35,17 +35,17 @@ PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; - - // get current irp stack - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; - - - // let IrpTarget handle request - return IrpTarget->Read(DeviceObject, Irp); + PDISPATCH_CONTEXT DispatchContext; + + // get current irp stack + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; + + + // let IrpTarget handle request + return DispatchContext->Target->Read(DeviceObject, Irp); }
NTSTATUS @@ -55,17 +55,17 @@ PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; - - // get current irp stack - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; - - - // let IrpTarget handle request - return IrpTarget->Write(DeviceObject, Irp); + PDISPATCH_CONTEXT DispatchContext; + + // get current irp stack + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; + + + // let IrpTarget handle request + return DispatchContext->Target->Write(DeviceObject, Irp); }
NTSTATUS @@ -75,17 +75,17 @@ PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; - - // get current irp stack - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; - - - // let IrpTarget handle request - return IrpTarget->Flush(DeviceObject, Irp); + PDISPATCH_CONTEXT DispatchContext; + + // get current irp stack + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; + + + // let IrpTarget handle request + return DispatchContext->Target->Flush(DeviceObject, Irp); }
NTSTATUS @@ -95,17 +95,24 @@ PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; - - // get current irp stack - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; - - - // let IrpTarget handle request - return IrpTarget->Close(DeviceObject, Irp); + PDISPATCH_CONTEXT DispatchContext; + NTSTATUS Status; + + // get current irp stack + IoStack = IoGetCurrentIrpStackLocation(Irp); + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; + + // let IrpTarget handle request + Status = DispatchContext->Target->Close(DeviceObject, Irp); + + if (NT_SUCCESS(Status)) + { + KsFreeObjectHeader(DispatchContext->ObjectHeader); + FreeItem(DispatchContext, TAG_PORTCLASS); + } + // done + return Status; }
NTSTATUS @@ -115,17 +122,17 @@ PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; - - // get current irp stack - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; - - - // let IrpTarget handle request - return IrpTarget->QuerySecurity(DeviceObject, Irp); + PDISPATCH_CONTEXT DispatchContext; + + // get current irp stack + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; + + + // let IrpTarget handle request + return DispatchContext->Target->QuerySecurity(DeviceObject, Irp); }
NTSTATUS @@ -135,17 +142,16 @@ PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; - - // get current irp stack - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; - - - // let IrpTarget handle request - return IrpTarget->SetSecurity(DeviceObject, Irp); + PDISPATCH_CONTEXT DispatchContext; + + // get current irp stack + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; + + // let IrpTarget handle request + return DispatchContext->Target->SetSecurity(DeviceObject, Irp); }
BOOLEAN @@ -161,13 +167,13 @@ PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { - IIrpTarget * IrpTarget; - - // access IrpTarget - IrpTarget = (IIrpTarget *)FileObject->FsContext; - - // let IrpTarget handle request - return IrpTarget->FastDeviceIoControl(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject); + PDISPATCH_CONTEXT DispatchContext; + + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)FileObject->FsContext; + + // let IrpTarget handle request + return DispatchContext->Target->FastDeviceIoControl(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject); }
@@ -183,13 +189,13 @@ PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { - IIrpTarget * IrpTarget; - - // access IrpTarget - IrpTarget = (IIrpTarget *)FileObject->FsContext; - - // let IrpTarget handle request - return IrpTarget->FastRead(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); + PDISPATCH_CONTEXT DispatchContext; + + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)FileObject->FsContext; + + // let IrpTarget handle request + return DispatchContext->Target->FastRead(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); }
BOOLEAN @@ -204,12 +210,12 @@ PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { - IIrpTarget * IrpTarget; - - // access IrpTarget - IrpTarget = (IIrpTarget *)FileObject->FsContext; - // let IrpTarget handle request - return IrpTarget->FastWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); + PDISPATCH_CONTEXT DispatchContext; + + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)FileObject->FsContext; + // let IrpTarget handle request + return DispatchContext->Target->FastWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); }
static KSDISPATCH_TABLE DispatchTable = @@ -226,7 +232,6 @@ Dispatch_fnFastWrite, };
- NTSTATUS NTAPI NewDispatchObject( @@ -238,14 +243,35 @@ NTSTATUS Status; KSOBJECT_HEADER ObjectHeader; PIO_STACK_LOCATION IoStack; + PDISPATCH_CONTEXT DispatchContext;
// get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp);
- IoStack->FileObject->FsContext = (PVOID)Target; - + DispatchContext = (PDISPATCH_CONTEXT)AllocateItem(NonPagedPool, sizeof(DISPATCH_CONTEXT), TAG_PORTCLASS); + if (!DispatchContext) + return STATUS_INSUFFICIENT_RESOURCES; + + // allocate object header Status = KsAllocateObjectHeader(&ObjectHeader, CreateItemCount, CreateItem, Irp, &DispatchTable); - DPRINT("KsAllocateObjectHeader result %x\n", Status); + + if (!NT_SUCCESS(Status)) + { + // free dispatch context + FreeItem(DispatchContext, TAG_PORTCLASS); + // done + return Status; + } + + // initialize dispatch context + DispatchContext->ObjectHeader = ObjectHeader; + DispatchContext->Target = Target; + DispatchContext->CreateItem = CreateItem; + + // store dispatch context + IoStack->FileObject->FsContext = DispatchContext; + + DPRINT("KsAllocateObjectHeader result %x Target %p Context %p\n", Status, Target, DispatchContext); return Status; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp [iso-8859-1] Sat Nov 28 18:01:46 2009 @@ -223,6 +223,7 @@ CDmaChannelInit::BufferSize() { DPRINT("BufferSize %u\n", m_BufferSize); + PC_ASSERT(m_BufferSize); return m_BufferSize; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- 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] Sat Nov 28 18:01:46 2009 @@ -231,6 +231,8 @@ 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); + Status = IoConnectInterrupt(&m_Interrupt, IInterruptServiceRoutine, (PVOID)this,
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp [iso-8859-1] Sat Nov 28 18:01:46 2009 @@ -12,6 +12,13 @@
#include "private.hpp"
+typedef struct +{ + PIRP Irp; + PDEVICE_OBJECT DeviceObject; +}QUERY_POWER_CONTEXT, *PQUERY_POWER_CONTEXT; + + NTSTATUS NTAPI PortClsCreate( @@ -33,7 +40,10 @@ NTSTATUS Status; PPCLASS_DEVICE_EXTENSION DeviceExt; PIO_STACK_LOCATION IoStack; + POWER_STATE PowerState; IResourceList* resource_list = NULL; + //ULONG Index; + //PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor, UnPartialDescriptor;
DeviceExt = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension; IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -92,6 +102,14 @@ // Assign the resource list to our extension DeviceExt->resources = resource_list;
+ // store device power state + DeviceExt->DevicePowerState = PowerDeviceD0; + DeviceExt->SystemPowerState = PowerSystemWorking; + + // notify power manager of current state + PowerState = *((POWER_STATE*)&DeviceExt->DevicePowerState); + PoSetPowerState(DeviceObject, DevicePowerState, PowerState); + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; @@ -103,10 +121,9 @@ DeviceExt->resources->Release(); IoDeleteDevice(DeviceObject);
- // Do not complete? - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; + // Forward request + Status = PcForwardIrpSynchronous(DeviceObject, Irp); + return PcCompleteIrp(DeviceObject, Irp, Status);
case IRP_MN_QUERY_INTERFACE: DPRINT("IRP_MN_QUERY_INTERFACE\n"); @@ -133,13 +150,230 @@ return STATUS_UNSUCCESSFUL; }
+VOID +CALLBACK +PwrCompletionFunction( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR MinorFunction, + IN POWER_STATE PowerState, + IN PVOID Context, + IN PIO_STATUS_BLOCK IoStatus) +{ + NTSTATUS Status; + PQUERY_POWER_CONTEXT PwrContext = (PQUERY_POWER_CONTEXT)Context; + + if (NT_SUCCESS(IoStatus->Status)) + { + // forward request to lower device object + Status = PcForwardIrpSynchronous(PwrContext->DeviceObject, PwrContext->Irp); + } + else + { + // failed + Status = IoStatus->Status; + } + + // start next power irp + PoStartNextPowerIrp(PwrContext->Irp); + + // complete request + PwrContext->Irp->IoStatus.Status = Status; + IoCompleteRequest(PwrContext->Irp, IO_NO_INCREMENT); + + // free context + FreeItem(PwrContext, TAG_PORTCLASS); +} + + NTSTATUS NTAPI PortClsPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + PIO_STACK_LOCATION IoStack; + PPCLASS_DEVICE_EXTENSION DeviceExtension; + PQUERY_POWER_CONTEXT PwrContext; + POWER_STATE PowerState; + NTSTATUS Status = STATUS_SUCCESS; + DPRINT("PortClsPower called\n"); + + // get currrent stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->MinorFunction != IRP_MN_SET_POWER && IoStack->MinorFunction != IRP_MN_QUERY_POWER) + { + // just forward the request + Status = PcForwardIrpSynchronous(DeviceObject, Irp); + + // start next power irp + PoStartNextPowerIrp(Irp); + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + + + // get device extension + DeviceExtension = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension; + + // get current request type + if (IoStack->Parameters.Power.Type == DevicePowerState) + { + // request for device power state + if (DeviceExtension->DevicePowerState == IoStack->Parameters.Power.State.DeviceState) + { + // nothing has changed + if (IoStack->MinorFunction == IRP_MN_QUERY_POWER) + { + // only forward query requests + Status = PcForwardIrpSynchronous(DeviceObject, Irp); + } + + // start next power irp + PoStartNextPowerIrp(Irp); + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + + if (IoStack->MinorFunction == IRP_MN_QUERY_POWER) + { + // check if there is a registered adapter power management + if (DeviceExtension->AdapterPowerManagement) + { + // it is query if the change can be changed + PowerState = *((POWER_STATE*)&IoStack->Parameters.Power.State.DeviceState); + Status = DeviceExtension->AdapterPowerManagement->QueryPowerChangeState(PowerState); + + // sanity check + PC_ASSERT(Status == STATUS_SUCCESS); + } + + // only forward query requests + PcForwardIrpSynchronous(DeviceObject, Irp); + + // start next power irp + PoStartNextPowerIrp(Irp); + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + else + { + // set power state + PowerState = *((POWER_STATE*)&IoStack->Parameters.Power.State.DeviceState); + PoSetPowerState(DeviceObject, DevicePowerState, PowerState); + + // check if there is a registered adapter power management + if (DeviceExtension->AdapterPowerManagement) + { + // notify of a power change state + DeviceExtension->AdapterPowerManagement->PowerChangeState(PowerState); + } + + // FIXME call all registered IPowerNotify interfaces via ISubdevice interface + + // store new power state + DeviceExtension->DevicePowerState = IoStack->Parameters.Power.State.DeviceState; + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + } + else + { + // sanity check + PC_ASSERT(IoStack->Parameters.Power.Type == SystemPowerState); + + if (IoStack->MinorFunction == IRP_MN_QUERY_POWER) + { + // mark irp as pending + IoMarkIrpPending(Irp); + + // allocate power completion context + PwrContext = (PQUERY_POWER_CONTEXT)AllocateItem(NonPagedPool, sizeof(QUERY_POWER_CONTEXT), TAG_PORTCLASS); + + if (!PwrContext) + { + // no memory + PoStartNextPowerIrp(Irp); + + // complete and forget + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + + // setup power context + PwrContext->Irp = Irp; + PwrContext->DeviceObject = DeviceObject; + + // pass the irp down + PowerState = *((POWER_STATE*)IoStack->Parameters.Power.State.SystemState); + Status = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject, IoStack->MinorFunction, PowerState, PwrCompletionFunction, (PVOID)PwrContext, NULL); + + // check for success + if (!NT_SUCCESS(Status)) + { + // failed + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + + // done + return STATUS_PENDING; + } + else + { + // set power request + DeviceExtension->SystemPowerState = IoStack->Parameters.Power.State.SystemState; + + // only forward query requests + Status = PcForwardIrpSynchronous(DeviceObject, Irp); + + // start next power irp + PoStartNextPowerIrp(Irp); + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + } +} + +NTSTATUS +NTAPI +PortClsSysControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("PortClsSysControl called\n");
// TODO
@@ -152,13 +386,21 @@
NTSTATUS NTAPI -PortClsSysControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - DPRINT("PortClsSysControl called\n"); - - // TODO +PortClsShutdown( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PPCLASS_DEVICE_EXTENSION DeviceExtension; + DPRINT("PortClsShutdown called\n"); + + // get device extension + DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (DeviceExtension->AdapterPowerManagement) + { + // release adapter power management + DPRINT("Power %u\n", DeviceExtension->AdapterPowerManagement->Release()); + }
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -169,40 +411,15 @@
NTSTATUS NTAPI -PortClsShutdown( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PPCLASS_DEVICE_EXTENSION DeviceExtension; - DPRINT("PortClsShutdown called\n"); - - // get device extension - DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - if (DeviceExtension->AdapterPowerManagement) - { - // release adapter power management - DPRINT("Power %u\n", DeviceExtension->AdapterPowerManagement->Release()); - } - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI PcDispatchIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IoStack;
- DPRINT("PcDispatchIrp called - handling IRP in PortCls\n"); - IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("PcDispatchIrp called - handling IRP in PortCls MajorFunction %x MinorFunction %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
switch ( IoStack->MajorFunction ) {
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- 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] Sat Nov 28 18:01:46 2009 @@ -145,7 +145,14 @@ }
// get first stream header - Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; + + if (Irp->RequestorMode == UserMode) + Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; + else + Header = (PKSSTREAM_HEADER)Irp->UserBuffer; + + // sanity check + PC_ASSERT(Header);
// calculate num headers NumHeaders = IoStack->Parameters.DeviceIoControl.OutputBufferLength / Header->Size; @@ -156,7 +163,8 @@
// get first audio buffer Mdl = Irp->MdlAddress; - + // sanity check + PC_ASSERT(Mdl);
// store the current stream header Irp->Tail.Overlay.DriverContext[OFFSET_STREAMHEADER] = (PVOID)Header; @@ -166,7 +174,6 @@ // store current header index Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(0);
- NumData = 0; // prepare all headers for(Index = 0; Index < NumHeaders; Index++) @@ -175,7 +182,10 @@ PC_ASSERT(Header); PC_ASSERT(Mdl);
- Header->Data = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); + if (Irp->RequestorMode == UserMode) + { + Header->Data = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); + }
if (!Header->Data) { @@ -344,10 +354,13 @@ return; }
- // irp has been processed completly + // irp has been processed completly
NumData = 0; - StreamHeader = (PKSSTREAM_HEADER)m_Irp->AssociatedIrp.SystemBuffer; + if (m_Irp->RequestorMode == KernelMode) + StreamHeader = (PKSSTREAM_HEADER)m_Irp->UserBuffer; + else + StreamHeader = (PKSSTREAM_HEADER)m_Irp->AssociatedIrp.SystemBuffer;
// loop all stream headers for(Index = 0; Index < STREAMHEADER_COUNT(m_Irp); Index++)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] Sat Nov 28 18:01:46 2009 @@ -35,16 +35,11 @@ CPortPinWaveCyclic(IUnknown *OuterUnknown){} virtual ~CPortPinWaveCyclic(){}
- VOID SetState(KSSTATE State); - protected:
VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount); VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount); VOID GeneratePositionEvents(IN ULONGLONG OldOffset, IN ULONGLONG NewOffset); - NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); - NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); -
friend NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); friend NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); @@ -52,6 +47,7 @@ friend NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); friend NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); friend NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); + friend VOID CALLBACK PinSetStateWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context);
IPortWaveCyclic * m_Port; IPortFilterWaveCyclic * m_Filter; @@ -82,6 +78,8 @@ KSPIN_LOCK m_EventListLock; LIST_ENTRY m_EventList;
+ KSRESET m_ResetState; + ULONG m_Delay;
LONG m_Ref; @@ -358,6 +356,57 @@ return STATUS_NOT_SUPPORTED; }
+typedef struct +{ + CPortPinWaveCyclic *Pin; + KSSTATE NewState; + PIO_WORKITEM WorkItem; + PIRP Irp; + +}SETPIN_CONTEXT, *PSETPIN_CONTEXT; + +VOID +CALLBACK +PinSetStateWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PSETPIN_CONTEXT PinWorkContext = (PSETPIN_CONTEXT)Context; + NTSTATUS Status; + + // try set stream + Status = PinWorkContext->Pin->m_Stream->SetState(PinWorkContext->NewState); + + DPRINT1("Setting state %u %x\n", PinWorkContext->NewState, Status); + if (NT_SUCCESS(Status)) + { + // store new state + PinWorkContext->Pin->m_State = PinWorkContext->NewState; + + if (PinWorkContext->Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && PinWorkContext->Pin->m_State == KSSTATE_STOP) + { + /* FIXME complete pending irps with successfull state */ + PinWorkContext->Pin->m_IrpQueue->CancelBuffers(); + } + //HACK + //PinWorkContext->Pin->m_IrpQueue->CancelBuffers(); + } + + // store result + PinWorkContext->Irp->IoStatus.Information = sizeof(KSSTATE); + PinWorkContext->Irp->IoStatus.Status = Status; + + // complete irp + IoCompleteRequest(PinWorkContext->Irp, IO_NO_INCREMENT); + + // free work item + IoFreeWorkItem(PinWorkContext->WorkItem); + + // free work context + FreeItem(PinWorkContext, TAG_PORTCLASS); + +} +
NTSTATUS NTAPI @@ -366,10 +415,10 @@ IN PKSIDENTIFIER Request, IN OUT PVOID Data) { - NTSTATUS Status = STATUS_UNSUCCESSFUL; CPortPinWaveCyclic *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; PKSSTATE State = (PKSSTATE)Data; + PSETPIN_CONTEXT PinWorkContext;
// get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); @@ -387,25 +436,20 @@
if (Request->Flags & KSPROPERTY_TYPE_SET) { - // try set stream - Status = Pin->m_Stream->SetState(*State); - - DPRINT("Setting state %u %x\n", *State, Status); - if (NT_SUCCESS(Status)) - { - // store new state - Pin->m_State = *State; - - if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP) - { - /* FIXME complete pending irps with successfull state */ - Pin->m_IrpQueue->CancelBuffers(); - } - } - - // store result - Irp->IoStatus.Information = sizeof(KSSTATE); - return Status; + PinWorkContext = (PSETPIN_CONTEXT)AllocateItem(NonPagedPool, sizeof(PSETPIN_CONTEXT), TAG_PORTCLASS); + PC_ASSERT(PinWorkContext); + + PinWorkContext->WorkItem = IoAllocateWorkItem(IoGetCurrentIrpStackLocation(Irp)->DeviceObject); + PC_ASSERT(PinWorkContext->WorkItem); + // initialize work item context + PinWorkContext->NewState = *State; + PinWorkContext->Pin = Pin; + PinWorkContext->Irp = Irp; + + IoMarkIrpPending(Irp); + + IoQueueWorkItem(PinWorkContext->WorkItem, PinSetStateWorkerRoutine, DelayedWorkQueue, (PVOID)PinWorkContext); + return STATUS_PENDING; } else if (Request->Flags & KSPROPERTY_TYPE_GET) { @@ -413,7 +457,7 @@ *State = Pin->m_State; // store result Irp->IoStatus.Information = sizeof(KSSTATE); - + DPRINT1("Getting state %u %x\n", *State, STATUS_SUCCESS); return STATUS_SUCCESS; }
@@ -464,7 +508,7 @@ }
// new change request - PC_ASSERT(Pin->m_State == KSSTATE_STOP); + PC_ASSERT(Pin->m_State != KSSTATE_RUN); // FIXME queue a work item when Irql != PASSIVE_LEVEL PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
@@ -762,78 +806,33 @@
NTSTATUS NTAPI -CPortPinWaveCyclic::HandleKsProperty( - IN PIRP Irp) -{ - PKSPROPERTY Property; - NTSTATUS Status; - UNICODE_STRING GuidString; - PIO_STACK_LOCATION IoStack; - - IoStack = IoGetCurrentIrpStackLocation(Irp); - - DPRINT("IPortPinWave_HandleKsProperty entered\n"); - - IoStack = IoGetCurrentIrpStackLocation(Irp); - - Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); - - if (Status == STATUS_NOT_FOUND) - { - Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - RtlStringFromGUID(Property->Set, &GuidString); - DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); - RtlFreeUnicodeString(&GuidString); - } - - if (Status != STATUS_PENDING) - { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - - return Status; -} - -NTSTATUS -NTAPI -CPortPinWaveCyclic::HandleKsStream( - IN PIRP Irp) -{ - NTSTATUS Status; - ULONG Data = 0; - InterlockedIncrement((PLONG)&m_TotalPackets); - - DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); - - Status = m_IrpQueue->AddMapping(Irp, &Data); - - if (NT_SUCCESS(Status)) - { - m_Position.WriteOffset += Data; - - return STATUS_PENDING; - } - - return Status; -} - -NTSTATUS -NTAPI CPortPinWaveCyclic::DeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IoStack; + PKSPROPERTY Property; + UNICODE_STRING GuidString; NTSTATUS Status = STATUS_NOT_SUPPORTED; - + ULONG Data = 0; + KSRESET ResetValue; + + /* get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp);
- if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) { - return HandleKsProperty(Irp); + /* handle property with subdevice descriptor */ + Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); + + if (Status == STATUS_NOT_FOUND) + { + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + RtlStringFromGUID(Property->Set, &GuidString); + DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); + RtlFreeUnicodeString(&GuidString); + } } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) { @@ -846,11 +845,48 @@ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) { /// FIXME - /// handle reset state + Status = KsAcquireResetValue(Irp, &ResetValue); + DPRINT("Status %x Value %u\n", Status, ResetValue); + /* check for success */ + if (NT_SUCCESS(Status)) + { + if (ResetValue == KSRESET_BEGIN) + { + m_IrpQueue->CancelBuffers(); + m_ResetState = KSRESET_BEGIN; + } + else if (ResetValue == KSRESET_END) + { + m_ResetState = KSRESET_END; + } + } } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM) { - return HandleKsStream(Irp); + /* increment total number of packets */ + InterlockedIncrement((PLONG)&m_TotalPackets); + + DPRINT("New Packet Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); + + /* is the device not currently reset */ + if (m_ResetState == KSRESET_END) + { + /* add the mapping */ + Status = m_IrpQueue->AddMapping(Irp, &Data); + + /* check for success */ + if (NT_SUCCESS(Status)) + { + m_Position.WriteOffset += Data; + Status = STATUS_PENDING; + } + } + else + { + /* reset request is currently in progress */ + Status = STATUS_DEVICE_NOT_READY; + DPRINT1("NotReady\n"); + } } else { @@ -1146,6 +1182,9 @@ m_Descriptor.EventList = &m_EventList; m_Descriptor.EventListLock = &m_EventListLock;
+ // initialize reset state + m_ResetState = KSRESET_END; + // release subdevice descriptor Subdevice->Release();
@@ -1183,6 +1222,7 @@ m_AllocatorFraming.FrameSize = m_FrameSize;
m_Stream->Silence(SilenceBuffer, m_FrameSize); + m_Stream->Silence(m_CommonBuffer, m_CommonBufferSize);
Status = m_IrpQueue->Init(ConnectDetails, DataFormat, DeviceObject, m_FrameSize, 0, SilenceBuffer); if (!NT_SUCCESS(Status)) @@ -1203,8 +1243,8 @@ m_Port = Port; m_Filter = Filter;
- 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 acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); + //DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE));
return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp [iso-8859-1] Sat Nov 28 18:01:46 2009 @@ -107,6 +107,7 @@
if (IsEqualGUIDAligned(refiid, IID_IPortDMus) || IsEqualGUIDAligned(refiid, IID_IPortMidi) || + IsEqualGUIDAligned(refiid, IID_IPort) || IsEqualGUIDAligned(refiid, IID_IUnknown)) { *Output = PVOID(PUNKNOWN((IPortDMus*)this));
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp [iso-8859-1] Sat Nov 28 18:01:46 2009 @@ -328,7 +328,10 @@ IN PIRP Irp, IN PSUBDEVICE_DESCRIPTOR Descriptor);
- +IIrpTarget * +NTAPI +KsoGetIrpTargetFromIrp( + PIRP Irp);
#define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\ PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\ @@ -389,6 +392,9 @@ LIST_ENTRY TimerList; KSPIN_LOCK TimerListLock;
+ DEVICE_POWER_STATE DevicePowerState; + SYSTEM_POWER_STATE SystemPowerState; + } PCLASS_DEVICE_EXTENSION, *PPCLASS_DEVICE_EXTENSION;
@@ -406,4 +412,11 @@ PVOID Context; }TIMER_CONTEXT, *PTIMER_CONTEXT;
+typedef struct +{ + KSOBJECT_HEADER ObjectHeader; + IIrpTarget * Target; + PKSOBJECT_CREATE_ITEM CreateItem; +}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT; + #endif
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp [iso-8859-1] Sat Nov 28 18:01:46 2009 @@ -183,7 +183,7 @@ IIrpTarget * IrpTarget; IPort *Port; ISubdevice *SubDevice; - + PDISPATCH_CONTEXT DispatchContext;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
@@ -193,8 +193,11 @@ // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp);
+ // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; + // Get the IrpTarget - IrpTarget = (IIrpTarget*)IoStack->FileObject->FsContext; + IrpTarget = DispatchContext->Target; PC_ASSERT(IrpTarget);
// Get the parent
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] Sat Nov 28 18:01:46 2009 @@ -50,13 +50,13 @@ KsoGetIrpTargetFromIrp( PIRP Irp) { - PKSOBJECT_CREATE_ITEM CreateItem; - - // access the create item - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + PIO_STACK_LOCATION IoStack; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp);
// IIrpTarget is stored in Context member - return (IIrpTarget*)CreateItem->Context; + return (IIrpTarget*)IoStack->FileObject->FsContext; }
NTSTATUS @@ -110,6 +110,9 @@ /* try first KsPropertyHandler */ Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet);
+ if (Status != STATUS_NOT_FOUND) + return Status; + // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -119,7 +122,7 @@ // check if this a GUID_NULL request if (Status == STATUS_NOT_FOUND) { - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE) || !(Property->Property.Flags & KSPROPERTY_TYPE_TOPOLOGY)) return Status;
// check if its a request for a topology node @@ -350,16 +353,21 @@ DumpFilterDescriptor( IN PPCFILTER_DESCRIPTOR FilterDescription) { - ULONG Index; + ULONG Index, SubIndex; PPCPROPERTY_ITEM PropertyItem; + PPCEVENT_ITEM EventItem; + PPCNODE_DESCRIPTOR NodeDescriptor; UNICODE_STRING GuidString;
- DPRINT("======================\n"); - DPRINT("Descriptor Automation Table%p\n",FilterDescription->AutomationTable); + + + DPRINT1("======================\n"); + DPRINT1("Descriptor Automation Table%p\n",FilterDescription->AutomationTable);
if (FilterDescription->AutomationTable) { - DPRINT("FilterPropertiesCount %u FilterPropertySize %u Expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM)); + DPRINT1("FilterPropertiesCount %u FilterPropertySize %u Expected %u Events %u EventItemSize %u expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM), + FilterDescription->AutomationTable->EventCount, FilterDescription->AutomationTable->EventItemSize, sizeof(PCEVENT_ITEM)); if (FilterDescription->AutomationTable->PropertyCount) { PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties; @@ -367,15 +375,56 @@ for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++) { RtlStringFromGUID(*PropertyItem->Set, &GuidString); - DPRINT("Index %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags); + DPRINT("Property Index %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize); } + + EventItem = (PPCEVENT_ITEM)FilterDescription->AutomationTable->Events; + for(Index = 0; Index < FilterDescription->AutomationTable->EventCount; Index++) + { + RtlStringFromGUID(*EventItem->Set, &GuidString); + DPRINT1("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags); + + EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize); + } + } }
- - DPRINT("======================\n"); + if (FilterDescription->Nodes) + { + DPRINT1("NodeCount %u NodeSize %u expected %u\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR)); + NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes; + for(Index = 0; Index < FilterDescription->NodeCount; Index++) + { + DPRINT("Index %u AutomationTable %p\n", Index, NodeDescriptor->AutomationTable); + + if (NodeDescriptor->AutomationTable) + { + DPRINT1("Index %u EventCount %u\n", Index, NodeDescriptor->AutomationTable->EventCount); + EventItem = (PPCEVENT_ITEM)NodeDescriptor->AutomationTable->Events; + for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->EventCount; SubIndex++) + { + RtlStringFromGUID(*EventItem->Set, &GuidString); + DPRINT1("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags); + + EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize); + } + + } + + + NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize); + } + + + + } + + + + DPRINT1("======================\n"); }
NTSTATUS