コード例 #1
1
ファイル: adapter.cpp プロジェクト: GYGit/reactos
NTSTATUS
NTAPI
PcRegisterSubdevice(
    IN  PDEVICE_OBJECT DeviceObject,
    IN  PWCHAR Name,
    IN  PUNKNOWN Unknown)
{
    PPCLASS_DEVICE_EXTENSION DeviceExt;
    NTSTATUS Status;
    ISubdevice *SubDevice;
    UNICODE_STRING SymbolicLinkName;
    PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
    ULONG Index;
    UNICODE_STRING RefName;
    PSYMBOLICLINK_ENTRY SymEntry;

    DPRINT("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown);

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    // check if all parameters are valid
    if (!DeviceObject || !Name || !Unknown)
    {
        DPRINT("PcRegisterSubdevice invalid parameter\n");
        return STATUS_INVALID_PARAMETER;
    }

    // get device extension
    DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    if (!DeviceExt)
    {
        // should not happen
        DbgBreakPoint();
        return STATUS_UNSUCCESSFUL;
    }

    // look up our undocumented interface
    Status = Unknown->QueryInterface(IID_ISubdevice, (LPVOID*)&SubDevice);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("No ISubdevice interface\n");
        // the provided port driver doesnt support ISubdevice
        return STATUS_INVALID_PARAMETER;
    }

    // get the subdevice descriptor
    Status = SubDevice->GetDescriptor(&SubDeviceDescriptor);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Failed to get subdevice descriptor %x\n", Status);
        SubDevice->Release();
        return STATUS_UNSUCCESSFUL;
    }

    // add an create item to the device header
    Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PcCreateItemDispatch, (PVOID)SubDevice, Name, NULL);
    if (!NT_SUCCESS(Status))
    {
        // failed to attach
        SubDevice->Release();
        DPRINT("KsAddObjectCreateItemToDeviceHeader failed with %x\n", Status);
        return Status;
    }

    // initialize reference string
    RtlInitUnicodeString(&RefName, Name);
    RtlInitUnicodeString(&SubDeviceDescriptor->RefString, Name);

    for(Index = 0; Index < SubDeviceDescriptor->InterfaceCount; Index++)
    {
        // FIXME
        // check if reference string with that name already exists
        
        Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject,
                                           &SubDeviceDescriptor->Interfaces[Index],
                                           &RefName,
                                           &SymbolicLinkName);

        if (NT_SUCCESS(Status))
        {
            // activate device interface
            IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
            // allocate symbolic link entry
            SymEntry = (PSYMBOLICLINK_ENTRY)AllocateItem(NonPagedPool, sizeof(SYMBOLICLINK_ENTRY), TAG_PORTCLASS);
            if (SymEntry)
            {
                // initialize symbolic link item
                RtlInitUnicodeString(&SymEntry->SymbolicLink, SymbolicLinkName.Buffer);
                // store item
                InsertTailList(&SubDeviceDescriptor->SymbolicLinkList, &SymEntry->Entry);
            }
            else
            {
                // allocating failed
                RtlFreeUnicodeString(&SymbolicLinkName);
            }
        }
    }

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

    return STATUS_SUCCESS;
}
コード例 #2
0
ファイル: port_topology.cpp プロジェクト: hoangduit/reactos
NTSTATUS
NTAPI
PcCreateItemDispatch(
    IN  PDEVICE_OBJECT DeviceObject,
    IN  PIRP Irp)
{
    NTSTATUS Status;
    ISubdevice * SubDevice;
    IIrpTarget *Filter;
    PKSOBJECT_CREATE_ITEM CreateItem, PinCreateItem;

    // access the create item
    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);

    DPRINT("PcCreateItemDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer);

    // get the subdevice
    SubDevice = (ISubdevice*)CreateItem->Context;

    // sanity checks
    PC_ASSERT(SubDevice != NULL);


#if KS_IMPLEMENTED
    Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
    if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)
    {
        DPRINT("PcCreateItemDispatch failed to reference device header\n");

        FreeItem(Entry, TAG_PORTCLASS);
        goto cleanup;
    }
