zoukankan      html  css  js  c++  java
  • 【驱动笔记11】使用DeviceIoControl通信

    文章作者:grayfox
    作者主页:http://nokyo.blogbus.com

    原始出处:http://www.blogbus.com/nokyo-logs/34018521.html

     

          在我昨日发布的《驱动学习笔记系列文章汇总(PDF)》第11.2节中,我没有给出使用DeviceIoControl通信的演示源码,附录中附带的程序是我尚未调试好的,因此没有达到通信的目的。

          今天又认真阅读了下张帆的《Windows驱动开发技术详解》第7章的内容,并对它给出的示例程序多次调试,总算把这个通信过程给理解了,下面我们先来看看应用层程序的代码:

    #include <windows.h>

    #include <stdio.h>

    #include <winioctl.h>

    #include "..Ioctls.h"

     

    #define SYMBOL_LINK "\\.\Test"

     

    int main()

    {

        HANDLE hDevice = ::CreateFile(SYMBOL_LINK, 

                                    GENERIC_READ | GENERIC_WRITE,

                                    0,    

                                    NULL,

                                    OPEN_EXISTING,

                                    FILE_ATTRIBUTE_NORMAL,

                                    NULL );

        if (hDevice == INVALID_HANDLE_VALUE)

        {

            printf("Failed to Open Device : %d ", ::GetLastError());

            return -1;

        }

     

        UCHAR InputBuffer[10];

        UCHAR OutputBuffer[10];

        DWORD dwOutput;

        

        memset(InputBuffer, 0xAA, 10);

        BOOL bRet = ::DeviceIoControl(hDevice, IOCTL_TEST, InputBuffer, 10, &OutputBuffer, 10, &dwOutput, NULL);

        if (bRet)

        {

            printf("Output buffer:%d bytes ",dwOutput);

            for (int i=0;i<(int)dwOutput;i++)

            {

                printf("%02X ",OutputBuffer[i]);

            }

            printf(" ");

        }

     

        CloseHandle(hDevice);

        return 0;

    }

          其中Ioctls.h这个头文件没有实质作用,它是为了在驱动程序和应用层程序之间共享IOCTL定义而设立的,内容很简单,如下所示:

    #ifndef IOCTLS_H

    #define IOCTLS_H

     

    #ifndef CTL_CODE

        #pragma message("CTL_CODE undefined. Include winioctl.h or wdm.h")

    #endif

     

    #define IOCTL_TEST 

                CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)

     

    #endif

          我们再来看驱动程序,这里的xxxxDispatchDeviceControl函数需要作适当修改,如下所示:

    NTSTATUS

    TestDispatchDeviceControl(

        IN PDEVICE_OBJECT        DeviceObject,

        IN PIRP                    Irp

    )

    {

        NTSTATUS            Status = STATUS_SUCCESS;

        PIO_STACK_LOCATION    irpStack;

        ULONG                inBufLength, outBufLength;

        ULONG                i = 0;

        ULONG                ioControlCode;

        UCHAR                *InputBuffer, *OutputBuffer;

        

        irpStack = IoGetCurrentIrpStackLocation(Irp);

        

        inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;

        outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

        ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

        

        if (ioControlCode == IOCTL_TEST)

        {

            KdPrint(("[Test] IOCTL_TEST : 0x%X", ioControlCode));

            // 读取数据

            InputBuffer = (UCHAR *)Irp->AssociatedIrp.SystemBuffer;

            for (i = 0; i < inBufLength; i++)

            {

                KdPrint(("[Test] %X ", InputBuffer[i]));

            }

            

            // 写入数据

            OutputBuffer = (UCHAR *)Irp->AssociatedIrp.SystemBuffer;

            memset(OutputBuffer, 0xBB, outBufLength);

            

            Irp->IoStatus.Information = outBufLength;

        } 

        else

        {

            KdPrint(("[Test] Unknown IOCTL: 0x%X (%04X,%04X)", 

                        ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode), IoGetFunctionCodeFromCtlCode(ioControlCode)));

     

            Status = STATUS_INVALID_PARAMETER;

            Irp->IoStatus.Information = 0;

        }    

        // 完成IRP

        Irp->IoStatus.Status = Status;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        

        return Status;

    }

     

          最后的演示结果如下图所示:

  • 相关阅读:
    php 本地 备份远程mysql和mdb 多任务只执行一次
    c# 监控服务器上传木马(包含可疑文件)
    jquery 简短 右键菜单 兼容ie6 ie7 ie8 firefox chrome
    分解从身份证中读回的户籍地址
    备份mysql(一表一文件)
    THINKPHP 3.0 整合KINDEDITOR 4.05
    c# 仿照计划任务(定时提示、定时运行程序、定时打开url(前台/后台))/每天/每周/每月/一次 多时间段
    php基本操作echo
    c# 扫描可疑文件(找到木马)(简)
    GOOGLE 地图,查询地名,移动标记,生成静态地图
  • 原文地址:https://www.cnblogs.com/huhu0013/p/3312203.html
Copyright © 2011-2022 走看看