/***************************************************************************** * StartDevice() ***************************************************************************** * * This function is called by the operating system when the device is started. * It is responsible for starting the miniports. This code is specific to * the adapter because it calls out miniports for functions that are specific * to the adapter. A list of no resources is not the same as a NULL list ptr. * */ NTSTATUS StartDevice ( IN PDEVICE_OBJECT pDeviceObject, // Context for the class driver. IN PIRP pIrp, // Context for the class driver. IN PRESOURCELIST ResourceList // List of hardware resources. ) { PAGED_CODE(); _DbgPrintF(DEBUGLVL_VERBOSE, ("StartDevice")); ASSERT(ResourceList); if (!ResourceList) { return STATUS_INVALID_PARAMETER; } PPORT port; NTSTATUS ntStatus = PcNewPort(&port, CLSID_PortDMus); if (!NT_SUCCESS(ntStatus)) { _DbgPrintF(DEBUGLVL_TERSE,("StartDevice PcNewPort failed (0x%08x)", ntStatus)); return ntStatus; } ASSERT(port); PUNKNOWN miniport; #ifdef USE_OBSOLETE_FUNCS ntStatus = CreateMiniportDmSynth(&miniport, NULL, NonPagedPool); #else ntStatus = CreateMiniportDmSynth(&miniport, NULL, NonPagedPool, pDeviceObject); #endif if (!NT_SUCCESS(ntStatus)) { _DbgPrintF(DEBUGLVL_TERSE,("StartDevice CreateMiniportDmSynth failed (0x%08x)", ntStatus)); port->Release(); return ntStatus; } ASSERT(miniport); ntStatus = port->Init ( pDeviceObject, pIrp, miniport, NULL, ResourceList ); if (!NT_SUCCESS(ntStatus)) { _DbgPrintF(DEBUGLVL_TERSE,("StartDevice port Init failed (0x%08x)", ntStatus)); port->Release(); miniport->Release(); return ntStatus; } ntStatus = PcRegisterSubdevice( pDeviceObject, L"DDKSynth", port); if (!NT_SUCCESS(ntStatus)) { _DbgPrintF(DEBUGLVL_TERSE,("StartDevice PcRegisterSubdevice failed (0x%08x)", ntStatus)); } // // We don't need the miniport any more. Either the port has it, // or we've failed, and it should be deleted. // miniport->Release(); // // Release the reference which existed when PcNewPort() gave us the // pointer in the first place. This is the right thing to do // regardless of the outcome. // port->Release(); return ntStatus; }
//============================================================================= NTSTATUS InstallSubdevice( __in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PWSTR Name, __in REFGUID PortClassId, __in REFGUID MiniportClassId, __in_opt PFNCREATEINSTANCE MiniportCreate, __in_opt PUNKNOWN UnknownAdapter, __in_opt PRESOURCELIST ResourceList, __in REFGUID PortInterfaceId, __out_opt PUNKNOWN * OutPortInterface, __out_opt PUNKNOWN * OutPortUnknown ) /*++ Routine Description: This function creates and registers a subdevice consisting of a port driver, a minport driver and a set of resources bound together. It will also optionally place a pointer to an interface on the port driver in a specified location before initializing the port driver. This is done so that a common ISR can have access to the port driver during initialization, when the ISR might fire. Arguments: DeviceObject - pointer to the driver object Irp - pointer to the irp object. Name - name of the miniport. Passes to PcRegisterSubDevice PortClassId - port class id. Passed to PcNewPort. MiniportClassId - miniport class id. Passed to PcNewMiniport. MiniportCreate - pointer to a miniport creation function. If NULL, PcNewMiniport is used. UnknownAdapter - pointer to the adapter object. Used for initializing the port. ResourceList - pointer to the resource list. PortInterfaceId - GUID that represents the port interface. OutPortInterface - pointer to store the port interface OutPortUnknown - pointer to store the unknown port interface. Return Value: NT status code. --*/ { PAGED_CODE(); ASSERT(DeviceObject); ASSERT(Irp); ASSERT(Name); NTSTATUS ntStatus; PPORT port = NULL; PUNKNOWN miniport = NULL; DPF_ENTER(("[InstallSubDevice %S]", Name)); // Create the port driver object ntStatus = PcNewPort(&port, PortClassId); // Create the miniport object if (NT_SUCCESS(ntStatus)) { if (MiniportCreate) { ntStatus = MiniportCreate(&miniport, MiniportClassId, NULL, NonPagedPool ); } else { ntStatus = PcNewMiniport((PMINIPORT *) &miniport, MiniportClassId); } } // Init the port driver and miniport in one go. if (NT_SUCCESS(ntStatus)) { ntStatus = port->Init(DeviceObject, Irp, miniport, UnknownAdapter, ResourceList); if (NT_SUCCESS(ntStatus)) { // Register the subdevice (port/miniport combination). ntStatus = PcRegisterSubdevice(DeviceObject, Name, port); } // We don't need the miniport any more. Either the port has it, // or we've failed, and it should be deleted. miniport->Release(); } // Deposit the port interfaces if it's needed. if (NT_SUCCESS(ntStatus)) { if (OutPortUnknown) { ntStatus = port->QueryInterface(IID_IUnknown, (PVOID *)OutPortUnknown); } if (OutPortInterface) { ntStatus = port->QueryInterface(PortInterfaceId, (PVOID *) OutPortInterface); } } if (port) { port->Release(); } return ntStatus; } // InstallSubDevice
/***************************************************************************** * InstallSubdevice() ***************************************************************************** * This function creates and registers a subdevice consisting of a port * driver, a minport driver and a set of resources bound together. It will * also optionally place a pointer to an interface on the port driver in a * specified location before initializing the port driver. This is done so * that a common ISR can have access to the port driver during initialization, * when the ISR might fire. */ NTSTATUS InstallSubdevice ( __in PVOID Context1, __in PVOID Context2, __in PWSTR Name, __in REFGUID PortClassId, __in REFGUID MiniportClassId, __in_opt PUNKNOWN UnknownAdapter, //not used - null __in PRESOURCELIST ResourceList, //not optional, but can be EMPTY! __in REFGUID PortInterfaceId, __out_opt PUNKNOWN * OutPortInterface, //not used - null __out_opt PUNKNOWN * OutPortUnknown //not used - null ) { PAGED_CODE(); _DbgPrintF(DEBUGLVL_VERBOSE, ("InstallSubdevice")); ASSERT(Context1); ASSERT(Context2); ASSERT(Name); ASSERT(ResourceList); // // Create the port driver object // PPORT port; NTSTATUS ntStatus = PcNewPort(&port,PortClassId); if (NT_SUCCESS(ntStatus)) { // // Deposit the port somewhere if it's needed. // if (OutPortInterface) { // // Failure here doesn't cause the entire routine to fail. // (void) port->QueryInterface ( PortInterfaceId, (PVOID *) OutPortInterface ); } PMINIPORT miniport; // // Create the miniport object // ntStatus = PcNewMiniport(&miniport,MiniportClassId); if (NT_SUCCESS(ntStatus)) { // // Init the port driver and miniport in one go. // ntStatus = port->Init( (PDEVICE_OBJECT)Context1, (PIRP)Context2, miniport, NULL, // interruptsync created in miniport. ResourceList); if (NT_SUCCESS(ntStatus)) { // // Register the subdevice (port/miniport combination). // ntStatus = PcRegisterSubdevice( (PDEVICE_OBJECT)Context1, Name, port ); if (!(NT_SUCCESS(ntStatus))) { _DbgPrintF(DEBUGLVL_TERSE, ("StartDevice: PcRegisterSubdevice failed")); } } else { _DbgPrintF(DEBUGLVL_TERSE, ("InstallSubdevice: port->Init failed")); } // // We don't need the miniport any more. Either the port has it, // or we've failed, and it should be deleted. // miniport->Release(); } else { _DbgPrintF(DEBUGLVL_TERSE, ("InstallSubdevice: PcNewMiniport failed")); } if (NT_SUCCESS(ntStatus)) { // // Deposit the port as an unknown if it's needed. // if (OutPortUnknown) { // // Failure here doesn't cause the entire routine to fail. // (void) port->QueryInterface ( IID_IUnknown, (PVOID *) OutPortUnknown ); } } else { // // Retract previously delivered port interface. // if (OutPortInterface && (*OutPortInterface)) { (*OutPortInterface)->Release(); *OutPortInterface = NULL; } } // // Release the reference which existed when PcNewPort() gave us the // pointer in the first place. This is the right thing to do // regardless of the outcome. // port->Release(); } else { _DbgPrintF(DEBUGLVL_TERSE, ("InstallSubdevice: PcNewPort failed")); } return ntStatus; }
/***************************************************************************** * InstallSubdevice ***************************************************************************** * This function creates and registers a subdevice consisting of a port * driver, a minport driver and a set of resources bound together. It will * also optionally place a pointer to an interface on the port driver in a * specified location before initializing the port driver. This is done so * that a common ISR can have access to the port driver during initialization, * when the ISR might fire. * This function is internally used and validates no parameters. */ NTSTATUS InstallSubdevice ( __in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PWSTR Name, __in REFGUID PortClassId, __in REFGUID MiniportClassId, __in_opt PFNCREATEINSTANCE MiniportCreate, __in_opt PUNKNOWN UnknownAdapter, __in_opt PRESOURCELIST ResourceList, __in_opt REFGUID PortInterfaceId, __out_opt PMINIPORT * OutMiniport, __out_opt PUNKNOWN * OutPortUnknown ) { PAGED_CODE (); NTSTATUS ntStatus; PPORT port; PMINIPORT miniport; DOUT (DBG_PRINT, ("[InstallSubdevice]")); UNREFERENCED_PARAMETER(PortInterfaceId); // // Create the port driver object // ntStatus = PcNewPort (&port,PortClassId); // // return immediately in case of an error // if (!NT_SUCCESS (ntStatus)) return ntStatus; // // Create the miniport object // if (MiniportCreate) { ntStatus = MiniportCreate ((PUNKNOWN*)&miniport, MiniportClassId, NULL, NonPagedPool); } else { ntStatus = PcNewMiniport (&miniport,MiniportClassId); } // // return immediately in case of an error // if (!NT_SUCCESS (ntStatus)) { port->Release (); return ntStatus; } // // Init the port driver and miniport in one go. // ntStatus = port->Init (DeviceObject, Irp, miniport, UnknownAdapter, ResourceList); if (NT_SUCCESS (ntStatus)) { // // Register the subdevice (port/miniport combination). // ntStatus = PcRegisterSubdevice (DeviceObject, Name, port); // // Deposit the port as an unknown if it's needed. // if (OutPortUnknown && NT_SUCCESS (ntStatus)) { ntStatus = port->QueryInterface (IID_IUnknown, (PVOID *)OutPortUnknown); } // // Deposit the miniport as an IMiniport if it's needed. // if ( OutMiniport && NT_SUCCESS (ntStatus) ) { ntStatus = miniport->QueryInterface (IID_IMiniport, (PVOID *)OutMiniport); } } // // Release the reference for the port and miniport. This is the right // thing to do, regardless of the outcome. // miniport->Release (); port->Release (); return ntStatus; }