• 移除设备


    当要移除设备的时候,IO管理器发送IRP_MN_REMOVE_DEVICE 类型的IRP包,这是一个即插即用型的IRP包。通过调用即插即用例程来处理。

    由于在Driver_Entry()函数中,将即插即用的函数和处理Pnp的MajorFunction进行了绑定,即:

    pDriverObject->MajorFunction[IRP_MJ_PNP] =xxxPnp;

    NTSTATUS xxxPnp(IN PDEVICE_OBJECT fdo,IN PIRP Irp)

    {

             …

    }

    该函数前面都已经提到过,通过调用下面函数来完成:

    NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)

    {

             //释放分配的内存

             if(pdx->MemBar0)

                       MmUnmapIoSpace(pdx->MemBar0,pdx->nMem0);

             //设置寄存器状态

    WRITE_REGISTER_ULONG((PULONG) &pdx->pHBARegs->Dma_wr_en,0x00000000);

    //释放DMA资源

    pdx->freeCommonBuffer()

    //删除中断

    IoDisconnectInterrupt(pdx->InterruptObject);

    //将IRP_MN_REMOVE_DEVICE交给硬件处理

    NTSTATUS status = ForwardAndWait(pdx,Irp);

    //设置设备接口状态

             IoSetDeviceInterfaceState(&pdx->interfaceName, FALSE);

             //释放UNICODE字符串

             RtlFreeUnicodeString(&pdx->interfaceName);

             //调用IoDetachDevice()把fdo从设备栈中脱开:

             if (pdx->NextStackDevice)

                       IoDetachDevice(pdx->NextStackDevice);

             //删除设备对象fdo:

             IoDeleteDevice(pdx->fdo);

             //释放UNICODE字符串

    //      RtlFreeUnicodeString(&pdx->devName);

             Irp->IoStatus.Status = status;

             IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status

    }

    驱动需要对一些不做特殊处理的IRP包进行默认操作,对这类Pnp类型的操作可以提供一个这样的函数来处理:

    NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)

    {

             PAGED_CODE();

             KdPrint(("Enter DefaultPnpHandler\n"));

             IoSkipCurrentIrpStackLocation(Irp);

             KdPrint(("Leave DefaultPnpHandler\n"));

             return IoCallDriver(pdx->NextStackDevice, Irp);

    }

    通过IoCallDriver()直接交给PDO。

    对于非Pnp类的操作,如IRP_MJ_CREATE、IRP_MJ_CLOSE、IRP_MJ_READ、IRP_MJ_WRITE,直接提供下面类似的默认处理函数:

    NTSTATUS xxxCreate(IN PDEVICE_OBJECT fdo,IN PIRP Irp)

    {

             PAGED_CODE();

             PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

             pdx->open_flag++;

             Irp->IoStatus.Status = STATUS_SUCCESS;

             Irp->IoStatus.Information = 0;         // no bytes xfered

             IoCompleteRequest( Irp, IO_NO_INCREMENT );

             return STATUS_SUCCESS;

    }

    make it simple, make it happen
  • 相关阅读:
    文件读写和进度条
    复选框选择变化(可以演化成简单的字符串拼接)
    读取文本方式的简单登录
    计算字符出现次数
    判断系统版本号
    DataTable合并
    获取单元格值的数据类型
    struts2 日期标签
    jsp获取枚举的值
    java web项目修改项目名称
  • 原文地址:https://www.cnblogs.com/zhuyp1015/p/2396628.html
Copyright © 2020-2023  润新知