#endif

    // get filter object 
    Status = SubDevice->NewIrpTarget(&Filter,
                                     NULL,
                                     NULL,
                                     NonPagedPool,
                                     DeviceObject,
                                     Irp,
                                     NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Failed to get filter object\n");
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return Status;
    }

    // allocate pin create item
    PinCreateItem = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);
    if (!PinCreateItem)
    {
        // not enough memory
        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    // initialize pin create item
    PinCreateItem->Context = (PVOID)Filter;
    PinCreateItem->Create = PcCreatePinDispatch;
    RtlInitUnicodeString(&PinCreateItem->ObjectClass, KSSTRING_Pin);
    // FIXME copy security descriptor

    // now allocate a dispatch object
    Status = NewDispatchObject(Irp, Filter, 1, PinCreateItem);

    // complete request
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}
コード例 #3
0
ファイル: propertyhandler.cpp プロジェクト: reactos/reactos
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;
}
コード例 #4
0
ファイル: pin_wavepci.cpp プロジェクト: Moteesh/reactos
NTSTATUS
NTAPI
CPortPinWavePci::Init(
    IN PPORTWAVEPCI Port,
    IN PPORTFILTERWAVEPCI Filter,
    IN KSPIN_CONNECT * ConnectDetails,
    IN KSPIN_DESCRIPTOR * KsPinDescriptor,
    IN PDEVICE_OBJECT DeviceObject)
{
    NTSTATUS Status;
    PKSDATAFORMAT DataFormat;
    BOOLEAN Capture;
    ISubdevice * Subdevice = NULL;
    PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL;

    // check if it is a source / sink pin
    if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
    {
        // sink pin
        Capture = FALSE;
    }
    else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
    {
        // source pin
        Capture = TRUE;
    }
    else
    {
        DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
        DbgBreakPoint();
        while(TRUE);
    }

    // add port / filter reference
    Port->AddRef();
    Filter->AddRef();

    // initialize pin
    m_Port = Port;
    m_Filter = Filter;
    m_KsPinDescriptor = KsPinDescriptor;
    m_ConnectDetails = ConnectDetails;
    m_Miniport = GetWavePciMiniport(Port);
    m_DeviceObject = DeviceObject;
    m_State = KSSTATE_STOP;
    m_Capture = Capture;

    DPRINT("IPortPinWavePci_fnInit entered\n");

    // get dataformat
    DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);

    // allocate data format
    m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
    if (!m_Format)
    {
        // release references
        m_Port->Release();
        m_Filter->Release();

        // no dangling pointers
        Port = NULL;
        Filter = NULL;

        // failed to allocate data format
        return STATUS_INSUFFICIENT_RESOURCES;
    }

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

    // allocate new stream
    Status = m_Miniport->NewStream(&m_Stream,
                                   NULL,
                                   NonPagedPool,
                                   PPORTWAVEPCISTREAM(this),
                                   ConnectDetails->PinId,
                                   Capture,
                                   m_Format,
                                   &m_DmaChannel,
                                   &m_ServiceGroup);

    DPRINT("IPortPinWavePci_fnInit Status %x\n", Status);

    if (!NT_SUCCESS(Status))
    {
        // free references
        Port->Release();
        Filter->Release();

        // free data format
        FreeItem(m_Format, TAG_PORTCLASS);

        // no dangling pointers
        m_Port = NULL;
        m_Filter = NULL;
        m_Format = NULL;

        // failed to allocate stream
        return Status;
    }

    // get allocator requirements for pin
    Status = m_Stream->GetAllocatorFraming(&m_AllocatorFraming);
    if (NT_SUCCESS(Status))
    {
        DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n",
               m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment);
    }

    // allocate new irp queue
    Status = NewIrpQueue(&m_IrpQueue);
    if (!NT_SUCCESS(Status))
    {
        // free references
        Port->Release();
        Filter->Release();
        m_Stream->Release();

        // free data format
        FreeItem(m_Format, TAG_PORTCLASS);

        // no dangling pointers
        m_Port = NULL;
        m_Filter = NULL;
        m_Format = NULL;
        m_Stream = NULL;

        // failed to allocate irp queue
        return Status;
    }

    // initialize irp queue
    Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment, TRUE);
    if (!NT_SUCCESS(Status))
    {
        // this should never happen
        ASSERT(0);
    }

    // get subdevice interface
    Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice);

    if (!NT_SUCCESS(Status))
    {
        // this function should never fail
        ASSERT(0);
    }

    // get subdevice descriptor
    Status = Subdevice->GetDescriptor(&SubDeviceDescriptor);
    if (!NT_SUCCESS(Status))
    {
        // this function should never fail
        ASSERT(0);
    }

    // release subdevice
    Subdevice->Release();

    /* set up subdevice descriptor */
    RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR));
    m_Descriptor.FilterPropertySet = PinWavePciPropertySet;
    m_Descriptor.FilterPropertySetCount = sizeof(PinWavePciPropertySet) / sizeof(KSPROPERTY_SET);
    m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream;
    m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor;
    m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport;
    m_Descriptor.PortPin = (PVOID)this;

    if (m_ServiceGroup)
    {
        Status = m_ServiceGroup->AddMember(PSERVICESINK(this));
        if (!NT_SUCCESS(Status))
        {
            // free references
            m_Stream->Release();
            Port->Release();
            Filter->Release();

            // free data format
            FreeItem(m_Format, TAG_PORTCLASS);

            // no dangling pointers
            m_Stream = NULL;
            m_Port = NULL;
            m_Filter = NULL;
            m_Format = NULL;

            // failed to add to service group
            return Status;
        }
    }


    return STATUS_SUCCESS;
}