0x00代码
//驱动程序
MyFirstDriver.c
#include <wdm.h>
//所有支持PNP的内核模式驱动程序都必须提供AddDevice例程.
//DriverObject->DriverExtension->AddDevice 回调
/*
DRIVER_ADD_DEVICE DriverAddDevice;
NTSTATUS DriverAddDevice(
_DRIVER_OBJECT *DriverObject,
_DEVICE_OBJECT *PhysicalDeviceObject
)
{...}
*/
//驱动卸载
void DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("== DriverUnload ==");
if (DriverObject->DeviceObject)
{
IoDeleteDevice(DriverObject->DeviceObject);
UNICODE_STRING SymbolName = { 0 };
RtlInitUnicodeString(&SymbolName, L"\\??\\MyFirstDevice");
IoDeleteSymbolicLink(&SymbolName);
}
return;
}
NTSTATUS DispatchCreate(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
DbgPrint("== DispatchCreate ==");
NTSTATUS status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return status;
}
NTSTATUS DispatchCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DbgPrint("== DispatchCleanup ==");
NTSTATUS status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS DispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DbgPrint("== DispatchClose ==");
NTSTATUS status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
/*驱动程序入口
* 加载驱动后调用该函数进行初始化工作
*/
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
DriverObject->DriverUnload = DriverUnload; //驱动卸载
//1 创建设备
PDEVICE_OBJECT pDevice;
UNICODE_STRING DeviceName = { 0 };
RtlInitUnicodeString(&DeviceName, L"\\Device\\MyFirstDevice");
status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevice);
if (status != STATUS_SUCCESS)
{
DbgPrint("IoCreateDevice Failed");
return status;
}
//2 创建符号链接
UNICODE_STRING SymbolName = { 0 };
//访问\\.\MyFirstDevice == 访问\Device\MyFirstDevice设备
//系统盘符也使用了符号链接
RtlInitUnicodeString(&SymbolName, L"\\??\\MyFirstDevice");
status = IoCreateSymbolicLink(&SymbolName, &DeviceName);
if (status != STATUS_SUCCESS)
{
DbgPrint("IoCreateDevice Failed");
IoDeleteDevice(pDevice);
return status;
}
//3 分派IRP
//调用表,使用索引来标识函数
//该表以驱动对象来维护,即该驱动下设备的回调相同
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
return status;
}
//控制台程序
MyFirstDriverConsole.c
#include <windows.h>
#include <stdio.h>
int main(int argc,char** argv)
{
//使用符号链接访问设备
//CreateFile() == IRP_MJ_CREATE回调
HANDLE handle = CreateFile(L"\\\\.\\MyFirstDevice", GENERIC_READ|| GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if (handle == INVALID_HANDLE_VALUE)
{
printf("CreateFile failed\n");
system("pause");
return 0;
}
printf("CreateFile success\n");
system("pause");
//关闭设备
//CloseHandle() == IRP_MJ_CLEANUP() + IRP_MJ_CLOSE()回调
CloseHandle(handle);
system("pause");
return 0;
}
0x01 设备与符号链接
驱动 -> 创建/管理设备对象
符号链接 -> 对应设备
0x02 文档
驱动
https://docs.microsoft.com/en-us/windows-hardware/drivers/
内核
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/_kernel/
内核模式驱动程序架构设计指南
https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/
0X03扩展
status = IoCreateDevice(0xFFFFA60CEAD90B30, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevice);
修改了驱动对象,成功创建了该驱动下的设备