跟老师的例子写的第一个驱动

自己跟着教程写的驱动,觉得重要的地方都标了注释

#include <ntddk.h>

#define device_name L"\\device\\myfirstdrv"
#define link_name L"\\dosdevices\\myfirstdrv"

#define ioctrl_base 0x8000

#define myioctrl_code(i) \
	CTL_CODE(FILE_DEVICE_UNKNOWN,ioctrl_base+i,METHOD_BUFFERED,FILE_ANY_ACCESS)  //定义控制码,其中CTL_CODE是库里的宏

#define ctl_hello myioctrl_code(0)
#define ctl_print myioctrl_code(1)
#define ctl_bye myioctrl_code(2)


NTSTATUS dispathcommon(PDEVICE_OBJECT pobject, PIRP pirp)
{
	pirp->IoStatus.Status = STATUS_SUCCESS;//告诉r3成功
	pirp->IoStatus.Information = 0;//通讯的有效字节数
	
	IoCompleteRequest(pirp, IO_NO_INCREMENT);//结束掉这个irp

	return STATUS_SUCCESS;//告诉内核驱动对象io管理器成功

}
NTSTATUS dispathcreat(PDEVICE_OBJECT pobject, PIRP pirp)
{
	pirp->IoStatus.Status = STATUS_SUCCESS;
	pirp->IoStatus.Information = 0;
	
	IoCompleteRequest(pirp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}
NTSTATUS dispathread(PDEVICE_OBJECT pobject, PIRP pirp)
{
	PVOID preadbuffer = NULL;           //参数初始化(buff地址,buff长度,irp栈地址)
	ULONG ureadlength = 0;
	PIO_STACK_LOCATION pstack = NULL;
	ULONG umin = 0;
	ULONG uhellostr = 0;

	uhellostr = (wcslen(L"hello world") + 1)*sizeof(WCHAR);//计算字符串的长度sizeof保证可移植性

	preadbuffer = pirp->AssociatedIrp.SystemBuffer;   //从irp头部拿需要拷入的buff地址,因为是buff_io所以是systembuffer
	pstack = IoGetCurrentIrpStackLocation(pirp);      //从irp下部拿栈地址,read,write,iocontrol都在栈上的一个union中

	ureadlength = pstack->Parameters.Read.Length;   //从栈中拿buff的长度
	umin = ureadlength > uhellostr ? uhellostr : ureadlength;//确定buff的实际长度,保证数据不会溢出
	RtlCopyMemory(preadbuffer, L"hellow world", umin);//内核内存拷贝函数

	pirp->IoStatus.Status = STATUS_SUCCESS;
	pirp->IoStatus.Information = umin;

	IoCompleteRequest(pirp,IO_NO_INCREMENT);

	return STATUS_SUCCESS;


}
NTSTATUS dispathwrite(PDEVICE_OBJECT pobject, PIRP pirp)
{
	
	PVOID pwritebuffer = NULL;                //参数初始化(irp中buff地址、长度、irp栈地址)
	ULONG uwritelengh = 0;
	PIO_STACK_LOCATION pstack = NULL;

	PVOID pbuffer = NULL;                    //参数初始化(内核中buff地址)

	pwritebuffer = pirp->AssociatedIrp.SystemBuffer;

	pstack = IoGetCurrentIrpStackLocation(pirp);
	uwritelengh = pstack->Parameters.Write.Length;

	pbuffer = ExAllocatePoolWithTag(PagedPool, uwritelengh, 'tset');//在堆上往内核中分配内存:分页池(首选),源地址,源地址长度,标记(便于以后的测试,大小为4字节)
	if (pbuffer == NULL)  //内存分配失败的处理(空间不够)
	{
		pirp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		pirp->IoStatus.Information = 0;
		IoCompleteRequest(pirp, IO_NO_INCREMENT);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	memset(pbuffer, 0, uwritelengh);//对新分配的内存全部填0初始化处理

	RtlCopyMemory(pbuffer, pwritebuffer, uwritelengh);//r3的内容写入r0

	ExFreePool(pbuffer);//因为实际什么都没做,所以释放内存
	pbuffer = NULL;//防止野指针(因为函数快结束所以意义不大)

	pirp->IoStatus.Status = STATUS_SUCCESS;
	pirp->IoStatus.Information =uwritelengh;

	IoCompleteRequest(pirp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;

}
NTSTATUS dispathioctrl(PDEVICE_OBJECT pobject, PIRP pirp)
{
	ULONG uioctrlcode = 0;          //通过查阅r3的deviceiocontrol函数,得知须用到5个参数:控制码、写入缓存地址、写入缓存长度、读取缓存地址、读取缓存长度
	PVOID pinputbuff = NULL;        //分别对它们进行初始化
	PVOID poutputbuff = NULL;

	ULONG uinputlength = 0;
	ULONG uoutputlength = 0;
	PIO_STACK_LOCATION pstack = NULL;

	pinputbuff = poutputbuff = pirp->AssociatedIrp.SystemBuffer;

	pstack = IoGetCurrentIrpStackLocation(pirp);
	uinputlength = pstack->Parameters.DeviceIoControl.InputBufferLength;    //控制码、地址长度都在irp栈里
	uoutputlength = pstack->Parameters.DeviceIoControl.OutputBufferLength;

	uioctrlcode = pstack->Parameters.DeviceIoControl.IoControlCode;

	switch (uioctrlcode)
	{
	case ctl_hello:
		DbgPrint("hellow iocontrol\n");
		break;
	case ctl_print:
		DbgPrint("%ws\n",pinputbuff);
		break;
	case ctl_bye:
		break;
		DbgPrint("goodbye iocontrol\n");
	default:
		DbgPrint("unknow iocontrol\n");
	}

	pirp->IoStatus.Status = STATUS_SUCCESS;
	pirp->IoStatus.Information = 0;

	IoCompleteRequest(pirp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}
NTSTATUS dispathclose(PDEVICE_OBJECT pobject, PIRP pirp)
{
	pirp->IoStatus.Status = STATUS_SUCCESS;
	pirp->IoStatus.Information = 0;

	IoCompleteRequest(pirp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}
NTSTATUS dispathclean(PDEVICE_OBJECT pobject, PIRP pirp)
{
	pirp->IoStatus.Status = STATUS_SUCCESS;
	pirp->IoStatus.Information = 0;

	IoCompleteRequest(pirp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}
void driverunload(PDRIVER_OBJECT pdriverobject)
{
	UNICODE_STRING ulinkname = { 0 };
	RtlInitUnicodeString(&ulinkname, link_name);
	IoDeleteSymbolicLink(&ulinkname);

	IoDeleteDevice(pdriverobject->DeviceObject);

	DbgPrint("driver unload!");
	
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pdriverobject,PUNICODE_STRING pregpath)
{
	UNICODE_STRING udevicename = { 0 };//定义一个设备名
	UNICODE_STRING ulinkname = { 0 };//定义一个符号链接名
	NTSTATUS ntstatus = 0;//驱动里NTSTATUS返回0才为成功
	PDEVICE_OBJECT pdeviceobject = NULL;
	ULONG i = 0;
	DbgPrint("driver load begin\n");//驱动中的打印函数
	RtlInitUnicodeString(&udevicename,device_name);//设备名初始化
	RtlInitUnicodeString(&ulinkname,link_name);//符号链接名初始化
	ntstatus = IoCreateDevice(pdriverobject,
		0, &udevicename,FILE_DEVICE_UNKNOWN,0,FALSE,&pdeviceobject);//创建设备对象,用来接收irp
	                                                                //(驱动对象,设备扩展长度,设备类型,设备属性,驱动是否被独占,设备对象指针)
	if (!NT_SUCCESS(ntstatus))//ntstatus<0的处理
	{
		DbgPrint("iocreatdevice faild:%x", ntstatus);
		return ntstatus;
	}
	pdeviceobject->Flags |= DO_BUFFERED_IO;//最安全

	ntstatus = IoCreateSymbolicLink(&ulinkname, &udevicename);//创建符号链接,为了驱动能被看到
	if (!NT_SUCCESS(ntstatus))
	{
		IoDeleteDevice(pdeviceobject);//如果出错应把分配的资源删除,要删掉设备对象
		DbgPrint("IoCreateSymbolicLink failed:%x",ntstatus);
		return ntstatus;
	}
	for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION+1; i++)//将分发函数初始化
	{
		pdriverobject->MajorFunction[i] = dispathcommon;
	}
	
	pdriverobject->MajorFunction[IRP_MJ_CREATE] = dispathcreat;//分发函数的注册
	pdriverobject->MajorFunction[IRP_MJ_READ] = dispathread;
	pdriverobject->MajorFunction[IRP_MJ_WRITE] = dispathwrite;
	pdriverobject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = dispathioctrl;
	pdriverobject->MajorFunction[IRP_MJ_CLEANUP] = dispathclean;
	pdriverobject->MajorFunction[IRP_MJ_CLOSE] = dispathclose;

	pdriverobject->DriverUnload = driverunload;

	DbgPrint("driver load ok!\n");

	return STATUS_SUCCESS;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值