• windows driver 简单的驱动和通信


    sysmain.c

    #pragma once
    #pragma warning(disable: 4100)
    
    #include <ntifs.h>
    #include <ntddk.h>
    
    #define IO_READ_Control CTL_CODE(FILE_DEVICE_UNKNOWN, 0x777, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
    
    typedef struct _Player
    {
      ULONG id;
      ULONG hp;
      ULONG mp;
    } Player, * PPlayer;
    
    UNICODE_STRING deviceName = RTL_CONSTANT_STRING(L"\Device\hsys");
    UNICODE_STRING symbolName = RTL_CONSTANT_STRING(L"\??\hsys");
    PDEVICE_OBJECT pDeviceObject = NULL;
    
    // 卸载驱动时,必须清理资源
    NTSTATUS DriverUnload(PDRIVER_OBJECT pDriverObject)
    {
      IoDeleteSymbolicLink(&symbolName);
      IoDeleteDevice(pDeviceObject); // or: IoDeleteDevice(pDriverObject->DeviceObject);
    
      DbgPrintEx(0, 0, "[hsys] stop.
    ");
      return STATUS_SUCCESS;
    }
    
    NTSTATUS DispatchHandle(PDEVICE_OBJECT DeviceObject, PIRP pIrp)
    {
      NTSTATUS status = STATUS_SUCCESS;
      SIZE_T byteSize = 0;
    
      // 获取io堆栈位置
      PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    
      switch (stack->MajorFunction)
      {
      case IRP_MJ_CREATE:
      case IRP_MJ_CLOSE:
        break;
      case IRP_MJ_DEVICE_CONTROL:
      {
        ULONG controlCode = stack->Parameters.DeviceIoControl.IoControlCode;
    
        if (controlCode == IO_READ_Control)
        {
          // 用户模式发送的player指针过来
          PPlayer pPlayer = (PPlayer)pIrp->AssociatedIrp.SystemBuffer;
    
          pPlayer->id = 1;
          pPlayer->hp = 100;
          pPlayer->mp = 50;
    
          status = STATUS_SUCCESS;
          byteSize = sizeof(Player);
        }
      }
      break;
      default:
        break;
      }
    
      pIrp->IoStatus.Status = status;
      pIrp->IoStatus.Information = byteSize; // 读写了多少字节
      IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 完成请求
      return status;
    }
    
    NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegister)
    {
      DbgPrintEx(0, 0, "[hsys] start!!
    ");
      pDriverObject->DriverUnload = DriverUnload;
    
      NTSTATUS status = STATUS_SUCCESS;
    
      // 创建一个设备
      status = IoCreateDevice(pDriverObject, 0, &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
      if (!NT_SUCCESS(status))
      {
        DbgPrintEx(0, 0, "IoCreateDevice Error.
    ");
        return status;
      }
    
      // 设置了一个设备对象名称和该设备的用户可视名称之间的符号链接
      // 向应用程序公开的连接符号,别的程序才能和你的驱动通信
      status = IoCreateSymbolicLink(&symbolName, &deviceName);
      if (!NT_SUCCESS(status))
      {
        DbgPrintEx(0, 0, "IoCreateSymbolicLink Error.
    ");
        IoDeleteDevice(pDeviceObject);
        return status;
      }
    
      DbgPrintEx(0, 0, "Driver load success.
    "); // 查看驱动设备列表: >driverquery
    
      // irp,当用户模式打开使用此驱动时通信
      SIZE_T i;
      for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {
        pDriverObject->MajorFunction[i] = DispatchHandle;
      }
      // 也可以单独设置
      // pDriverObject->MajorFunction[IRP_MJ_CREATE] = CreateCall;
      // pDriverObject->MajorFunction[IRP_MJ_CLOSE] = CloseCall;
      // pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoControl;
    
      pDeviceObject->Flags |= DO_DIRECT_IO;
      pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    
      return status;
    }
    

    用户模式(管理员模式启动) main.cpp

    #include <iostream>
    #include <Windows.h>
    
    #define IO_READ_Control CTL_CODE(FILE_DEVICE_UNKNOWN, 0x777, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
    
    typedef struct _Player
    {
      ULONG id;
      ULONG hp;
      ULONG mp;
    } Player, * PPlayer;
    
    using namespace std;
    
    const WCHAR* symbolName = L"\\.\hsys";
    
    int main()
    {
      HANDLE hDriver;
    
      // 使用驱动就和打开文件一样
      hDriver = CreateFileW(symbolName, GENERIC_ALL, 0, 0, OPEN_EXISTING, 0, 0); // IRP_MJ_CREATE
    
      if (hDriver == INVALID_HANDLE_VALUE)
      {
        printf("打开驱动失败
    ");
        return 0;
      }
    
      Player player;
      DWORD Bytes;
    
      // IRP_MJ_DEVICE_CONTROL
      if (!DeviceIoControl(hDriver, IO_READ_Control,
        &player, sizeof(Player), // 发送
        &player, sizeof(Player), // 接收,不接收可以填NULL
        &Bytes, 0))
      {
        printf("发送消息失败
    ");
        CloseHandle(hDriver); // IRP_MJ_CLOSE
        return 0;
      }
    
      printf("id(%d), hp(%d), mp(%d)", player.id, player.hp, player.mp); // id(1), hp(100), mp(50)
    
      CloseHandle(hDriver); // IRP_MJ_CLOSE
      return 0;
    }
    
  • 相关阅读:
    【Hadoop学习之七】Hadoop YARN
    【Hadoop学习之六】MapReduce原理
    【Hadoop学习之五】win7+Eclipse+hadoop3搭建本机开发环境
    【Hadoop学习之四】HDFS HA搭建(QJM)
    【Hadoop学习之三】Hadoop全分布式安装
    【Hadoop学习之二】Hadoop伪分布式安装
    【Hadoop学习之一】Hadoop介绍
    【Linux学习十】负载均衡带来tomcat的session不一致问题
    【Linux学习九】负载均衡
    Okhttp3基本使用
  • 原文地址:https://www.cnblogs.com/ajanuw/p/13810181.html
Copyright © 2020-2023  润新知