驱动代码
.h文件
#pragma once
#include // 引入内核文件
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// 驱动入口
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path);
#ifdef __cplusplus
}
#endif // __cplusplus
#define DEVICE_NAME L"\\Device\\MaoYu" // 驱动名
#define SYMBOL_NAME L"\\??\\MaoYu" // 对外的符号链接
// 自定义代码控制
#define USER_CODE CTL_CODE(FILE_DEVICE_UNKNOWN, 0xFFF, METHOD_BUFFERED, FILE_ANY_ACCESS)
void driver_unload(PDRIVER_OBJECT driver); // 驱动卸载回调
// 派遣函数
NTSTATUS dis_create(PDEVICE_OBJECT device, PIRP irp); // 创建
NTSTATUS dis_clean_up(PDEVICE_OBJECT device, PIRP irp); // 清除
NTSTATUS dis_close(PDEVICE_OBJECT device, PIRP irp); // 关闭
NTSTATUS dis_user_code(PDEVICE_OBJECT device, PIRP irp); // 自定义控制IO通信
// 驱动运行对象
class Cat_Driver
{
public:
explicit Cat_Driver(PDRIVER_OBJECT driver); // 构造
bool add_device(PUNICODE_STRING name); // 添加设备
bool set_symbol(PUNICODE_STRING d, PUNICODE_STRING s); // 设置符号链接
void set_flags_io(ULONG flag = DO_BUFFERED_IO); // 设置设备的传输标志
PDRIVER_DISPATCH* get_dis(); // 获取派遣函数的数组
protected:
PDRIVER_OBJECT driver_; // 驱动对象
};
.cpp文件
#include "driver.h"
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
DbgPrint("++++++ 驱动加载 ++++++");
Cat_Driver cat(driver); // 定义一个对象
UNICODE_STRING d, s; // 定义驱动名称、链接符号
RtlInitUnicodeString(&d, DEVICE_NAME); // 初始化驱动名称
RtlInitUnicodeString(&s, SYMBOL_NAME); // 初始化链接符号
if (!cat.add_device(&d)) // 如果添加驱动设备失败
{
DbgPrint("添加设备失败");
return STATUS_UNSUCCESSFUL;
}
if (!cat.set_symbol(&d, &s)) // 如果设置符号链接失败
{
DbgPrint("设置符号链接失败");
}
cat.set_flags_io(DO_BUFFERED_IO); // 设置驱动设备的传输方式
// IRP派遣函数尚未实现
cat.get_dis()[IRP_MJ_CREATE] = dis_create;
cat.get_dis()[IRP_MJ_CLEANUP] = dis_clean_up;
cat.get_dis()[IRP_MJ_CLOSE] = dis_close;
cat.get_dis()[IRP_MJ_DEVICE_CONTROL] = dis_user_code;
return STATUS_SUCCESS;
}
void driver_unload(PDRIVER_OBJECT driver) // 驱动卸载回调
{
DbgPrint(" ----------- 驱动卸载 -----------");
if (driver->DeviceObject) // 如果有创建驱动设备
{
// 删除符号链接
UNICODE_STRING s;
RtlInitUnicodeString(&s, SYMBOL_NAME);
IoDeleteSymbolicLink(&s);
IoDeleteDevice(driver->DeviceObject); // 删除设备
}
}
NTSTATUS dis_create(PDEVICE_OBJECT device, PIRP irp) // 创建
{
DbgPrint("dis 创建");
// 返回的IRP状态处理
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0L;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS dis_clean_up(PDEVICE_OBJECT device, PIRP irp) // 清除
{
DbgPrint("dis 清除");
// 返回的IRP状态处理
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0L;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS dis_close(PDEVICE_OBJECT device, PIRP irp) // 关闭
{
DbgPrint("dis 关闭");
// 返回的IRP状态处理
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0L;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS dis_user_code(PDEVICE_OBJECT device, PIRP irp)
{
DbgPrint("dis 自定义控制");
auto stack = IoGetCurrentIrpStackLocation(irp); // 获取当前栈IO位置
auto in_length = stack->Parameters.DeviceIoControl.InputBufferLength; // 可读长度
auto out_length = stack->Parameters.DeviceIoControl.OutputBufferLength; // 可写长度
auto code = stack->Parameters.DeviceIoControl.IoControlCode; // 控制代码
PDWORD32 buffer = reinterpret_cast<PDWORD32>(irp->AssociatedIrp.SystemBuffer); // 缓冲区
DbgPrint("获取到应用的输入 %u", *buffer);
switch (code)
{
case USER_CODE:
*buffer *= 5; // 将应用层的值 *5 在返回去
irp->IoStatus.Status = STATUS_SUCCESS; // 成功
irp->IoStatus.Information = 4L; // 传输的字节长度
break;
default:
irp->IoStatus.Status = STATUS_UNSUCCESSFUL; // 不成功
irp->IoStatus.Information = 0L; // 传输的字节长度
break;
}
IoCompleteRequest(irp, IO_NO_INCREMENT); // 调用者已经完成了对给定I/O请求的所有处理
return STATUS_SUCCESS;
}
Cat_Driver::Cat_Driver(PDRIVER_OBJECT driver) // 构造
:driver_(driver)
{
driver_->DriverUnload = driver_unload; // 驱动设置卸载回调
}
bool Cat_Driver::add_device(PUNICODE_STRING name) // 添加设备
{
PDEVICE_OBJECT d = nullptr; // 设备指针
return NT_SUCCESS(IoCreateDevice(driver_, 0, name, FILE_DEVICE_UNKNOWN, 0L, TRUE, &d));
}
bool Cat_Driver::set_symbol(PUNICODE_STRING d, PUNICODE_STRING s) // 设置符号链接
{
return NT_SUCCESS(IoCreateSymbolicLink(s, d));
}
void Cat_Driver::set_flags_io(ULONG flag) // 设置传输方式
{
driver_->DeviceObject->Flags |= flag;
}
PDRIVER_DISPATCH* Cat_Driver::get_dis() // 返回派遣数组
{
return driver_->MajorFunction;
}
应用层代码
#include
#in#pragma once
#include // 引入内核文件
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path); // 驱动入口
#ifdef __cplusplus
}
#endif // __cplusplus
#define DEVICE_NAME L"\\Device\\MaoYu" // 驱动名
#define SYMBOL_NAME L"\\??\\MaoYu" // 对外的符号链接
// 自定义代码控制
#define USER_CODE CTL_CODE(FILE_DEVICE_UNKNOWN, 0xFFF, METHOD_BUFFERED, FILE_ANY_ACCESS)
void driver_unload(PDRIVER_OBJECT driver);
// 派遣函数
NTSTATUS dis_create(PDEVICE_OBJECT device, PIRP irp); // 创建
NTSTATUS dis_clean_up(PDEVICE_OBJECT device, PIRP irp); // 清除
NTSTATUS dis_close(PDEVICE_OBJECT device, PIRP irp); // 关闭
NTSTATUS dis_user_code(PDEVICE_OBJECT device, PIRP irp); // 自定义控制IO通信
class Cat_Driver
{
public:
explicit Cat_Driver(PDRIVER_OBJECT driver);
bool add_device(PUNICODE_STRING name);
bool set_symbol(PUNICODE_STRING d, PUNICODE_STRING s);
void set_flags_io(ULONG flag = DO_BUFFERED_IO);
PDRIVER_DISPATCH* get_dis();
protected:
PDRIVER_OBJECT driver_;
};
clude<Windows.h>
#define DEVICE_NAME L"\\\\.\\MaoYu" // 驱动设备的符号链接
// 驱动通信IO控制码
#define USER_CODE CTL_CODE(FILE_DEVICE_UNKNOWN, 0xFFF, METHOD_BUFFERED, FILE_ANY_ACCESS)
using namespace std;
int main(int argc, char** argv)
{
// 打开驱动设备
auto h_file = ::CreateFileW(DEVICE_NAME, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h_file == INVALID_HANDLE_VALUE) // 如果设备打开失败,则打印错误码
{
cout << "错误码:" << ::GetLastError() << endl;
system("pause");
return 1;
}
else
{
cout << "打开设备成功" << endl;
}
system("pause");
DWORD a = 666, b = 0;
DWORD out_length = 0; // 此变量接收驱动返回的长度
OVERLAPPED overlapped; // 包含异步(重叠)输入/输出(I/O)中使用的信息。包含异步(重叠)输入/输出(I/O)中使用的信息。
memset(&overlapped, 0, sizeof(overlapped)); // 使用之前必须初始化该内存为 0
// 与驱动设备进行通信 驱动设备会将 a *=5 然后写入到 b 变量中
if (!DeviceIoControl(h_file, USER_CODE, &a, sizeof(a), &b, sizeof(b), &out_length, &overlapped))
{
cout << "错误码:" << ::GetLastError() << endl;
}
else
{
cout << "b = " << b << endl;
}
if (::CloseHandle(h_file)) // 关闭驱动设备
{
cout << "关闭设备成功" << endl;
}
else
{
cout << "关闭设备失败" << endl;
}
system("pause");
}