Beispiel #1
0
NTSTATUS
NTAPI
PcHandlePropertyWithTable(
    IN PIRP Irp,
    IN ULONG PropertySetCount,
    IN PKSPROPERTY_SET PropertySet,
    IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
{
    PIO_STACK_LOCATION IoStack;

    // get current irp stack location
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
    {
        // certainly an invalid request
        return STATUS_INVALID_PARAMETER;
    }

    // store device descriptor
    KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;


    // then try KsPropertyHandler
    return KsPropertyHandler(Irp, PropertySetCount, PropertySet);
}
Beispiel #2
0
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;
}
Beispiel #3
0
NTSTATUS
NTAPI
TopologyPropertyHandler(
    IN PIRP Irp,
    IN PKSIDENTIFIER  Request,
    IN OUT PVOID  Data)
{
    PSUBDEVICE_DESCRIPTOR Descriptor;

    Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);

    return KsTopologyPropertyHandler(Irp, Request, Data, Descriptor->Topology);
}
Beispiel #4
0
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;
}
Beispiel #5
0
NTSTATUS
NTAPI
PropertyItemDispatch(
    IN PIRP Irp,
    IN PKSIDENTIFIER  Request,
    IN OUT PVOID  Data)
{
    PPCPROPERTY_REQUEST PropertyRequest;
    PSUBDEVICE_DESCRIPTOR Descriptor;
    PKSPROPERTY Property;
    PPCNODE_DESCRIPTOR NodeDescriptor;
    PKSNODEPROPERTY NodeProperty;
    PKSPROPERTY_SET PropertySet;
    PPCPROPERTY_ITEM PropertyItem;
    PPCAUTOMATION_TABLE NodeAutomation;
    PIO_STACK_LOCATION IoStack;
    ULONG InstanceSize, ValueSize, Index;
    PVOID Instance;
    NTSTATUS Status;

    // allocate a property request
    PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS);
    if (!PropertyRequest)
        return STATUS_INSUFFICIENT_RESOURCES;

    // grab device descriptor
    Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);

    // get current irp stack
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    // get input property request
    Property = (PKSPROPERTY)Request;

    // get property set
    PropertySet = (PKSPROPERTY_SET)KSPROPERTY_SET_IRP_STORAGE(Irp);

    // sanity check
    PC_ASSERT(Descriptor);
    PC_ASSERT(Descriptor->UnknownMiniport);

    // get instance / value size
    InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength;
    Instance = Request;
    ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength;

    // initialize property request
    PropertyRequest->MajorTarget = Descriptor->UnknownMiniport;
    PropertyRequest->MinorTarget = Descriptor->UnknownStream;
    PropertyRequest->Irp = Irp;
    PropertyRequest->Verb = Property->Flags;


    // check if this is filter / pin property request
    if (!(Property->Flags & KSPROPERTY_TYPE_TOPOLOGY))
    {
        // adjust input buffer size
        InstanceSize -= sizeof(KSPROPERTY);
        Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSPROPERTY));

        // filter / pin property request dont use node field
        PropertyRequest->Node = MAXULONG;
    }
    else if (InstanceSize >= sizeof(KSNODEPROPERTY))
    {
        // request is for a node
        InstanceSize -= sizeof(KSNODEPROPERTY);
        Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSNODEPROPERTY));

        // cast node property request
        NodeProperty = (PKSNODEPROPERTY)Request;

        // store node id
        PropertyRequest->Node = NodeProperty->NodeId;
    }
    else
    {
        // invalid buffer size
        return STATUS_INVALID_BUFFER_SIZE;
    }

    // store instance size
    PropertyRequest->InstanceSize = InstanceSize;
    PropertyRequest->Instance = (InstanceSize != 0 ? Instance : NULL);

    // store value size
    PropertyRequest->ValueSize = ValueSize;
    PropertyRequest->Value = Data;

    // now scan the property set for the attached property set item stored in Relations member
    if (PropertySet)
    {
        // sanity check
        PC_ASSERT(IsEqualGUIDAligned(Property->Set, *PropertySet->Set));

        for(Index = 0; Index < PropertySet->PropertiesCount; Index++)
        {
            // check if they got the same property id
            if (PropertySet->PropertyItem[Index].PropertyId == Property->Id)
            {
                // found item
                PropertyRequest->PropertyItem = (const PCPROPERTY_ITEM*)PropertySet->PropertyItem[Index].Relations;

                // done
                break;
            }
        }
    }

    // check if there has been a property set item attached
    if (!PropertyRequest->PropertyItem)
    {
        // is topology node id valid
        if (PropertyRequest->Node < Descriptor->DeviceDescriptor->NodeCount)
        {
            // get node descriptor
            NodeDescriptor = (PPCNODE_DESCRIPTOR) ((ULONG_PTR)Descriptor->DeviceDescriptor->Nodes + PropertyRequest->Node * Descriptor->DeviceDescriptor->NodeSize);

            // get node automation table
            NodeAutomation = (PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable;

            // has it got a automation table
            if (NodeAutomation)
            {
                // now scan the properties and check if it supports this request
                PropertyItem = (PPCPROPERTY_ITEM)NodeAutomation->Properties;
                for(Index = 0; Index < NodeAutomation->PropertyCount; Index++)
                {
                    // are they same property
                    if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Set))
                    {
                        if (PropertyItem->Id == Property->Id)
                        {
                            // found match
                            PropertyRequest->PropertyItem = PropertyItem;
                            DPRINT("Using property item %p\n", PropertyItem);
                            // done
                            break;
                        }
                    }

                    // move to next property item
                    PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeAutomation->PropertyItemSize);
                }
            }
        }
    }

    if (PropertyRequest->PropertyItem && PropertyRequest->PropertyItem->Handler)
    {
        // now call the handler
        UNICODE_STRING GuidBuffer;
        RtlStringFromGUID(Property->Set, &GuidBuffer);
        DPRINT("Calling Node %lu MajorTarget %p MinorTarget %p PropertySet %S PropertyId %lu PropertyFlags %lx InstanceSize %lu ValueSize %lu Handler %p PropertyRequest %p PropertyItemFlags %lx PropertyItemId %lu\n",
               PropertyRequest->Node, PropertyRequest->MajorTarget, PropertyRequest->MinorTarget, GuidBuffer.Buffer, Property->Id, Property->Flags, PropertyRequest->InstanceSize, PropertyRequest->ValueSize,
               PropertyRequest->PropertyItem->Handler, PropertyRequest, PropertyRequest->PropertyItem->Flags, PropertyRequest->PropertyItem->Id);
        RtlFreeUnicodeString(&GuidBuffer);
        Status = PropertyRequest->PropertyItem->Handler(PropertyRequest);
        DPRINT("Status %lx ValueSize %lu Information %lu\n", Status, PropertyRequest->ValueSize, Irp->IoStatus.Information);
        Irp->IoStatus.Information = PropertyRequest->ValueSize;

        if (Status != STATUS_PENDING)
        {
            // free property request
            FreeItem(PropertyRequest, TAG_PORTCLASS);
        }
    }
    else
    {
        FreeItem(PropertyRequest, TAG_PORTCLASS);
        Status = STATUS_NOT_FOUND;
    }

    /* done */
    return Status;
}
Beispiel #6
0
NTSTATUS
NTAPI
PinPropertyHandler(
    IN PIRP Irp,
    IN PKSIDENTIFIER  Request,
    IN OUT PVOID  Data)
{
    PIO_STACK_LOCATION IoStack;
    //PKSOBJECT_CREATE_ITEM CreateItem;
    PSUBDEVICE_DESCRIPTOR Descriptor;
    IIrpTarget * IrpTarget;
    IPort *Port;
    ISubdevice *SubDevice;
    PDISPATCH_CONTEXT DispatchContext;

    NTSTATUS Status = STATUS_UNSUCCESSFUL;

    Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
    PC_ASSERT(Descriptor);

    // get current irp stack
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    // get dispatch context
    DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;

    // Get the IrpTarget
    IrpTarget = DispatchContext->Target;
    PC_ASSERT(IrpTarget);

    // Get the parent
    Status = IrpTarget->QueryInterface(IID_IPort, (PVOID*)&Port);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Failed to obtain IPort interface from filter\n");
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        return STATUS_UNSUCCESSFUL;
    }

    // Get private ISubdevice interface
    Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Failed to obtain ISubdevice interface from port driver\n");
        DbgBreakPoint();
        while(TRUE);
    }

    // get current stack location
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    switch(Request->Id)
    {
    case KSPROPERTY_PIN_CTYPES:
    case KSPROPERTY_PIN_DATAFLOW:
    case KSPROPERTY_PIN_DATARANGES:
    case KSPROPERTY_PIN_INTERFACES:
    case KSPROPERTY_PIN_MEDIUMS:
    case KSPROPERTY_PIN_COMMUNICATION:
    case KSPROPERTY_PIN_CATEGORY:
    case KSPROPERTY_PIN_NAME:
    case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
        Status = KsPinPropertyHandler(Irp, Request, Data, Descriptor->Factory.PinDescriptorCount, Descriptor->Factory.KsPinDescriptor);
        break;
    case KSPROPERTY_PIN_GLOBALCINSTANCES:
        Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, TRUE, SubDevice);
        break;
    case KSPROPERTY_PIN_CINSTANCES:
        Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, FALSE, SubDevice);
        break;
    case KSPROPERTY_PIN_NECESSARYINSTANCES:
        Status = HandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, SubDevice);
        break;

    case KSPROPERTY_PIN_DATAINTERSECTION:
        Status = HandleDataIntersection(&Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor, SubDevice);
        break;
    case KSPROPERTY_PIN_PHYSICALCONNECTION:
        Status = HandlePhysicalConnection(&Irp->IoStatus, Request, IoStack->Parameters.DeviceIoControl.InputBufferLength, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor);
        break;
    case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
        UNIMPLEMENTED
        Status = STATUS_NOT_IMPLEMENTED;
        break;
    default:
        UNIMPLEMENTED
        Status = STATUS_UNSUCCESSFUL;
    }

    // Release reference
    Port->Release();

    // Release subdevice reference
    SubDevice->Release();

    return Status;
}
Beispiel #7
0
NTSTATUS
NTAPI
PinWavePciDataFormat(
    IN PIRP Irp,
    IN PKSIDENTIFIER Request,
    IN OUT PVOID Data)
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    CPortPinWavePci *Pin;
    PSUBDEVICE_DESCRIPTOR Descriptor;
    PIO_STACK_LOCATION IoStack;

    // get current irp stack location
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    // get sub device descriptor 
    Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);

    // sanity check 
    PC_ASSERT(Descriptor);
    PC_ASSERT(Descriptor->PortPin);

    // cast to pin impl
    Pin = (CPortPinWavePci*)Descriptor->PortPin;

    //sanity check
    PC_ASSERT(Pin->m_Stream);
    PC_ASSERT(Pin->m_Format);

    if (Request->Flags & KSPROPERTY_TYPE_SET)
    {
        // try to change data format
        PKSDATAFORMAT NewDataFormat, DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
        ULONG Size = min(Pin->m_Format->FormatSize, DataFormat->FormatSize);

        if (RtlCompareMemory(DataFormat, Pin->m_Format, Size) == Size)
        {
            // format is identical
            Irp->IoStatus.Information = DataFormat->FormatSize;
            return STATUS_SUCCESS;
        }

        // new change request
        PC_ASSERT(Pin->m_State == KSSTATE_STOP);
        // FIXME queue a work item when Irql != PASSIVE_LEVEL
        PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

        // allocate new data format
        NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
        if (!NewDataFormat)
        {
            // not enough memory
            return STATUS_NO_MEMORY;
        }

        // copy new data format
        RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize);

        // set new format
        Status = Pin->m_Stream->SetFormat(NewDataFormat);
        if (NT_SUCCESS(Status))
        {
            // free old format
            FreeItem(Pin->m_Format, TAG_PORTCLASS);

            // store new format
            Pin->m_Format = NewDataFormat;
            Irp->IoStatus.Information = NewDataFormat->FormatSize;

#if 0
            PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX));
            PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO));
            PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM));
            PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX));


            DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels,
                                                                       ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample,
                                                                       ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec);
#endif

        }
        else
        {
            // failed to set format
            FreeItem(NewDataFormat, TAG_PORTCLASS);
        }


        // done
        return Status;
    }
    else if (Request->Flags & KSPROPERTY_TYPE_GET)
    {
        // get current data format
        PC_ASSERT(Pin->m_Format);

        if (Pin->m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
        {
            // buffer too small
            Irp->IoStatus.Information = Pin->m_Format->FormatSize;
            return STATUS_MORE_ENTRIES;
        }
        // copy data format
        RtlMoveMemory(Data, Pin->m_Format, Pin->m_Format->FormatSize);
        // store result size
        Irp->IoStatus.Information = Pin->m_Format->FormatSize;

        // done
        return STATUS_SUCCESS;
    }

    // unsupported request
    return STATUS_NOT_SUPPORTED;
}
Beispiel #8
0
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;
}