⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buspdo.c

📁 无奈啊啊 啊啊 啊啊
💻 C
📖 第 1 页 / 共 3 页
字号:
    descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
    descriptor->Flags = CM_RESOURCE_PORT_IO|CM_RESOURCE_PORT_16_BIT_DECODE;
    descriptor->u.Port.Length = 1;
    descriptor->u.Port.Alignment = 0x01;
    descriptor->u.Port.MinimumAddress.QuadPart = 0;
    descriptor->u.Port.MaximumAddress.QuadPart = 0xFFFF;
    Irp->IoStatus.Information = (ULONG_PTR)resourceList;
    status = STATUS_SUCCESS;
    
    return status;
}

NTSTATUS
Bus_PDO_QueryDeviceRelations(
    IN PPDO_DEVICE_DATA     DeviceData,
    IN  PIRP   Irp )
/*++

Routine Description:

    The PnP Manager sends this IRP to gather information about 
    devices with a relationship to the specified device.
    Bus drivers must handle this request for TargetDeviceRelation 
    for their child devices (child PDOs).

    If a driver returns relations in response to this IRP, 
    it allocates a DEVICE_RELATIONS structure from paged 
    memory containing a count and the appropriate number of 
    device object pointers. The PnP Manager frees the structure 
    when it is no longer needed. If a driver replaces a 
    DEVICE_RELATIONS structure allocated by another driver, 
    it must free the previous structure.

    A driver must reference the PDO of any device that it 
    reports in this IRP (ObReferenceObject). The PnP Manager 
    removes the reference when appropriate.
        
Arguments:

    DeviceData - Pointer to the PDO's device extension.
    Irp          - Pointer to the irp.

Return Value:

    NT STATUS

--*/
{

    PIO_STACK_LOCATION   stack;
    PDEVICE_RELATIONS deviceRelations;
    NTSTATUS status;

    PAGED_CODE ();

    stack = IoGetCurrentIrpStackLocation (Irp);

    switch (stack->Parameters.QueryDeviceRelations.Type) {

    case TargetDeviceRelation:  

        deviceRelations = (PDEVICE_RELATIONS) Irp->IoStatus.Information; 
        if (deviceRelations) {
            //
            // Only PDO can handle this request. Somebody above
            // is not playing by rule.
            //
            ASSERTMSG("Someone above is handling TagerDeviceRelation", !deviceRelations);      
        }

        deviceRelations = (PDEVICE_RELATIONS)
                ExAllocatePoolWithTag (PagedPool, 
                                        sizeof(DEVICE_RELATIONS),
                                        BUSENUM_POOL_TAG);
        if (!deviceRelations) {
                status = STATUS_INSUFFICIENT_RESOURCES;
                break;
        }

        // 
        // There is only one PDO pointer in the structure 
        // for this relation type. The PnP Manager removes 
        // the reference to the PDO when the driver or application 
        // un-registers for notification on the device. 
        //

        deviceRelations->Count = 1;
        deviceRelations->Objects[0] = DeviceData->Self;
        ObReferenceObject(DeviceData->Self);

        status = STATUS_SUCCESS;
        Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;
        break;
        
    case BusRelations: // Not handled by PDO
    case EjectionRelations: // optional for PDO
    case RemovalRelations: // // optional for PDO
    default:
        status = Irp->IoStatus.Status;
    }

    return status;
}

NTSTATUS
Bus_PDO_QueryBusInformation(
    IN PPDO_DEVICE_DATA     DeviceData,
    IN  PIRP   Irp )
/*++

Routine Description:

    The PnP Manager uses this IRP to request the type and 
    instance number of a device's parent bus. Bus drivers 
    should handle this request for their child devices (PDOs). 
    
Arguments:

    DeviceData - Pointer to the PDO's device extension.
    Irp          - Pointer to the irp.

Return Value:

    NT STATUS

--*/
{

    PPNP_BUS_INFORMATION busInfo;

    PAGED_CODE ();

    busInfo = ExAllocatePoolWithTag (PagedPool, sizeof(PNP_BUS_INFORMATION),
                                        BUSENUM_POOL_TAG);

    if (busInfo == NULL) {
      return STATUS_INSUFFICIENT_RESOURCES;
    }

    busInfo->BusTypeGuid = GUID_TOASTER_BUS_TYPE;

    //
    // Some buses have a specific INTERFACE_TYPE value, 
    // such as PCMCIABus, PCIBus, or PNPISABus. 
    // For other buses, especially newer buses like TOASTER, the bus 
    // driver sets this member to PNPBus. 
    //

    busInfo->LegacyBusType = PNPBus;

    //
    // This is an hypothetical bus
    //

    busInfo->BusNumber = 0;

    Irp->IoStatus.Information = (ULONG_PTR)busInfo;

    return STATUS_SUCCESS;
}

