Beispiel #1
1
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;
}
Beispiel #2
0
NTSTATUS
NTAPI
PcRequestNewPowerState(
    IN  PDEVICE_OBJECT DeviceObject,
    IN  DEVICE_POWER_STATE RequestedNewState)
{
    KEVENT Event;
    NTSTATUS Status;
    POWER_STATE PowerState;
    PPCLASS_DEVICE_EXTENSION DeviceExt;

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!DeviceObject || !RequestedNewState)
        return STATUS_INVALID_PARAMETER;

    DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);

    PowerState.DeviceState = RequestedNewState;
    PowerState.SystemState = PowerSystemUnspecified;

    Status = PoRequestPowerIrp(DeviceExt->PhysicalDeviceObject, IRP_MN_SET_POWER, PowerState, PwrCompletionCallback, (PVOID)&Event, NULL);
    if (NT_SUCCESS(Status))
    {
        KeWaitForSingleObject((PVOID)&Event, Executive, KernelMode, FALSE, NULL);
    }


    return Status;
}
Beispiel #3
0
NTSTATUS
NTAPI
PcForwardIrpSynchronous(
    IN  PDEVICE_OBJECT DeviceObject,
    IN  PIRP Irp)
{
    KEVENT Event;
    PPCLASS_DEVICE_EXTENSION DeviceExt;
    NTSTATUS Status;

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    // initialize the notification event
    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    IoCopyCurrentIrpStackLocationToNext(Irp);

    IoSetCompletionRoutine(Irp, CompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE);

    // now call the driver
    Status = IoCallDriver(DeviceExt->PrevDeviceObject, Irp);
    // did the request complete yet
    if (Status == STATUS_PENDING)
    {
        // not yet, lets wait a bit
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        Status = Irp->IoStatus.Status;
    }
    return Status;
}
Beispiel #4
0
//
//  This is called from DriverEntry so that PortCls can take care of some
//  IRPs and map some others to the main KS driver. In most cases this will
//  be the first function called by an audio driver.
//
//  First 2 parameters are from DriverEntry.
//
//  The AddDevice parameter is a driver-supplied pointer to a function which
//  typically then calls PcAddAdapterDevice (see below.)
//
NTSTATUS
NTAPI
PcInitializeAdapterDriver(
    IN  PDRIVER_OBJECT DriverObject,
    IN  PUNICODE_STRING RegistryPathName,
    IN  PDRIVER_ADD_DEVICE AddDevice)
{
    DPRINT("PcInitializeAdapterDriver\n");
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    // Our IRP handlers
    DPRINT("Setting IRP handlers\n");
    DriverObject->MajorFunction[IRP_MJ_CREATE] = PcDispatchIrp;
    DriverObject->MajorFunction[IRP_MJ_PNP] = PcDispatchIrp;
    DriverObject->MajorFunction[IRP_MJ_POWER] = PcDispatchIrp;
    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = PcDispatchIrp;
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = PcDispatchIrp;

    // The driver-supplied AddDevice
    DriverObject->DriverExtension->AddDevice = AddDevice;

    // KS handles these
    DPRINT("Setting KS function handlers\n");
    KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
    KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
    KsSetMajorFunctionHandler(DriverObject, IRP_MJ_FLUSH_BUFFERS);
    KsSetMajorFunctionHandler(DriverObject, IRP_MJ_QUERY_SECURITY);
    KsSetMajorFunctionHandler(DriverObject, IRP_MJ_READ);
    KsSetMajorFunctionHandler(DriverObject, IRP_MJ_SET_SECURITY);
    KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);

    DPRINT("PortCls has finished initializing the adapter driver\n");

    return STATUS_SUCCESS;
}
Beispiel #5
0
NTSTATUS
NTAPI
CPortWavePci::NewMasterDmaChannel(
    OUT PDMACHANNEL *DmaChannel,
    IN PUNKNOWN OuterUnknown OPTIONAL,
    IN POOL_TYPE PoolType,
    IN PRESOURCELIST ResourceList OPTIONAL,
    IN BOOLEAN ScatterGather,
    IN BOOLEAN Dma32BitAddresses,
    IN BOOLEAN Dma64BitAddresses,
    IN BOOLEAN IgnoreCount,
    IN DMA_WIDTH DmaWidth,
    IN DMA_SPEED DmaSpeed,
    IN ULONG  MaximumLength,
    IN ULONG  DmaPort)
{
    NTSTATUS Status;
    DEVICE_DESCRIPTION DeviceDescription;

    DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", this);
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    Status = PcDmaMasterDescription(ResourceList, ScatterGather, Dma32BitAddresses, IgnoreCount, Dma64BitAddresses, DmaWidth, DmaSpeed, MaximumLength, DmaPort, &DeviceDescription);
    if (NT_SUCCESS(Status))
    {
        return PcNewDmaChannel(DmaChannel, OuterUnknown, PoolType, &DeviceDescription, m_pDeviceObject);
    }

    return Status;
}
Beispiel #6
0
NTSTATUS
NTAPI
CPortWaveCyclic::NewSlaveDmaChannel(
    OUT PDMACHANNELSLAVE* OutDmaChannel,
    IN  PUNKNOWN OuterUnknown,
    IN  PRESOURCELIST ResourceList OPTIONAL,
    IN  ULONG DmaIndex,
    IN  ULONG MaximumLength,
    IN  BOOLEAN DemandMode,
    IN  DMA_SPEED DmaSpeed)
{
    DEVICE_DESCRIPTION DeviceDescription;
    PDMACHANNEL DmaChannel;
    NTSTATUS Status;

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    // FIXME
    // Check for F-Type DMA Support
    //

    Status = PcDmaSlaveDescription(ResourceList, DmaIndex, DemandMode, TRUE, DmaSpeed, MaximumLength, 0, &DeviceDescription);
    if (NT_SUCCESS(Status))
    {
        Status = PcNewDmaChannel(&DmaChannel, OuterUnknown, NonPagedPool, &DeviceDescription, m_pDeviceObject);
        if (NT_SUCCESS(Status))
        {
            Status = DmaChannel->QueryInterface(IID_IDmaChannelSlave, (PVOID*)OutDmaChannel);
            DmaChannel->Release();
        }
    }

    return Status;
}
Beispiel #7
0
NTSTATUS
NTAPI
CPortDMus::NewRegistryKey(
    OUT PREGISTRYKEY  *OutRegistryKey,
    IN PUNKNOWN  OuterUnknown  OPTIONAL,
    IN ULONG  RegistryKeyType,
    IN ACCESS_MASK  DesiredAccess,
    IN POBJECT_ATTRIBUTES  ObjectAttributes  OPTIONAL,
    IN ULONG  CreateOptions  OPTIONAL,
    OUT PULONG  Disposition  OPTIONAL)
{
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!m_bInitialized)
    {
        DPRINT("IPortDMus_fnNewRegistryKey called w/o initialized\n");
        return STATUS_UNSUCCESSFUL;
    }

    return PcNewRegistryKey(OutRegistryKey,
                            OuterUnknown,
                            RegistryKeyType,
                            DesiredAccess,
                            m_pDeviceObject,
                            (ISubdevice*)this,
                            ObjectAttributes,
                            CreateOptions,
                            Disposition);
}
Beispiel #8
0
NTSTATUS
NTAPI
PcRegisterAdapterPowerManagement(
    IN  PUNKNOWN pUnknown,
    IN  PVOID pvContext)
{
    NTSTATUS Status;
    PDEVICE_OBJECT pDeviceObject;
    PPCLASS_DEVICE_EXTENSION DeviceExt;
    IAdapterPowerManagement * pPower;

    DPRINT("PcRegisterAdapterPowerManagement pUnknown %p pvContext %p\n", pUnknown, pvContext);
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!pUnknown || !pvContext)
        return STATUS_INVALID_PARAMETER;


    pDeviceObject = (PDEVICE_OBJECT)pvContext;
    DeviceExt = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension;

    Status = pUnknown->QueryInterface(IID_IAdapterPowerManagement, (PVOID*)&pPower);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("PcRegisterAdapterPowerManagement no IAdapterPowerManagement interface %x\n", Status);
        DeviceExt->AdapterPowerManagement = NULL;
        return STATUS_SUCCESS;
    }

    DeviceExt->AdapterPowerManagement = pPower;
    DPRINT("PcRegisterAdapterPowerManagement success %x\n", Status);
    return STATUS_SUCCESS;
}
Beispiel #9
0
NTSTATUS
NTAPI
CPortWaveCyclic::NewMasterDmaChannel(
    OUT PDMACHANNEL* DmaChannel,
    IN  PUNKNOWN OuterUnknown,
    IN  PRESOURCELIST ResourceList OPTIONAL,
    IN  ULONG MaximumLength,
    IN  BOOLEAN Dma32BitAddresses,
    IN  BOOLEAN Dma64BitAddresses,
    IN  DMA_WIDTH DmaWidth,
    IN  DMA_SPEED DmaSpeed)
{
    NTSTATUS Status;
    DEVICE_DESCRIPTION DeviceDescription;

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    Status = PcDmaMasterDescription(ResourceList, (Dma32BitAddresses | Dma64BitAddresses), Dma32BitAddresses, 0, Dma64BitAddresses, DmaWidth, DmaSpeed, MaximumLength, 0, &DeviceDescription);
    if (NT_SUCCESS(Status))
    {
        return PcNewDmaChannel(DmaChannel, OuterUnknown, NonPagedPool, &DeviceDescription, m_pDeviceObject);
    }

    return Status;
}
Beispiel #10
0
VOID
NTAPI
CPortDMus::RegisterServiceGroup(
    IN PSERVICEGROUP  ServiceGroup)
{
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    m_ServiceGroup = ServiceGroup;

    ServiceGroup->AddMember(PSERVICESINK(this));
}
Beispiel #11
0
NTSTATUS
NTAPI
CPortWaveCyclic::GetDeviceProperty(
    IN DEVICE_REGISTRY_PROPERTY  DeviceRegistryProperty,
    IN ULONG  BufferLength,
    OUT PVOID  PropertyBuffer,
    OUT PULONG  ReturnLength)
{
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
}
Beispiel #12
0
void
NTAPI
CPortWavePci::AddEventToEventList(
    IN PKSEVENT_ENTRY EventEntry)
{
    KIRQL OldIrql;

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    KeAcquireSpinLock(&m_EventListLock, &OldIrql);
    InsertTailList(&m_EventList, &EventEntry->ListEntry);
    KeReleaseSpinLock(&m_EventListLock, OldIrql);
}
Beispiel #13
0
NTSTATUS
NTAPI
CPortWaveCyclic::NewRegistryKey(
    OUT PREGISTRYKEY  *OutRegistryKey,
    IN PUNKNOWN  OuterUnknown  OPTIONAL,
    IN ULONG  RegistryKeyType,
    IN ACCESS_MASK  DesiredAccess,
    IN POBJECT_ATTRIBUTES  ObjectAttributes  OPTIONAL,
    IN ULONG  CreateOptions  OPTIONAL,
    OUT PULONG  Disposition  OPTIONAL)
{
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    return PcNewRegistryKey(OutRegistryKey, OuterUnknown, RegistryKeyType, DesiredAccess, m_pDeviceObject, (ISubdevice*)this, ObjectAttributes, CreateOptions, Disposition);
}
Beispiel #14
0
NTSTATUS
NTAPI
PcNewPort(
    OUT PPORT* OutPort,
    IN  REFCLSID ClassId)
{
    NTSTATUS Status;
    UNICODE_STRING GuidString;

    DPRINT("PcNewPort entered\n");

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!OutPort)
    {
        DPRINT("PcNewPort was supplied a NULL OutPort parameter\n");
        return STATUS_INVALID_PARAMETER;
    }

    if (IsEqualGUIDAligned(ClassId, CLSID_PortMidi))
        Status = NewPortDMus(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortDMus))
        Status = NewPortDMus(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortTopology))
        Status = NewPortTopology(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortWaveCyclic))
        Status = NewPortWaveCyclic(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortWavePci))
        Status = NewPortWavePci(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortWaveRT))
        Status = NewPortWaveRT(OutPort);
    else
    {

        if (RtlStringFromGUID(ClassId, &GuidString) == STATUS_SUCCESS)
        {
            DPRINT("unknown interface %S\n", GuidString.Buffer);
            RtlFreeUnicodeString(&GuidString);
        }

        Status = STATUS_NOT_SUPPORTED;
        return Status;
     }
    DPRINT("PcNewPort Status %lx\n", Status);

    return Status;
}
Beispiel #15
0
NTSTATUS
NTAPI
CPortDMus::GetDeviceProperty(
    IN DEVICE_REGISTRY_PROPERTY  DeviceRegistryProperty,
    IN ULONG  BufferLength,
    OUT PVOID  PropertyBuffer,
    OUT PULONG  ReturnLength)
{
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!m_bInitialized)
    {
        DPRINT("IPortDMus_fnNewRegistryKey called w/o initialized\n");
        return STATUS_UNSUCCESSFUL;
    }

    return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
}
Beispiel #16
0
NTSTATUS
NTAPI
PcNewMiniport(
    OUT PMINIPORT* OutMiniport,
    IN  REFCLSID ClassId)
{
    NTSTATUS Status = STATUS_INVALID_PARAMETER;

    DPRINT("PcNewMiniport entered\n");
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!OutMiniport)
    {
        DPRINT("PcNewMiniport was supplied a NULL OutPort parameter\n");
        return STATUS_INVALID_PARAMETER;
    }

    if (IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverDMusUART) ||
        IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverUart) ||
        IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverDMusUARTCapture))
    {
        Status = NewMiniportDMusUART(OutMiniport, ClassId);
    }
    else if (IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverFmSynth) ||
             IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverFmSynthWithVol))
    {
        Status = NewMiniportFmSynth(OutMiniport, ClassId);
    }
    else
    {
        Status = STATUS_INVALID_PARAMETER;
    }

    DPRINT("PcNewMiniport Status %x\n", Status);
    return Status;
}
Beispiel #17
0
NTSTATUS
NTAPI
CPortWavePci::Init(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp,
    IN PUNKNOWN  UnknownMiniport,
    IN PUNKNOWN  UnknownAdapter  OPTIONAL,
    IN PRESOURCELIST  ResourceList)
{
    IMiniportWavePci * Miniport;
    PSERVICEGROUP ServiceGroup = 0;
    NTSTATUS Status;
    PPINCOUNT PinCount;
    PPOWERNOTIFY PowerNotify;

    DPRINT("IPortWavePci_fnInit entered with This %p, DeviceObject %p Irp %p UnknownMiniport %p, UnknownAdapter %p ResourceList %p\n", 
            this, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList);
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    Status = UnknownMiniport->QueryInterface(IID_IMiniportWavePci, (PVOID*)&Miniport);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n");
        return STATUS_INVALID_PARAMETER;
    }

    // Initialize port object
    m_Miniport = Miniport;
    m_pDeviceObject = DeviceObject;

    InitializeListHead(&m_EventList);
    KeInitializeSpinLock(&m_EventListLock);

    // increment reference on miniport adapter
    Miniport->AddRef();

    Status = Miniport->Init(UnknownAdapter, ResourceList, this, &ServiceGroup);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("IPortWavePci_fnInit failed with %x\n", Status);

        // release reference on miniport adapter
        Miniport->Release();
        return Status;
    }

    // check if the miniport adapter provides a valid device descriptor
    Status = Miniport->GetDescription(&m_pDescriptor);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("failed to get description\n");
        Miniport->Release();
        return Status;
    }

   // create the subdevice descriptor
    Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, 
                                         3,
                                         InterfaceGuids,
                                         0, 
                                         NULL,
                                         2, 
                                         WavePciPropertySet,
                                         0,
                                         0,
                                         0,
                                         NULL,
                                         0,
                                         NULL,
                                         m_pDescriptor);


    if (!NT_SUCCESS(Status))
    {
        DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status);
        Miniport->Release();
        return Status;
    }

    // did we get a service group
   if (ServiceGroup)
    {
        // store service group in context
        m_ServiceGroup = ServiceGroup;

        // add ourselves to service group which is called when miniport receives an isr
        m_ServiceGroup->AddMember(PSERVICESINK(this));

        // increment reference on service group
        m_ServiceGroup->AddRef();
    }

    // store for node property requests
    m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport;

    // check if it supports IPinCount interface
    Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount);
    if (NT_SUCCESS(Status))
    {
        // store IPinCount interface
        m_pPinCount = PinCount;
    }

    // does the Miniport adapter support IPowerNotify interface*/
    Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify);
    if (NT_SUCCESS(Status))
    {
        // store reference
        m_pPowerNotify = PowerNotify;
    }

    DPRINT("IPortWavePci_Init successfully initialized\n");
    return STATUS_SUCCESS;
}
Beispiel #18
0
NTSTATUS
NTAPI
CPortDMus::Init(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp,
    IN PUNKNOWN  UnknownMiniport,
    IN PUNKNOWN  UnknownAdapter  OPTIONAL,
    IN PRESOURCELIST  ResourceList)
{
    IMiniportDMus * Miniport = NULL;
    IMiniportMidi * MidiMiniport = NULL;
    NTSTATUS Status;
    PSERVICEGROUP ServiceGroup = NULL;
    PPINCOUNT PinCount;
    PPOWERNOTIFY PowerNotify;

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (m_bInitialized)
    {
        DPRINT("IPortDMus_Init called again\n");
        return STATUS_SUCCESS;
    }

    Status = UnknownMiniport->QueryInterface(IID_IMiniportDMus, (PVOID*)&Miniport);
    if (!NT_SUCCESS(Status))
    {
        // check for legacy interface
        Status = UnknownMiniport->QueryInterface(IID_IMiniportMidi, (PVOID*)&MidiMiniport);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("IPortDMus_Init called with invalid IMiniport adapter\n");
            return STATUS_INVALID_PARAMETER;
        }
    }

    // Initialize port object
    m_pMiniport = Miniport;
    m_pMiniportMidi = MidiMiniport;
    m_pDeviceObject = DeviceObject;
    m_bInitialized = TRUE;

    if (Miniport)
    {
        // initialize IMiniportDMus
        Status = Miniport->Init(UnknownAdapter, ResourceList, this, &ServiceGroup);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("IMiniportDMus_Init failed with %x\n", Status);
            m_bInitialized = FALSE;
            return Status;
        }

        // get the miniport device descriptor
        Status = Miniport->GetDescription(&m_pDescriptor);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("failed to get description\n");
            Miniport->Release();
            m_bInitialized = FALSE;
            return Status;
        }

        // increment reference on miniport adapter
        Miniport->AddRef();

    }
    else
    {
        // initialize IMiniportMidi
        Status = MidiMiniport->Init(UnknownAdapter, ResourceList, (IPortMidi*)this, &ServiceGroup);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("IMiniportMidi_Init failed with %x\n", Status);
            m_bInitialized = FALSE;
            return Status;
        }

        // get the miniport device descriptor
        Status = MidiMiniport->GetDescription(&m_pDescriptor);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("failed to get description\n");
            MidiMiniport->Release();
            m_bInitialized = FALSE;
            return Status;
        }

        // increment reference on miniport adapter
        MidiMiniport->AddRef();
    }

    // create the subdevice descriptor
    Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, 
                                         3,
                                         InterfaceGuids, 
                                         0, 
                                         NULL,
                                         2, 
                                         PortDMusPropertySet,
                                         0,
                                         0,
                                         0,
                                         NULL,
                                         0,
                                         NULL,
                                         m_pDescriptor);

    if (!NT_SUCCESS(Status))
    {
        DPRINT("Failed to create descriptor\n");

        if (Miniport)
            Miniport->Release();
        else
            MidiMiniport->Release();

        m_bInitialized = FALSE;
        return Status;
    }

    if (m_ServiceGroup == NULL && ServiceGroup)
    {
        // register service group
        m_ServiceGroup = ServiceGroup;
    }

    // check if it supports IPinCount interface
    Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount);
    if (NT_SUCCESS(Status))
    {
        // store IPinCount interface
        m_pPinCount = PinCount;
    }

    // does the Miniport adapter support IPowerNotify interface*/
    Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify);
    if (NT_SUCCESS(Status))
    {
        // store reference
        m_pPowerNotify = PowerNotify;
    }

    return STATUS_SUCCESS;
}
Beispiel #19
0
NTSTATUS
NTAPI
CPortWaveCyclic::Init(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp,
    IN PUNKNOWN  UnknownMiniport,
    IN PUNKNOWN  UnknownAdapter  OPTIONAL,
    IN PRESOURCELIST  ResourceList)
{
    IMiniportWaveCyclic * Miniport;
    NTSTATUS Status;
    PPINCOUNT PinCount;
    PPOWERNOTIFY PowerNotify;

    DPRINT("IPortWaveCyclic_Init entered %p\n", this);
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    Status = UnknownMiniport->QueryInterface(IID_IMiniportWaveCyclic, (PVOID*)&Miniport);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("IPortWaveCyclic_Init called with invalid IMiniport adapter\n");
        return STATUS_INVALID_PARAMETER;
    }

    // Initialize port object
    m_pMiniport = Miniport;
    m_pDeviceObject = DeviceObject;

    // initialize miniport
    Status = Miniport->Init(UnknownAdapter, ResourceList, this);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status);
        Miniport->Release();
        return Status;
    }


    // get the miniport device descriptor
    Status = Miniport->GetDescription(&m_pDescriptor);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("failed to get description\n");
        Miniport->Release();
        return Status;
    }

    // create the subdevice descriptor
    Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor,
                                         4,
                                         InterfaceGuids,
                                         0,
                                         NULL,
                                         2,
                                         WaveCyclicPropertySet,
                                         0,
                                         0,
                                         0,
                                         NULL,
                                         0,
                                         NULL,
                                         m_pDescriptor);

    if (!NT_SUCCESS(Status))
    {
        DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status);
        Miniport->Release();
        return Status;
    }

    // store for node property requests
    m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport;

    // check if it supports IPinCount interface
    Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount);
    if (NT_SUCCESS(Status))
    {
        // store IPinCount interface
        m_pPinCount = PinCount;
    }

    // does the Miniport adapter support IPowerNotify interface*/
    Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify);
    if (NT_SUCCESS(Status))
    {
        // store reference
        m_pPowerNotify = PowerNotify;
    }

    DPRINT("IPortWaveCyclic successfully initialized\n");
    return STATUS_SUCCESS;
}
Beispiel #20
0
NTSTATUS
NTAPI
CPortTopology::Init(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp,
    IN PUNKNOWN  UnknownMiniport,
    IN PUNKNOWN  UnknownAdapter  OPTIONAL,
    IN PRESOURCELIST  ResourceList)
{
    IMiniportTopology * Miniport;
    NTSTATUS Status;

    DPRINT("IPortTopology_fnInit entered This %p DeviceObject %p Irp %p UnknownMiniport %p UnknownAdapter %p ResourceList %p\n",
            this, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList);

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (m_bInitialized)
    {
        DPRINT("IPortTopology_Init called again\n");
        return STATUS_SUCCESS;
    }

    Status = UnknownMiniport->QueryInterface(IID_IMiniportTopology, (PVOID*)&Miniport);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("IPortTopology_Init called with invalid IMiniport adapter\n");
        return STATUS_INVALID_PARAMETER;
    }

    // Initialize port object
    m_pMiniport = Miniport;
    m_pDeviceObject = DeviceObject;
    m_bInitialized = TRUE;

    // now initialize the miniport driver
    Status = Miniport->Init(UnknownAdapter, ResourceList, this);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("IPortTopology_Init failed with %x\n", Status);
        m_bInitialized = FALSE;
        Miniport->Release();
        return Status;
    }

    // get the miniport device descriptor
    Status = Miniport->GetDescription(&m_pDescriptor);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("failed to get description\n");
        Miniport->Release();
        m_bInitialized = FALSE;
        return Status;
    }

    // create the subdevice descriptor
    Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor,
                                         2,
                                         InterfaceGuids,
                                         0, 
                                         NULL,
                                         2, 
                                         TopologyPropertySet,
                                         0,
                                         0,
                                         0,
                                         NULL,
                                         0,
                                         NULL,
                                         m_pDescriptor);


    DPRINT("IPortTopology_fnInit success\n");
    if (NT_SUCCESS(Status))
    {
        // store for node property requests
        m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport;
    }

    return STATUS_SUCCESS;
}
Beispiel #21
0
//
//  Typically called by a driver's AddDevice function, which is set when
//  calling PcInitializeAdapterDriver. This performs some common driver
//  operations, such as creating a device extension.
//
//  The StartDevice parameter is a driver-supplied function which gets
//  called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE.
//
NTSTATUS
NTAPI
PcAddAdapterDevice(
    IN  PDRIVER_OBJECT DriverObject,
    IN  PDEVICE_OBJECT PhysicalDeviceObject,
    IN  PCPFNSTARTDEVICE StartDevice,
    IN  ULONG MaxObjects,
    IN  ULONG DeviceExtensionSize)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT fdo;
    PDEVICE_OBJECT PrevDeviceObject;
    PPCLASS_DEVICE_EXTENSION portcls_ext = NULL;

    DPRINT("PcAddAdapterDevice called\n");
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!DriverObject || !PhysicalDeviceObject || !StartDevice)
    {
        return STATUS_INVALID_PARAMETER;
    }

    // check if the DeviceExtensionSize is provided
    if ( DeviceExtensionSize < PORT_CLASS_DEVICE_EXTENSION_SIZE )
    {
        // driver does not need a device extension 
        if ( DeviceExtensionSize != 0 )
        {
            // DeviceExtensionSize must be zero
            return STATUS_INVALID_PARAMETER;
        }
        // set size to our extension size
        DeviceExtensionSize = PORT_CLASS_DEVICE_EXTENSION_SIZE;
    }

    // create the device
    status = IoCreateDevice(DriverObject,
                            DeviceExtensionSize,
                            NULL,
                            FILE_DEVICE_KS,
                            FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
                            FALSE,
                            &fdo);

    if (!NT_SUCCESS(status))
    {
        DPRINT("IoCreateDevice() failed with status 0x%08lx\n", status);
        return status;
    }

    // Obtain the new device extension
    portcls_ext = (PPCLASS_DEVICE_EXTENSION) fdo->DeviceExtension;
    // initialize the device extension
    RtlZeroMemory(portcls_ext, DeviceExtensionSize);
    // allocate create item
    portcls_ext->CreateItems = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, MaxObjects * sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);

    if (!portcls_ext->CreateItems)
    {
        // not enough resources
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    // store max subdevice count
    portcls_ext->MaxSubDevices = MaxObjects;
    // store the physical device object
    portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject;
    // set up the start device function
    portcls_ext->StartDevice = StartDevice;
    // initialize timer lock
    KeInitializeSpinLock(&portcls_ext->TimerListLock);
    // initialize timer list
    InitializeListHead(&portcls_ext->TimerList);
    // initialize io timer
    IoInitializeTimer(fdo, PcIoTimerRoutine, NULL);
    // start the io timer
    IoStartTimer(fdo);

    // set io flags
    fdo->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
    // clear initializing flag
    fdo->Flags &= ~ DO_DEVICE_INITIALIZING;

    // allocate the device header
    status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems);
    // did we succeed
    if (!NT_SUCCESS(status))
    {
        goto cleanup;
    }

    // attach device to device stack
    PrevDeviceObject = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
    // did we succeed
    if (PrevDeviceObject)
    {
        // store the device object in the device header
        //KsSetDevicePnpBaseObject(portcls_ext->KsDeviceHeader, fdo, PrevDeviceObject);
        portcls_ext->PrevDeviceObject = PrevDeviceObject;
    }
    else
    {
        // return error code
        status = STATUS_UNSUCCESSFUL;
        goto cleanup;
    }

    // register shutdown notification
    IoRegisterShutdownNotification(PhysicalDeviceObject);

    return status;

cleanup:

    if (portcls_ext->KsDeviceHeader)
    {
        // free the device header
        KsFreeDeviceHeader(portcls_ext->KsDeviceHeader);
    }

    if (portcls_ext->CreateItems)
    {
        // free previously allocated create items
        FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
    }

    // delete created fdo
    IoDeleteDevice(fdo);


    return status;
}