狂野之城 发表于 2013-3-28 15:52:01

驱动与应用层简单消息通信

/* 驱动SYS irp1.h */
#include <ntddk.h>   

/*采用缓冲区内存模式IOCTL,
MY_DVC_BUFFERED_CODE是自定义的控制码*/
#define MY_DVC_BUFFERED_CODE /   
      (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, /
      0x900, /
      METHOD_BUFFERED, /
      FILE_ANY_ACCESS)


//---------函数声明---------   
NTSTATUS   
DriverEntry(IN PDRIVER_OBJECT DriverObject,   
            IN PUNICODE_STRING registryPath);

NTSTATUS
MyDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
                  IN PIRP Irp);

NTSTATUS
MyCreateClose(IN PDEVICE_OBJECT DeviceObject,
            IN PIRP Irp);

VOID
MyDriverOnUnload(IN PDRIVER_OBJECT DriverObject);
//-------------------------   

/* 驱动SYS irp1.c */
#include "irp1.h"   

//------------驱动入口----------   
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING registryPath )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_OBJECT Device;
    UNICODE_STRING DeviceName, DeviceLink;//设备名,符号链接名   

    DbgPrint(" DriverEntry/n");

    RtlInitUnicodeString(&DeviceName, L"//Device//Aliwy");         //初始化设备名
    RtlInitUnicodeString(&DeviceLink, L"//DosDevices//IamAliwy");//初始化符号链接名

    /* IoCreateDevice 生成设备对象 */
    ntStatus = IoCreateDevice(DriverObject,         //生成设备的驱动对象   
                              0,                  //设备扩展区内存大小   
                              &DeviceName,          //设备名,/Device/Aliwy   
                              FILE_DEVICE_UNKNOWN,//设备类型   
                              0,                  //填写0即可   
                              FALSE,                //必须为FALSE   
                              &Device);             //设备对象指针返回到DeviceObject中   
    if (!NT_SUCCESS(ntStatus))
    {
      DbgPrint(" IoCreateDevice FALSE: %.8X/n", ntStatus);
      return ntStatus;//生成失败就返回   
    }
    else
       DbgPrint(" IoCreateDevice SUCCESS/n");

    /* IoCreateSymbolicLink 生成符号链接 */
    ntStatus = IoCreateSymbolicLink(&DeviceLink, &DeviceName);
    if (!NT_SUCCESS(ntStatus))
    {
      DbgPrint(" IoCreateSymbolicLink FALSE: %.8X/n", ntStatus);
      IoDeleteDevice(Device);//删除设备   
      return ntStatus;
    }
    else
      DbgPrint(" IoCreateSymbolicLink SUCCESS/n");

    Device->Flags &= ~DO_DEVICE_INITIALIZING;//设备初始化完成标记   

    DriverObject->DriverUnload = MyDriverOnUnload;
      
    /*设备控制请求,对应Ring3 DeviceIoControl*/
    DriverObject->MajorFunction = MyDeviceIoControl;
    /*设备打开请求,对应Ring3 CreateFile*/                      //   
    DriverObject->MajorFunction = MyCreateClose; //要与应用层通信,   
    /*设备关闭请求,对应Ring3 CloseHandle*/                     //必须有打开、关闭请求!   
    DriverObject->MajorFunction = MyCreateClose;//      

    return ntStatus;
}
//------------------------------   

