NTSTATUS uStartFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION Stack; PFDO_EXT FdoExt; PDEVICE_RELATIONS Rels; Stack = IoGetCurrentIrpStackLocation( Irp ); FdoExt = DeviceObject->DeviceExtension; Status = SendIrpSynchronously(FdoExt->LowerDev,Irp); if (NT_ERROR(Status)) goto ErrorOut; Status = IoSetDeviceInterfaceState (&FdoExt->InterfaceName , TRUE ); if (NT_ERROR(Status)) goto ErrorOut; uSCSIInitialize(); return Status; ErrorOut: return Status; }
_Must_inspect_result_ NTSTATUS FxPkgFdo::PnpQueryCapabilities( __inout FxIrp *Irp ) /*++ Routine Description: This method is invoked in response to a Pnp QueryCapabilities IRP. Arguments: Device - a pointer to the FxDevice Irp - a pointer to the FxIrp Returns: NTSTATUS --*/ { NTSTATUS status; HandleQueryCapabilities(Irp); status = SendIrpSynchronously(Irp); // // Now that the IRP has returned to us, we modify what the bus driver // set up. // if (NT_SUCCESS(status)) { HandleQueryCapabilitiesCompletion(Irp); } CompletePnpRequest(Irp, status); return status; }
_Must_inspect_result_ NTSTATUS FxPkgFdo::PnpFilterResourceRequirements( __inout FxIrp *Irp ) /*++ Routine Description: This method is invoked in response to a Pnp FilterResourceRequirements IRP. Arguments: Device - a pointer to the FxDevice Irp - a pointer to the FxIrp Returns: NTSTATUS --*/ { PIO_RESOURCE_REQUIREMENTS_LIST pWdmRequirementsList; PIO_RESOURCE_REQUIREMENTS_LIST pNewWdmList; NTSTATUS status; FxIoResReqList *pIoResReqList; WDFIORESREQLIST reqlist; DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, "Entering FilterResourceRequirements handler"); if (m_DeviceFilterRemoveResourceRequirements.m_Method != NULL) { pWdmRequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST) Irp->GetInformation(); status = STATUS_INSUFFICIENT_RESOURCES; pIoResReqList = FxIoResReqList::_CreateFromWdmList(GetDriverGlobals(), pWdmRequirementsList, FxResourceAllAccessAllowed); if (pIoResReqList != NULL) { status = pIoResReqList->Commit(NULL, (PWDFOBJECT) &reqlist); // Commit should never fail because we own all object state ASSERT(NT_SUCCESS(status)); UNREFERENCED_PARAMETER(status); status = m_DeviceFilterRemoveResourceRequirements.Invoke( m_Device->GetHandle(), pIoResReqList->GetHandle()); if (NT_SUCCESS(status) && pIoResReqList->IsChanged()) { pNewWdmList = pIoResReqList->CreateWdmList(); if (pNewWdmList != NULL) { // // List could be missing previously // if (pWdmRequirementsList != NULL) { // // Propagate BusNumber to our new list. // pNewWdmList->BusNumber = pWdmRequirementsList->BusNumber; MxMemory::MxFreePool(pWdmRequirementsList); } Irp->SetInformation((ULONG_PTR) pNewWdmList); } else { status = STATUS_INSUFFICIENT_RESOURCES; } } // // No matter what, free the resource requirements list object. If // we need another one when adding resources, another one will be // allocated. // pIoResReqList->DeleteObject(); pIoResReqList = NULL; } } else { // // No filtering on the way down, set status to STATUS_SUCCESS so we // send the irp down the stack. // status = STATUS_SUCCESS; } if (NT_SUCCESS(status)) { status = SendIrpSynchronously(Irp); } // // If we do not handle the IRP on the way down and the PDO does not handle // the IRP, we can have a status of STATUS_NOT_SUPPORTED. We still want to // process the irp in this state. // if (NT_SUCCESS(status) || status == STATUS_NOT_SUPPORTED) { NTSTATUS filterStatus; // // Give the Framework objects a pass at the list. // filterStatus = FxPkgPnp::FilterResourceRequirements( (PIO_RESOURCE_REQUIREMENTS_LIST*)(&Irp->GetIrp()->IoStatus.Information) ); if (!NT_SUCCESS(filterStatus)) { status = filterStatus; } else if (m_DeviceFilterAddResourceRequirements.m_Method != NULL) { // // Now give the driver a shot at it. // pWdmRequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST) Irp->GetInformation(); pIoResReqList = FxIoResReqList::_CreateFromWdmList( GetDriverGlobals(), pWdmRequirementsList, FxResourceAllAccessAllowed); if (pIoResReqList != NULL) { status = pIoResReqList->Commit(NULL, (PWDFOBJECT) &reqlist); UNREFERENCED_PARAMETER(status); // // Since we absolutely control the lifetime of pIoResReqList, this // should never fail // ASSERT(NT_SUCCESS(status)); status = m_DeviceFilterAddResourceRequirements.Invoke( m_Device->GetHandle(), reqlist); // // It is possible the child driver modified the resource list, // and if so we need to update the requirements list. // if (NT_SUCCESS(status) && pIoResReqList->IsChanged()) { pNewWdmList = pIoResReqList->CreateWdmList(); if (pNewWdmList != NULL) { // // List could be missing previously // if (pWdmRequirementsList != NULL) { // // Propagate BusNumber to our new list. // pNewWdmList->BusNumber = pWdmRequirementsList->BusNumber; ExFreePool(pWdmRequirementsList); } Irp->SetInformation((ULONG_PTR) pNewWdmList); } else { status = STATUS_INSUFFICIENT_RESOURCES; } } pIoResReqList->DeleteObject(); pIoResReqList = NULL; } else { status = STATUS_INSUFFICIENT_RESOURCES; } } } CompletePnpRequest(Irp, status); DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, "Exiting FilterResourceRequirements handler, %!STATUS!", status); return status; }
NTSTATUS uPnPFdo (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status = STATUS_SUCCESS; ULONG i = 0 , OldCount; PIO_STACK_LOCATION Stack; PLIST_ENTRY PdoEnt , PdoEnt2; PFDO_EXT FdoExt; PPDO_EXT PdoExt; PDEVICE_RELATIONS OldRels , Rels; Stack = IoGetCurrentIrpStackLocation( Irp ); FdoExt = DeviceObject->DeviceExtension; KdPrintEx((DPFLTR_USCSI,DBG_USCSI, "%s MinorFunction 0x%X\n" , __FUNCTION__ , Stack->MinorFunction)); switch (Stack->MinorFunction ) { case IRP_MN_START_DEVICE: Status = uStartFdo (DeviceObject , Irp); break; case IRP_MN_QUERY_DEVICE_RELATIONS: if ( BusRelations == Stack->Parameters.QueryDeviceRelations.Type ) { OldRels = (PDEVICE_RELATIONS) Irp->IoStatus.Information; if (OldRels) OldCount = OldRels->Count; else OldCount = 0; Rels = ExAllocatePoolWithTag(PagedPool , sizeof (DEVICE_RELATIONS) + (FdoExt->PDOCount + OldCount - 1)*sizeof (PDEVICE_OBJECT), USCSI_TAG ); if ( Rels ) { if (OldCount) RtlCopyMemory (Rels->Objects, OldRels->Objects, OldCount * sizeof (PDEVICE_OBJECT)); Rels->Count = OldCount + FdoExt->PDOCount; PdoEnt = &FdoExt->PDOList; PdoEnt2 = PdoEnt->Flink; while ( PdoEnt2 != PdoEnt ) { PdoExt = CONTAINING_RECORD ( PdoEnt2, PDO_EXT , PDOList); if ( !PdoExt->Reported ) { ObReferenceObject( PdoExt->Self ); Rels->Objects[OldCount++] = PdoExt->Self; PdoExt->Reported = TRUE; } PdoEnt2 = PdoEnt2->Flink; } Irp->IoStatus.Information = (ULONG_PTR)Rels; } } break; case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: case IRP_MN_QUERY_CAPABILITIES: case IRP_MN_QUERY_PNP_DEVICE_STATE: IoSkipCurrentIrpStackLocation( Irp ); Status = IoCallDriver ( FdoExt->LowerDev , Irp ); return Status; case 0x18: //IRP_MN_QUERY_LEGACY_BUS_INFORMATION Status = SendIrpSynchronously( FdoExt->LowerDev , Irp ); break; } Irp->IoStatus.Status = Status; IoCompleteRequest( Irp , IO_NO_INCREMENT ); return Status; }