Windows驱动开发学习2

在看梦无极关于驱动开发的教程,感觉讲的很细致。

 I/O管理器作用:

1.    I/O管理器创建一个数据包代表一个对应的请求,并且把该数据包(即IRP)传递给正确的驱动程序,当请求完成时再处理该数据包。
2.    除了创建和处理请求的数据包以外,I/O管理器也提供一些对于不同驱动程序都通用的代码,驱动程序可以调用这些代码来完成它们的I/O处理。由于这些通用的任务都被合并到I/O管理器中了,因此,单独的驱动程序变得更为简单。
3.    驱动程序所具有的一致的、模块化的接口使得I/O管理器能够调用任何一个驱动程序,而无需任何有关驱动程序数据结构或内部细节的专门知识。
4.    操作系统对待所有的I/O请求就好像它们都是针对一个文件进行的操作一样;驱动程序将这些请求从一个针对虚拟文件的请求,转变一个与硬件相关的请求。

正确寻找驱动的流程:

1.用户态下接受符号链接,在系统命名对象中(使用WinObj查看系统当前的内核对象以及命名空间)找到设备。

2.查询到具体设备。

3.设备信息压入到数据包(IRP)中。

IRP即I/O Request Packet,是一个包含数据缓冲区的数据结构。Windows设备驱动程序通常需要处理IRP来与用户模式的程序进行通信。处于用户模式的程序可以打开一个文件句柄并向其中写入信息。在内核中,这个写入操作表示一个IRP。例如用户态程序向文件句柄中写入字符串"HELLO DRIVER!",则内核将会创建一个包含了缓冲区和字符串"HELLO DRIVER!"的IRP。用户态与内核态间的通信通过IRP进行。

IRP生命周期是在I/O管理器<->内核模式驱动程序<->硬件设备这三个阶段。

这里梦无极推荐了几本书《深入解析windows操作系统》《Windows内核原理与实现》《Windows内核情景分析》

下面自己跟着写了一个简单的驱动。

#include"ntddk.h"
VOID MyUnload(PDRIVER_OBJECT pDriverObject)
{
	UNICODE_STRING usSymName;
	RtlInitUnicodeString(&usSymName, L"\\Device\\FirstDevice");
		if (pDriverObject->DeviceObject != NULL)
		{
			IoDeleteSymbolicLink(&usSymName);
			IoDeleteDevice(pDriverObject->DeviceObject);
			KdPrint(("delete device success."));
		}
}

NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject)
{
	NTSTATUS Status;
	PDEVICE_OBJECT pDevObj;                                        //Pointer back to the device object
	UNICODE_STRING usDevName;                                      //Devicename
	UNICODE_STRING usSymName;                                      //Symbolic link name
	RtlInitUnicodeString(&usDevName, L"\\Device\\FirstDevice");
		Status = IoCreateDevice(pDriverObject,
			0,
			&usDevName,
			FILE_DEVICE_UNKNOWN,
			FILE_DEVICE_SECURE_OPEN,
			TRUE,
			&pDevObj);                        //使用 IoCreateDevice 函数创建一个设备对象. 设备类型为 "FILE_DEVICE_UNKNOWN" ,是一种独占的设备,在运行时只能被一个应用程序所使用。
	if (!NT_SUCCESS(Status))
	{
		return Status;
	}
	pDevObj->Flags |= DO_BUFFERED_IO;
	RtlInitUnicodeString(&usSymName, L"//??//FirstDevice");              //??是全局GLOBAL
		IoCreateSymbolicLink(&usSymName, &usDevName);                    //使用 IoCreateSymbolicLink 函数宏创建了设备符号链接,并对创建结果判断进行必要的失败处理。与应用程序进行通信。如果创建失败,则删除已经创建的设备对象。
	if (!NT_SUCCESS(Status))
	{
		IoDeleteDevice(pDevObj);
		return Status;
	}
	return STATUS_SUCCESS;
}



NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)     //驱动对象的指针和注册表子键的字符串指针
{
	KdPrint(("successed"));
	NTSTATUS status;
	status = CreateDevice(pDriverObject);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("creat device failed."));
	}
	else
	{
		KdPrint(("creat device successed."));
		KdPrint(("%wZ", pRegistryPath));
	}
	pDriverObject->DriverUnload = MyUnload;
		return STATUS_SUCCESS;                                                       //无须重启机器的情况下安全地加载和卸载驱动程序
}
发布了13 篇原创文章 · 获赞 2 · 访问量 402

猜你喜欢

转载自blog.csdn.net/z17805008775/article/details/100516703