小巧的驱动测试工具

首先使用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已经说明了它们的关系。需要这个小东东的朋友可以到http://kruglinski.ys168.com/下载。

你可能感兴趣的:(小巧的驱动测试工具)