//---------设备请求处理---------   
NTSTATUS MyDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    PIO_STACK_LOCATION irpSp; //当前IRP调用栈空间   
    ULONG code;               //功能号   
    NTSTATUS ntStatus = STATUS_SUCCESS;
    ULONG inBufLength;      //输入缓冲区长度   
    ULONG outBufLength;       //输出缓冲区长度   
    PCHAR inBuf;            //输入缓冲区   
    PCHAR outBuf;             //输出缓冲区   
    PCHAR outData = " outBuf: This String is from Driver !!!"; //要向应用层输出的信息   
    ULONG outDataLen = strlen(outData) + 1;//信息长度含结尾一个NULL   

    DbgPrint(" MyDeviceIoControl/n");

    irpSp = IoGetCurrentIrpStackLocation(Irp);               //获得当前IRP调用栈空间   
    code = irpSp->Parameters.DeviceIoControl.IoControlCode;//得到功能号,即控制码   
    inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;   //得到输入缓冲区长度   
    outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; //得到输出缓冲区长度   
    inBuf = Irp->AssociatedIrp.SystemBuffer;//输入缓冲区   
    outBuf = Irp->AssociatedIrp.SystemBuffer; //输出缓冲区   

    if (code == MY_DVC_BUFFERED_CODE)//我们自定义的控制码   
    {
      DbgPrint(" inBuf: %s/n", inBuf);      //打印出应用层传入的内容   

      RtlCopyBytes(outBuf, outData, outBufLength); //复制我们要传入的内容到输出缓冲区   

      Irp->IoStatus.Information = (outBufLength < outDataLen ? outBufLength : outDataLen);
      Irp->IoStatus.Status = STATUS_SUCCESS;
    }
    else   
    {   
      Irp->IoStatus.Information = 0;
      Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
    }
    IoCompleteRequest(Irp, IO_NO_INCREMENT); //结束IRP请求   

    DbgPrint(" MyDeviceIoControl Over/n");
    return Irp->IoStatus.Status;
}
//------------------------------   

//----------打开关闭------------   
NTSTATUS MyCreateClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    DbgPrint(" MyCreateClose/n");
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return Irp->IoStatus.Status;
}
//------------------------------   

//----------驱动卸载------------   
VOID MyDriverOnUnload( IN PDRIVER_OBJECT DriverObject )
{
    UNICODE_STRING DeviceLink; //符号链接名   
    DbgPrint(" MyDriverOnUnload/n");

    RtlInitUnicodeString(&DeviceLink, L"//DosDevices//IamAliwy");
    IoDeleteSymbolicLink(&DeviceLink); //删除符号链接   
    if (DriverObject->DeviceObject != NULL)
    {
      IoDeleteDevice(DriverObject->DeviceObject);//删除设备   
    }
}
//------------------------------   



/* 应用层EXE irp1.cpp */
#include <windows.h>   
#include <winioctl.h>   
#include <stdio.h>   

/*采用缓冲区内存模式IOCTL,MY_DVC_IN_CODE是自定义的控制码*/
#define MY_DVC_BUFFERED_CODE /   
       (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, /
      0x900, /
      METHOD_BUFFERED, /
      FILE_ANY_ACCESS)

void main()
{
    ULONG bytesReturned;
    char inBuf = "This String is from User !!!";//传入驱动的内容   
    char outBuf;//用于接收驱动传出内容的缓冲区   

    /*打开设备,用我们自定的符号链接,响应驱动IRP_MJ_CREATE*/
    HANDLE hDevice = CreateFile("////.//IamAliwy",
                              GENERIC_READ | GENERIC_WRITE,
                              0,
                              NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL);
    if (hDevice == INVALID_HANDLE_VALUE)
    {
      printf("设备打开失败 %d %.8x/n", GetLastError(), hDevice);
      return;
    }

    memset(outBuf, 0, sizeof(outBuf));   

    /*控制设备,响应驱动IRP_MJ_DEVICE_CONTROL*/
    BOOL ret = DeviceIoControl(hDevice,
                               MY_DVC_BUFFERED_CODE, //我们自定义的功能号   
                               &inBuf,               //传入驱动的内容   
                               strlen(inBuf) + 1,    //传入内容长度   
                               &outBuf,            //驱动输出的缓冲区   
                               sizeof(outBuf),       //驱动输出缓冲区大小   
                               &bytesReturned,       //返回的长度   
                               NULL);
    if (!ret)
    {
      printf("Error in DeviceIoControl: %d", GetLastError());
    }
    else
      printf("%s(%d)/n", outBuf, bytesReturned);   //打印驱动传给我们的内容   
      
    /*关闭设备,对应驱动IRP_MJ_CLOSE*/
    CloseHandle(hDevice);
}
页: [1]
查看完整版本: 驱动与应用层简单消息通信