驱动开发——第一个HelloDDK

news/2024/11/16 3:48:18/

友链

非即插即用驱动

helloddk.h

// 保证头文件只被编译一次
// 因为在实际项目中,一个头文件可能会被另一个头文件包含
// 比如b.h中包含了a.h
// 然后在c.c中有如下代码:
/*
#include<a.h>
#include<b.h>
*/
// 这样一来,a.h就被包含了两次
// 而#pragma once可以保证a.h只被编译一次
// 从而提高编译效率
#pragma once// 下面的这段条件编译在C++项目中是非常常见的
// 它使得我们可以在C++项目中使用C中的头文件
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif// 分页标记、非分页标记和初始化内存块
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
// INIT标志指明函数只是在加载的时候需要载入内存
// 在驱动程序成功加载之后,函数可以从内存中卸载掉
#define INITCODE code_seg("INIT")#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")#define arraysize(p)    (sizeof(p)/sizeof((p)[0]))// 定义机构体 _DEVICE_EXTENSION ,并起别名
// 设备扩展结构体
// 该结构体广泛应用于驱动程序中
// 根据不同程序的需要,用于补充定义设备的相关信息
typedef struct _DEVICE_EXTENSION {PDEVICE_OBJECT pDevice;UNICODE_STRING ustrDeviceName;      // 设备名称UNICODE_STRING ustrSymLinkName;     // 符号链接名称
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;// 函数声明
// 这个IN关键字可能是用来说明参数是传入参数
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);

helloddk.cpp

#include "HelloDDK.h"/*
初始化驱动程序,定位和申请硬件资源,创建内核对象
参数列表pDriverObject:从IO管理器中传进来的驱动对象pRegistryPath:驱动程序在注册表中的路径
返回值:返回初始化驱动状态
*/
// 使用extern "C"对该函数进行修饰,这样在编译的时候会编译成_DriverEntry@8
// 如果没有这个修饰符的话,编译器会按照C++的符号名进行编译,链接的时候会报错
// 指明函数是加载到INIT内存区域中
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath)
{NTSTATUS status;// 运行在内核中的程序是没有console的,所以只能使用KdPrint宏来输出调试信息// 这个宏只在调试版本中有作用(Free)// 在发行版本中不执行任何操作(Checked)KdPrint(("Enter DriverEntry\n"));// 注册其他驱动调用函数入口// 将我们自己定义的函数的地址传送给操作系统// 操作系统会在合适的时候调用这些函数// 通过下面的赋值操作// 在驱动卸载的时候,HelloDDKUnload函数会被调用// 在驱动程序创建、关闭和读写相关的IRP时,HelloDDKDispatchRoutine函数会被调用pDriverObject->DriverUnload                     = HelloDDKUnload;pDriverObject->MajorFunction[IRP_MJ_CREATE]     = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_CLOSE]      = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_WRITE]      = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_READ]       = HelloDDKDispatchRoutine;// 创建驱动设备对象status = CreateDevice(pDriverObject);KdPrint(("DriverEntry end\n"));// 返回CreateDevice的结果return status;
}// 定义CreateDevice函数
#pragma INITCODE
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject)
{NTSTATUS            status;PDEVICE_OBJECT      pDevObj;PDEVICE_EXTENSION   pDevExt;   // 创建设备名称// 构造Unicode字符串用来存储此设备对象的名称UNICODE_STRING devName;RtlInitUnicodeString(&devName, L"\\Device\\MyDDKDevice");// 创建设备status = IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0, TRUE,&pDevObj);if(!NT_SUCCESS(status))return status;// 表明该设备为BUFFERED_IO设备// 设备对内存的操作分为两种,一种是BUFFERED_IO,一种是DO_DIRECT_IO,后面解释pDevObj->Flags          = pDevObj->Flags | DO_BUFFERED_IO;// 填写设备的扩展结构体pDevExt                 = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;pDevExt->pDevice        = pDevObj;pDevExt->ustrDeviceName = devName;// 创建符号链接// 设备名称只在内核态可见,用户程序是看不到的// 因此需要暴露出一个符号连接,该符号链接指向真正的设备名称UNICODE_STRING SymLinkName;RtlInitUnicodeString(&SymLinkName, L"\\??\\HelloDDK");pDevExt->ustrSymLinkName = SymLinkName;// 创建成功则返回,否则调用IoDeleteDevice删除设备status = IoCreateSymbolicLink(&SymLinkName, &devName);if(!NT_SUCCESS(status)){IoDeleteDevice(pDevObj);return status;}return STATUS_SUCCESS;
}// 定义驱动卸载函数
#pragma PAGEDCODE
VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject)
{PDEVICE_OBJECT pNextObj;KdPrint(("Enter DriverUnload\n"));// 从驱动对象中获得设备对象pNextObj = pDriverObject->DeviceObject;// 遍历设备对象while(pNextObj != NULL){PDEVICE_EXTENSION pDevExt   = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;// 删除符号链接UNICODE_STRING pLinkName    = pDevExt->ustrSymLinkName;// 删除设备对象的符号链接IoDeleteSymbolicLink(&pLinkName);pNextObj                    = pNextObj->NextDevice;IoDeleteDevice(pDevExt->pDevice);}
}// 定义默认派遣例程
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{KdPrint(("Enter HelloDDKDispatchRoutine\n"));NTSTATUS status = STATUS_SUCCESS;// 完成IRP// 关于IRP的介绍,在后面会介绍pIrp->IoStatus.Status = status;pIrp->IoStatus.Information = 0;IoCompleteRequest(pIrp, IO_NO_INCREMENT);KdPrint(("Leave HelloDDKDispatchRoutine\n"));return status;
}

