首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

小巧的驱动测试工具

小巧的驱动测试工具

首先使用QuickSys向导一个驱动框架hellodrv,然后在DeviceControl例程里写入以下代码:
NTSTATUS
HellodrvDispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus;
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    PVOID lpInOutBuffer;
    ULONG nInBufferSize, nOutBufferSize, dwIoControlCode;
UCHAR uBuffer[256]={0};
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    //
    // Get the pointer to the input/output buffer and it's length
    //
    lpInOutBuffer = Irp->AssociatedIrp.SystemBuffer;
    nInBufferSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
    nOutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
    dprintf("[HelloDrv] IRP_MJ_DEVICE_CONTROL/n");
    dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
    switch (dwIoControlCode)
    {
case IOCTL_HELLODRV_HELLO:
  {
   __try
   {
    strncpy(uBuffer,lpInOutBuffer,256);
    dprintf(uBuffer);
    {
     int iLen=strlen("Hi! I Got it!");
     strncpy(lpInOutBuffer,"Hi! I Got it!",nOutBufferSize);
     
     Irp->IoStatus.Information=iLen;
    }
   
   }
   __except(1)
   {
    dprintf("Excpetion during strncpy");
   }
   break;
  }
    default:
        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
        dprintf("[HelloDrv] unknown IRP_MJ_DEVICE_CONTROL/n");
        break;
}
    //
    // DON'T get cute and try to use the status field of
    // the irp in the return status.  That IRP IS GONE as
    // soon as you call IoCompleteRequest.
    //
    ntStatus = Irp->IoStatus.Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    //
    // We never have pending operation so always return the status code.
    //
    return ntStatus;
}
编译生成一个sys后,使用Driver Testter测试它。


装载驱动:设置好参数后点Load按钮完成驱动装载.

进行IO测试,在这里可以通过Driver Tester程序传递最长256字节数据给驱动。
点Content按钮,设置参数,可以在左边使用16进制设置数据包值,比如某种特别的包结构内容,也可以使用右边的ASIIC视图输入字符,我在这里只敲了个了字符串"can you see it?"

参数设置好后,点IoControl按钮

可以看到驱动已收到了我们的数据,再看看驱动返回的数据,按Content按钮

我们也以收到驱动返回的数据,后面的那个t?是因为驱动返回的数据没有我们输入的长,所以没有被覆盖掉。
卸载驱动:最后点击Unload按钮,卸载驱动同时删除服务,不会在系统留下干什么痕迹,我不喜欢什么东东都在注册表写东东,自所不欲,勿所于人!这一点我很明白,所以在停止Driver的Kernel类型服务后,我就将服务删除。


一个小问题:
就是输入输出缓冲最大只支持256字节,为什么只支持这么小的数据Buffer,因为我只是要写一个小的驱动来研究系统,而不是要搞大数据量的东东,而且在对驱动进行一次DeviceIoControl也不宜用过大的数据,特别是在Buffered方式时IO管理器会把数据copy到内核态空间,此前IO管理器会分配一块内存,在驱动处理完后IO管理器再将数据从内核心态空间copy回ring3的Buffer里,这样会使效率所低,会占用很多我们很宝贵的内存啊!所以我建议的做法是驱动只完成很小的动作,比如要dump什么数据,驱动一次只负责dump一块出来,由Ring3程序进行多次DeviceIoControl请求来完成大量数据的dump操作,这样的效率也许会高一些,也就是驱动只完成一些"原子操作",而应用逻辑由Ring3程序进行包装实现。
Driver Logical Tester不是一个Debug工具,更不能防止BSOD出现,它所能做的是在你已经对你的驱动Debug后,对驱动的输入输出做一些逻辑测试,所以我给它起的名称叫Driver Logical Tester,也许没有什么大不了,但对我来说很有用,呵呵!
程序介绍:

关于DeviceID,ControlCode和Method不要问我是什么意思,怎么取值!!!具体的取值也根据你自己定义的来设置,界面里的Notes已经说明了它们的关系。
返回列表