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; }
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; }
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; }
// // 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; }
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; }
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; }
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); }
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; }
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; }
VOID NTAPI CPortDMus::RegisterServiceGroup( IN PSERVICEGROUP ServiceGroup) { PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); m_ServiceGroup = ServiceGroup; ServiceGroup->AddMember(PSERVICESINK(this)); }
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); }
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); }
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); }
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; }
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); }
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; }
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; }
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; }
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; }
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; }
// // 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; }