source

TARGETNAME=HelloDDK
TARGETTYPE=DRIVER
TARGETPATH=OBJINCLUDES=$(BASEDIR)\inc;\$(BASEDIR)\inc\ddk;\SOURCES=helloddk.cpp\

http://www.ppmy.cn/news/734973.html

相关文章

python提取GO信息

1.原始数据&#xff1a; 原始数据链接&#xff1a; http://current.geneontology.org/ontology/go-basic.obo原始数据样式&#xff1a; 2.目标格式&#xff1a; 3.代码&#xff1a; with open("go-basic.obo","r") as file:lib{}for line in file:lin…

天书夜读笔记——C++写的内核驱动程序

友链 extern "C" {#include<ntifs.h> }class MyDriver { public:MyDriver(PDRIVER_OBJECT driver);virtual NTSTATUS OnDispatch(PDEVICE_OBJECT dev, PIRP irp) {return STATUS_UNSUCCESSFUL;};static MyDriver *d_my_driver;private:static NTSTATUS sDisp…

适用于XP的DDK

友链 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 占位 …

Ubuntu 18.04 安装网卡驱动(有线连接)

之前一直用小米的驱动&#xff0c;但是感觉太慢了&#xff0c;所以还是决定使用有线连接。 但是之前进入Linux系统后&#xff0c;有线连接没有&#xff0c;所以需要安装驱动。 01 查询网卡类型&#xff08;Windows&#xff09; 进入windows系统&#xff0c;进入CMD命令行&am…

linux装完显卡驱动分辨率低,装上显卡驱动后屏幕分辨率变低了,肿么破。。。...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 00:00.0 Host bridge: Intel Corporation 2nd Generation Core Processor Family DRAM Controller (rev 09) Subsystem: Device 1b0a:2099 Kernel driver in use: agpgart-intel 00:01.0 PCI bridge: Intel Corporation Xeon E3-1…

Python 之测试数据驱动

Parameterized 模块 parameterized 第三方包的安装&#xff1a; pip install parameterized $ pip install parameterized Collecting parameterizedDownloading https://files.pythonhosted.org/packages/65/d4/b0b626eb263a4c2aa3ca3cd20ea3db410db837f7f6b5d3fc4a6c4bee363…

华为服务器linux版的网卡驱动下载,华为服务器RH2288H V3 服务器上安装Windows2008 R2 SP1指导书...

1 安装前准备 1.1 硬件环境准备 无 备注: 本指导书以虚拟光驱、虚拟软驱为例,如使用物理光驱、物理软驱安装系统操作则以实际系统光盘、软盘代替。 1.2 软件环境准备 1.2.1 准备操作系统安装文件 到windows 官网下载安装文件,或者采用光盘安装文件。 …

Clover 驱动文件夹_Intel全系利核显驱动教程

关注上方蓝字关注黑果小白 让小白为你排忧解难 1 驱动准备 清理旧驱动 显卡驱动准备工作,请清理以前的驱动→获取 IGPU 的设备路径→填入 ig-platform-id→填入 device-id关于HD4600集显驱动,举个例子:驱动完 HD4600 也就这点东西。仿冒设备id及核显型号就可以了!缩写解释缩…