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.\n");
  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!!\n");
  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.\n");
    return status;
  }

  // 设置了一个设备对象名称和该设备的用户可视名称之间的符号链接
  // 向应用程序公开的连接符号,别的程序才能和你的驱动通信
  status = IoCreateSymbolicLink(&symbolName, &deviceName);
  if (!NT_SUCCESS(status))
  {
    DbgPrintEx(0, 0, "IoCreateSymbolicLink Error.\n");
    IoDeleteDevice(pDeviceObject);
    return status;
  }

  DbgPrintEx(0, 0, "Driver load success.\n"); // 查看驱动设备列表: >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("打开驱动失败\n");
    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("发送消息失败\n");
    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;
}
posted @ 2020-10-13 17:36  Ajanuw  阅读(475)  评论(0编辑  收藏  举报