NTSTATUS
Bus_PDO_QueryInterface(
    IN PPDO_DEVICE_DATA     DeviceData,
    IN  PIRP   Irp )
/*++

Routine Description:

    This requests enables a driver to export proprietary interface
    to other drivers. This function and the following 5 routines 
    are meant to show how a typical interface is exported. 
    Note: This and many other routines in this sample are not required if 
    someone is using this sample for just device enumeration purpose.
Arguments:

    DeviceData - Pointer to the PDO's device extension.
    Irp          - Pointer to the irp.

Return Value:

    NT STATUS

--*/
{
   PIO_STACK_LOCATION irpStack;
   PTOASTER_INTERFACE_STANDARD toasterInterfaceStandard;
   GUID *interfaceType;
   NTSTATUS    status = STATUS_SUCCESS;

   PAGED_CODE();

   irpStack = IoGetCurrentIrpStackLocation(Irp);
   interfaceType = (GUID *) irpStack->Parameters.QueryInterface.InterfaceType;
   if (IsEqualGUID(interfaceType, (PVOID) &GUID_TOASTER_INTERFACE_STANDARD)) {

      if (irpStack->Parameters.QueryInterface.Size < 
                    sizeof(TOASTER_INTERFACE_STANDARD)
                    && irpStack->Parameters.QueryInterface.Version != 1) {
         return STATUS_INVALID_PARAMETER;
      }
      
      toasterInterfaceStandard = (PTOASTER_INTERFACE_STANDARD) 
                                irpStack->Parameters.QueryInterface.Interface;

      toasterInterfaceStandard->Context = DeviceData;
      //
      // Fill in the exported functions
      //
      toasterInterfaceStandard->InterfaceReference   = 
                        (PINTERFACE_REFERENCE) Bus_InterfaceReference;
      toasterInterfaceStandard->InterfaceDereference = 
                        (PINTERFACE_DEREFERENCE) Bus_InterfaceDereference;
      toasterInterfaceStandard->GetCrispinessLevel   = Bus_GetCrispinessLevel;
      toasterInterfaceStandard->SetCrispinessLevel   = Bus_SetCrispinessLevel;
      toasterInterfaceStandard->IsSafetyLockEnabled = Bus_IsSafetyLockEnabled;
      
      //
      // Must take a reference before returning
      //
      Bus_InterfaceReference(DeviceData);
   } else {
        //
        // Interface type not supported
        //
        status = Irp->IoStatus.Status;
   }
   return status;
}

BOOLEAN
Bus_GetCrispinessLevel(
    IN   PVOID Context,
    OUT  PUCHAR Level
    )
/*++

Routine Description:

    This routine gets the current crispiness level of the toaster.

Arguments:

    Context        pointer to  PDO device extension
    Level          crispiness level of the device
    
Return Value:

    TRUE or FALSE

--*/
{
    //
    // Validate the context to see if it's really a pointer
    // to PDO's device extension. You can store some kind
    // of signature in the PDO for this purpose
    //
    Bus_KdPrint ((PPDO_DEVICE_DATA)Context, BUS_DBG_PNP_TRACE, 
                                    ("GetCrispinessLevel\n"));
    *Level = 10;
    return TRUE;
}

BOOLEAN
Bus_SetCrispinessLevel(
    IN   PVOID Context,
    IN   UCHAR Level
    )
/*++

Routine Description:

    This routine sets the current crispiness level of the toaster.

Arguments:

    Context        pointer to  PDO device extension
    Level          crispiness level of the device

Return Value:

    TRUE or FALSE

--*/
{
    Bus_KdPrint ((PPDO_DEVICE_DATA)Context, BUS_DBG_PNP_TRACE, 
                                    ("SetCrispinessLevel\n"));
    return TRUE;
}

