[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

svn path=/trunk/; revision=44309
This commit is contained in:
Johannes Anderwald
2009-11-28 17:01:46 +00:00
parent 7171029029
commit f45f63e7c2
10 changed files with 531 additions and 166 deletions
@@ -16,16 +16,16 @@ Dispatch_fnDeviceIoControl(
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
// get current irp stack
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access IrpTarget
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->DeviceIoControl(DeviceObject, Irp);
return DispatchContext->Target->DeviceIoControl(DeviceObject, Irp);
}
NTSTATUS
@@ -35,17 +35,17 @@ Dispatch_fnRead(
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
// get current irp stack
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access IrpTarget
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->Read(DeviceObject, Irp);
return DispatchContext->Target->Read(DeviceObject, Irp);
}
NTSTATUS
@@ -55,17 +55,17 @@ Dispatch_fnWrite(
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
// get current irp stack
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access IrpTarget
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->Write(DeviceObject, Irp);
return DispatchContext->Target->Write(DeviceObject, Irp);
}
NTSTATUS
@@ -75,17 +75,17 @@ Dispatch_fnFlush(
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
// get current irp stack
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access IrpTarget
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->Flush(DeviceObject, Irp);
return DispatchContext->Target->Flush(DeviceObject, Irp);
}
NTSTATUS
@@ -95,17 +95,24 @@ Dispatch_fnClose(
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
NTSTATUS Status;
// get current irp stack
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access IrpTarget
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->Close(DeviceObject, Irp);
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 @@ Dispatch_fnQuerySecurity(
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
// get current irp stack
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access IrpTarget
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->QuerySecurity(DeviceObject, Irp);
return DispatchContext->Target->QuerySecurity(DeviceObject, Irp);
}
NTSTATUS
@@ -135,17 +142,16 @@ Dispatch_fnSetSecurity(
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
// get current irp stack
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access IrpTarget
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->SetSecurity(DeviceObject, Irp);
return DispatchContext->Target->SetSecurity(DeviceObject, Irp);
}
BOOLEAN
@@ -161,13 +167,13 @@ Dispatch_fnFastDeviceIoControl(
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
// access IrpTarget
IrpTarget = (IIrpTarget *)FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->FastDeviceIoControl(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject);
return DispatchContext->Target->FastDeviceIoControl(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject);
}
@@ -183,13 +189,13 @@ Dispatch_fnFastRead(
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
// access IrpTarget
IrpTarget = (IIrpTarget *)FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->FastRead(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
return DispatchContext->Target->FastRead(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
}
BOOLEAN
@@ -204,12 +210,12 @@ Dispatch_fnFastWrite(
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
IIrpTarget * IrpTarget;
PDISPATCH_CONTEXT DispatchContext;
// access IrpTarget
IrpTarget = (IIrpTarget *)FileObject->FsContext;
// get dispatch context
DispatchContext = (PDISPATCH_CONTEXT)FileObject->FsContext;
// let IrpTarget handle request
return IrpTarget->FastWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
return DispatchContext->Target->FastWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
}
static KSDISPATCH_TABLE DispatchTable =
@@ -226,7 +232,6 @@ static KSDISPATCH_TABLE DispatchTable =
Dispatch_fnFastWrite,
};
NTSTATUS
NTAPI
NewDispatchObject(
@@ -238,14 +243,35 @@ NewDispatchObject(
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;
}
@@ -223,6 +223,7 @@ NTAPI
CDmaChannelInit::BufferSize()
{
DPRINT("BufferSize %u\n", m_BufferSize);
PC_ASSERT(m_BufferSize);
return m_BufferSize;
}
@@ -231,6 +231,8 @@ 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);
Status = IoConnectInterrupt(&m_Interrupt,
IInterruptServiceRoutine,
(PVOID)this,
+228 -11
View File
@@ -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 @@ PortClsPnp(
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 @@ PortClsPnp(
// 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 @@ PortClsPnp(
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,21 +150,221 @@ PortClsPnp(
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");
// TODO
// get currrent stack location
IoStack = IoGetCurrentIrpStackLocation(Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
if (IoStack->MinorFunction != IRP_MN_SET_POWER && IoStack->MinorFunction != IRP_MN_QUERY_POWER)
{
// just forward the request
Status = PcForwardIrpSynchronous(DeviceObject, Irp);
return STATUS_SUCCESS;
// 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
@@ -200,10 +417,10 @@ PcDispatchIrp(
{
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 )
{
// PortCls
@@ -145,7 +145,14 @@ CIrpQueue::AddMapping(
}
// 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 @@ CIrpQueue::AddMapping(
// 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 @@ CIrpQueue::AddMapping(
// 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 @@ CIrpQueue::AddMapping(
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 @@ CIrpQueue::UpdateMapping(
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++)
@@ -35,16 +35,11 @@ public:
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 @@ protected:
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 @@ protected:
KSPIN_LOCK m_EventListLock;
LIST_ENTRY m_EventList;
KSRESET m_ResetState;
ULONG m_Delay;
LONG m_Ref;
@@ -358,6 +356,57 @@ PinWaveCyclicAudioPosition(
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 @@ PinWaveCyclicState(
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 @@ PinWaveCyclicState(
if (Request->Flags & KSPROPERTY_TYPE_SET)
{
// try set stream
Status = Pin->m_Stream->SetState(*State);
PinWorkContext = (PSETPIN_CONTEXT)AllocateItem(NonPagedPool, sizeof(PSETPIN_CONTEXT), TAG_PORTCLASS);
PC_ASSERT(PinWorkContext);
DPRINT("Setting state %u %x\n", *State, Status);
if (NT_SUCCESS(Status))
{
// store new state
Pin->m_State = *State;
PinWorkContext->WorkItem = IoAllocateWorkItem(IoGetCurrentIrpStackLocation(Irp)->DeviceObject);
PC_ASSERT(PinWorkContext->WorkItem);
// initialize work item context
PinWorkContext->NewState = *State;
PinWorkContext->Pin = Pin;
PinWorkContext->Irp = Irp;
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();
}
}
IoMarkIrpPending(Irp);
// store result
Irp->IoStatus.Information = sizeof(KSSTATE);
return Status;
IoQueueWorkItem(PinWorkContext->WorkItem, PinSetStateWorkerRoutine, DelayedWorkQueue, (PVOID)PinWorkContext);
return STATUS_PENDING;
}
else if (Request->Flags & KSPROPERTY_TYPE_GET)
{
@@ -413,7 +457,7 @@ PinWaveCyclicState(
*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 @@ PinWaveCyclicDataFormat(
}
// 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);
@@ -760,65 +804,6 @@ CPortPinWaveCyclic::NewIrpTarget(
return STATUS_UNSUCCESSFUL;
}
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(
@@ -826,14 +811,28 @@ CPortPinWaveCyclic::DeviceIoControl(
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 @@ CPortPinWaveCyclic::DeviceIoControl(
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 @@ CPortPinWaveCyclic::Init(
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 @@ CPortPinWaveCyclic::Init(
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 @@ CPortPinWaveCyclic::Init(
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;
}
@@ -107,6 +107,7 @@ CPortDMus::QueryInterface(
if (IsEqualGUIDAligned(refiid, IID_IPortDMus) ||
IsEqualGUIDAligned(refiid, IID_IPortMidi) ||
IsEqualGUIDAligned(refiid, IID_IPort) ||
IsEqualGUIDAligned(refiid, IID_IUnknown))
{
*Output = PVOID(PUNKNOWN((IPortDMus*)this));
@@ -328,7 +328,10 @@ PcHandleDisableEventWithTable(
IN PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR Descriptor);
IIrpTarget *
NTAPI
KsoGetIrpTargetFromIrp(
PIRP Irp);
#define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\
PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\
@@ -389,6 +392,9 @@ typedef struct
LIST_ENTRY TimerList;
KSPIN_LOCK TimerListLock;
DEVICE_POWER_STATE DevicePowerState;
SYSTEM_POWER_STATE SystemPowerState;
} PCLASS_DEVICE_EXTENSION, *PPCLASS_DEVICE_EXTENSION;
@@ -406,4 +412,11 @@ typedef struct
PVOID Context;
}TIMER_CONTEXT, *PTIMER_CONTEXT;
typedef struct
{
KSOBJECT_HEADER ObjectHeader;
IIrpTarget * Target;
PKSOBJECT_CREATE_ITEM CreateItem;
}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
#endif
@@ -183,7 +183,7 @@ PinPropertyHandler(
IIrpTarget * IrpTarget;
IPort *Port;
ISubdevice *SubDevice;
PDISPATCH_CONTEXT DispatchContext;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
@@ -193,8 +193,11 @@ PinPropertyHandler(
// 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
@@ -50,13 +50,13 @@ NTAPI
KsoGetIrpTargetFromIrp(
PIRP Irp)
{
PKSOBJECT_CREATE_ITEM CreateItem;
PIO_STACK_LOCATION IoStack;
// access the create item
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
// 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 @@ PcHandlePropertyWithTable(
/* 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 @@ PcHandlePropertyWithTable(
// 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 @@ VOID
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 @@ DumpFilterDescriptor(
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);
}
}
}
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);
DPRINT("======================\n");
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