一、基础知识准备
1. 熟悉 C/C++ 语言
- 掌握 C++ 基础语法:类、继承、多态、模板等。
- 理解内存管理:new/delete、指针、引用、RAII 等。
本文介绍 C++ 驱动开发所需的基础知识、环境搭建及核心技术点。涵盖操作系统原理、驱动入口、设备对象、IRP 处理、内存同步管理及用户内核通信(IOCTL)。重点说明 Windows 下使用 C++ 开发驱动的限制,如禁用标准库和异常机制,并提供从项目创建到调试部署的分步流程示例。

DriverEntry 函数。extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryPath) { // 初始化代码 }
IoCreateDevice)IoCreateSymbolicLink)ExAllocatePoolWithTag、ExFreePool)KSPIN_LOCK)、互斥锁等,避免多线程访问冲突。DbgPrint 打印日志,辅助调试。Unload),清理资源、删除符号链接和设备对象。Windows 驱动开发官方推荐使用 C,但可以用 C++,但需注意:
extern "C" 导出入口函数。MajorFunction 数组,指定各类 IRP 的处理函数。IOCTL(Input Output Control)是一种常用的用户层与内核驱动进行命令/数据交互的机制。用户程序通过 DeviceIoControl(Windows)或 ioctl(Linux)向驱动发送命令,驱动收到后在 IRP_MJ_DEVICE_CONTROL 回调中处理。
Windows 下 IOCTL 码一般通过宏定义:
// 示例:自定义 IOCTL 码
#define IOCTL_MYDRV_GET_VALUE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_MYDRV_SET_VALUE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
尽量使用简单的结构体,避免使用复杂的 C++ 特性(如虚函数、继承),以保证兼容性:
typedef struct _MYDRV_DATA {
ULONG Value;
} MYDRV_DATA, *PMYDRV_DATA;
HANDLE hDevice = CreateFile(L"\\.\MyDevice", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
MYDRV_DATA data = { 123 };
DWORD returned = 0;
// 发送 SET_VALUE
DeviceIoControl(hDevice, IOCTL_MYDRV_SET_VALUE, &data, sizeof(data), NULL, 0, &returned, NULL);
// 发送 GET_VALUE
MYDRV_DATA outData = { 0 };
DeviceIoControl(hDevice, IOCTL_MYDRV_GET_VALUE, NULL, 0, &outData, sizeof(outData), &returned, NULL);
printf("内核返回值:%d\n", outData.Value);
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDeviceControl;
extern "C" NTSTATUS MyDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
PIO_STACK_LOCATION irpSp;
NTSTATUS status = STATUS_SUCCESS;
ULONG inLen, outLen;
PMYDRV_DATA pData;
static ULONG g_Value = 0; // 内核全局变量
irpSp = IoGetCurrentIrpStackLocation(Irp);
inLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;
outLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_MYDRV_SET_VALUE:
if (inLen < sizeof(MYDRV_DATA)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
pData = (PMYDRV_DATA)Irp->AssociatedIrp.SystemBuffer;
g_Value = pData->Value;
break;
case IOCTL_MYDRV_GET_VALUE:
if (outLen < sizeof(MYDRV_DATA)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
pData = (PMYDRV_DATA)Irp->AssociatedIrp.SystemBuffer;
pData->Value = g_Value;
Irp->IoStatus.Information = sizeof(MYDRV_DATA);
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
SystemBuffer 进行数据交换,需设置 METHOD_BUFFERED。DbgPrint 辅助调试。extern "C" void MyDriverUnload(PDRIVER_OBJECT pDriverObject) {
IoDeleteSymbolicLink(&g_SymbolicLinkName);
IoDeleteDevice(pDriverObject->DeviceObject);
DbgPrint("MyDriver unloaded.\n");
}
C++ 驱动开发技术要点:

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online