BOOLEAN
Bus_IsSafetyLockEnabled(
    IN PVOID Context
    )
/*++

Routine Description:

    Routine to check whether safety lock is enabled
    
Arguments:

    Context        pointer to  PDO device extension

Return Value:

    TRUE or FALSE

--*/
{
    Bus_KdPrint ((PPDO_DEVICE_DATA)Context, BUS_DBG_PNP_TRACE, 
                                    ("IsSafetyLockEnabled\n"));
    return TRUE;
}

VOID
Bus_InterfaceReference (
   IN PVOID Context
   )
/*++

Routine Description:

    This routine increments the refcount. We check this refcount
    during query_remove decide whether to allow the remove or not.
    
Arguments:

    Context        pointer to  PDO device extension

Return Value:

--*/
{
    InterlockedIncrement(&((PPDO_DEVICE_DATA)Context)->ToasterInterfaceRefCount);
}

VOID
Bus_InterfaceDereference (
   IN PVOID Context
   )
/*++

Routine Description:

    This routine decrements the refcount. We check this refcount
    during query_remove decide whether to allow the remove or not.

Arguments:

    Context        pointer to  PDO device extension

Return Value:

--*/
{
    InterlockedDecrement(&((PPDO_DEVICE_DATA)Context)->ToasterInterfaceRefCount);
}

NTSTATUS
Bus_GetDeviceCapabilities(
    IN  PDEVICE_OBJECT          DeviceObject,
    IN  PDEVICE_CAPABILITIES    DeviceCapabilities
    )
/*++

Routine Description:

    This routine sends the get capabilities irp to the given stack

Arguments:

    DeviceObject        A device object in the stack whose capabilities we want
    DeviceCapabilites   Where to store the answer

Return Value:

    NTSTATUS

--*/
{
    IO_STATUS_BLOCK     ioStatus;
    KEVENT              pnpEvent;
    NTSTATUS            status;
    PDEVICE_OBJECT      targetObject;
    PIO_STACK_LOCATION  irpStack;
    PIRP                pnpIrp;

    PAGED_CODE();

    //
    // Initialize the capabilities that we will send down
    //
    RtlZeroMemory( DeviceCapabilities, sizeof(DEVICE_CAPABILITIES) );
    DeviceCapabilities->Size = sizeof(DEVICE_CAPABILITIES);
    DeviceCapabilities->Version = 1;
    DeviceCapabilities->Address = -1;
    DeviceCapabilities->UINumber = -1;

    //
    // Initialize the event
    //
    KeInitializeEvent( &pnpEvent, NotificationEvent, FALSE );

    targetObject = IoGetAttachedDeviceReference( DeviceObject );

    //
    // Build an Irp
    //
    pnpIrp = IoBuildSynchronousFsdRequest(
        IRP_MJ_PNP,
        targetObject,
        NULL,
        0,
        NULL,
        &pnpEvent,
        &ioStatus
        );
    if (pnpIrp == NULL) {

        status = STATUS_INSUFFICIENT_RESOURCES;
        goto GetDeviceCapabilitiesExit;

    }

    //
    // Pnp Irps all begin life as STATUS_NOT_SUPPORTED;
    //
    pnpIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;

    //
    // Get the top of stack
    //
    irpStack = IoGetNextIrpStackLocation( pnpIrp );

    //
    // Set the top of stack
    //
    RtlZeroMemory( irpStack, sizeof(IO_STACK_LOCATION ) );
    irpStack->MajorFunction = IRP_MJ_PNP;
    irpStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
    irpStack->Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities;

    //
    // Call the driver
    //
    status = IoCallDriver( targetObject, pnpIrp );
    if (status == STATUS_PENDING) {

        //
        // Block until the irp comes back.
        // Important thing to note here is when you allocate 
        // the memory for an event in the stack you must do a  
        // KernelMode wait instead of UserMode to prevent 
        // the stack from getting paged out.
        //

        KeWaitForSingleObject(
            &pnpEvent,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );
        status = ioStatus.Status;

    }

GetDeviceCapabilitiesExit:
    //
    // Done with reference
    //
    ObDereferenceObject( targetObject );

    //
    // Done
    //
    return status;

}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -