NTSTATUS NTAPI PinWavePciAllocatorFraming( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { CPortPinWavePci *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(Descriptor); PC_ASSERT(Descriptor->PortPin); PC_ASSERT_IRQL(DISPATCH_LEVEL); // cast to pin impl Pin = (CPortPinWavePci*)Descriptor->PortPin; if (Request->Flags & KSPROPERTY_TYPE_GET) { // copy pin framing RtlMoveMemory(Data, &Pin->m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); return STATUS_SUCCESS; } // not supported return STATUS_NOT_SUPPORTED; }
NTSTATUS NTAPI CPortPinWavePci::TerminatePacket() { UNIMPLEMENTED; PC_ASSERT_IRQL(DISPATCH_LEVEL); return STATUS_SUCCESS; }
NTSTATUS NTAPI CPortPinWavePci::ReleaseMapping( IN PVOID Tag) { PC_ASSERT_IRQL(DISPATCH_LEVEL); return m_IrpQueue->ReleaseMappingWithTag(Tag); }
VOID NTAPI CPortPinWavePci::RequestService() { PC_ASSERT_IRQL(DISPATCH_LEVEL); if (m_State == KSSTATE_RUN) { m_Stream->Service(); //TODO //generate events } }
NTSTATUS NTAPI CPortPinWavePci::GetMapping( IN PVOID Tag, OUT PPHYSICAL_ADDRESS PhysicalAddress, OUT PVOID *VirtualAddress, OUT PULONG ByteCount, OUT PULONG Flags) { PC_ASSERT_IRQL(DISPATCH_LEVEL); return m_IrpQueue->GetMappingWithTag(Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags); }
NTSTATUS NTAPI PinWavePciAudioPosition( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { CPortPinWavePci *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(Descriptor); PC_ASSERT(Descriptor->PortPin); PC_ASSERT_IRQL(DISPATCH_LEVEL); // cast to pin impl Pin = (CPortPinWavePci*)Descriptor->PortPin; //sanity check PC_ASSERT(Pin->m_Stream); if (Request->Flags & KSPROPERTY_TYPE_GET) { // FIXME non multithreading-safe // copy audio position RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION)); DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset); Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); return STATUS_SUCCESS; } // not supported return STATUS_NOT_SUPPORTED; }
NTSTATUS NTAPI PcCreatePinDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status; IIrpTarget *Filter; IIrpTarget *Pin; PKSOBJECT_CREATE_ITEM CreateItem; // access the create item CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(CreateItem); DPRINT("PcCreatePinDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer); Filter = (IIrpTarget*)CreateItem->Context; // sanity checks PC_ASSERT(Filter != NULL); PC_ASSERT_IRQL(PASSIVE_LEVEL); #if KS_IMPLEMENTED Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED) { DPRINT("PcCreatePinDispatch failed to reference device header\n"); FreeItem(Entry, TAG_PORTCLASS); goto cleanup; } #endif Status = Filter->NewIrpTarget(&Pin, KSSTRING_Pin, NULL, NonPagedPool, DeviceObject, Irp, NULL); DPRINT("PcCreatePinDispatch Status %x\n", Status); if (NT_SUCCESS(Status)) { // create the dispatch object // FIXME need create item for clock Status = NewDispatchObject(Irp, Pin, 0, NULL); DPRINT("Pin %p\n", Pin); } DPRINT("CreatePinWorkerRoutine completing irp %p\n", Irp); // save status in irp Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; // complete the request IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS NTAPI PinWavePciState( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { NTSTATUS Status = STATUS_UNSUCCESSFUL; CPortPinWavePci *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; PVOID FirstTag, LastTag; ULONG MappingsRevoked; PKSSTATE State = (PKSSTATE)Data; // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(Descriptor); PC_ASSERT(Descriptor->PortPin); PC_ASSERT_IRQL(DISPATCH_LEVEL); // cast to pin impl Pin = (CPortPinWavePci*)Descriptor->PortPin; //sanity check PC_ASSERT(Pin->m_Stream); 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 with successful state Pin->m_IrpQueue->CancelBuffers(); while(Pin->m_IrpQueue->GetAcquiredTagRange(&FirstTag, &LastTag)) { Status = Pin->m_Stream->RevokeMappings(FirstTag, LastTag, &MappingsRevoked); DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status, MappingsRevoked); KeStallExecutionProcessor(10); } Pin->m_Position.PlayOffset = 0; Pin->m_Position.WriteOffset = 0; } else if (Pin->m_State == KSSTATE_STOP) { Pin->m_IrpQueue->CancelBuffers(); while(Pin->m_IrpQueue->GetAcquiredTagRange(&FirstTag, &LastTag)) { Status = Pin->m_Stream->RevokeMappings(FirstTag, LastTag, &MappingsRevoked); DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status, MappingsRevoked); KeStallExecutionProcessor(10); } Pin->m_Position.PlayOffset = 0; Pin->m_Position.WriteOffset = 0; } // store result Irp->IoStatus.Information = sizeof(KSSTATE); } // store result Irp->IoStatus.Information = sizeof(KSSTATE); return Status; } else if (Request->Flags & KSPROPERTY_TYPE_GET) { // get current stream state *State = Pin->m_State; // store result Irp->IoStatus.Information = sizeof(KSSTATE); return STATUS_SUCCESS; } // unsupported request return STATUS_NOT_SUPPORTED; }