Windows驱动开发WDM (2)- 一个简单的WDM驱动程序

这个例子是从《windows驱动开发技术详解》的光盘上copy的,我只是自己稍微改了一下。

 

入口函数DriverEntry

#pragma INITCODE 
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
								IN PUNICODE_STRING pRegistryPath)
{
	KdPrint(("Enter DriverEntry\n"));

	pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;
	pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;
	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = 
	pDriverObject->MajorFunction[IRP_MJ_CREATE] = 
	pDriverObject->MajorFunction[IRP_MJ_READ] = 
	pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;
	pDriverObject->DriverUnload = HelloWDMUnload;

	KdPrint(("Leave DriverEntry\n"));
	return STATUS_SUCCESS;
}

提供4个派遣函数:

HelloWDMAddDevice

HelloWDMPnp

HelloWDMDispatchRoutine

HelloWDMUnload

在DriverEntry里面简单的设置一下。

AddDevice函数

AddDevice函数是WDM驱动特有的,NT驱动没有,这也是主要的区别之一。先给出代码:

#pragma PAGEDCODE
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject)
//DriverObject就是指向本驱动程序的一个对象,是由PNP管理器传递进来的。
//PhysicalDeviceObject是PNP管理器传递进来的底层驱动设备对象,这个东西在NT驱动中是没有的。通常称之为PDO,确切的说是由总线驱动创建的。
{ 
	PAGED_CODE();
	KdPrint(("Enter HelloWDMAddDevice\n"));

	NTSTATUS status;
	PDEVICE_OBJECT fdo;
	UNICODE_STRING devName;
	RtlInitUnicodeString(&devName,L"\\Device\\MyWDMDevice");//设备名称,设备名称只能被内核模式下的其他驱动所识别。

	//创建FDO(Function Device Object)
	status = IoCreateDevice(
		DriverObject,
		sizeof(DEVICE_EXTENSION),
		&(UNICODE_STRING)devName,
		FILE_DEVICE_UNKNOWN,
		0,
		FALSE,
		&fdo);
	if( !NT_SUCCESS(status))
		return status;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
	pdx->fdo = fdo;
	//将FDO附加在PDO上面,并且将Extension中的NextStackDevice指向FDO的下层设备。如果PDO上面有过滤驱动的话,NextStackDevice就是过滤驱动,如果没有就是PDO。
	pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
	UNICODE_STRING symLinkName;
	//创建链接符号,这样用户模式的应用就可以访问此设备。内核模式下,符号链接是以\??\开头的(或者\DosDevices\)。用户模式下则是\\.\开头。
	//这里就可以在用户模式下用\\.\HelloWDM来访问本设备。
	RtlInitUnicodeString(&symLinkName,L"\\DosDevices\\HelloWDM");

	pdx->ustrDeviceName = devName;
	pdx->ustrSymLinkName = symLinkName;
	status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName,&(UNICODE_STRING)devName);

	if( !NT_SUCCESS(status))
	{
		IoDeleteSymbolicLink(&pdx->ustrSymLinkName);
		status = IoCreateSymbolicLink(&symLinkName,&devName);
		if( !NT_SUCCESS(status))
		{
			return status;
		}
	}

	fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;//DO_BUFFERED_IO,定义为“缓冲内存设备”
	fdo->Flags &= ~DO_DEVICE_INITIALIZING;//将Flag上的DO_DEVICE_INITIALIZING位清零,保证设备初始化完毕,必须的。

	KdPrint(("Leave HelloWDMAddDevice\n"));
	return STATUS_SUCCESS;
}

IoCreateDevice有个设备类型参数,这里使用FILE_DEVICE_UNKNOWN。Windows已经预先定义了一些常见的设备类型,如果驱动设备并不在这些类型里面,有两种办法:

1. 使用FILE_DEVICE_UNKNOWN;

2. 使用>=0x8000(32768 - 65535)的值

详见:http://msdn.microsoft.com/en-us/library/windows/hardware/ff563821(v=vs.85).aspx

在DriverEntry函数里面通过pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;设置AddDevice的例程函数。我画了一个简单的图来描述AddDevice基本流程:


 AddDevice函数有2个参数:DriverObject和PDO。

DriverObject就是当前驱动程序的一个实例,PDO是物理设备对象(由总线驱动创建)。

AddDevice函数主要工作就是创建一个功能设备对象FDO,然后附加在传递进来的PDO上面。

 

PNP IRP处理函数

WDM支持PNP(即插即用),这也是不同于NT驱动的一个主要特征。所有WDM驱动都需要设置PNP IRP的派遣函数。如:

pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;

这个是在入口函数DriverEntry里面设置的。

看具体代码:

#pragma PAGEDCODE
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
                        IN PIRP Irp)
{
	PAGED_CODE();

	KdPrint(("Enter HelloWDMPnp\n"));
	NTSTATUS status = STATUS_SUCCESS;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;//DEVICE_EXTENSION是在AddDevice里面创建的。
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
1.为什么要使用海豚蓝牙音箱,能带给我什么样的音乐体验 目前市面上的蓝牙音箱基本上是一个全频段的喇叭来播放CD音质的音乐,如果是立体声的是不能通过一个喇叭来播放,无法实现空间上的立体效果,必须像漫步者的2.1级音箱一样,总共有有三个喇叭,两个卫星箱一个超重低音音箱来重现立体声,但传统的音箱体积庞大携带性比较差,于是海豚蓝牙ASIO驱动软件应运而生,解决这些让人困扰的问题。 2.使用海豚蓝牙ASIO软件有什么样的音乐体验呢? a.声音来源干净无Windows操作系统干扰,由于采用的是独占式音频通道,音频流采用的是来自于Windows的内核流,没有经过Windows的过滤器,声音采样值直接输出到声卡,声音输出比较干净未遭到破坏,满足音乐发烧友的完美音质的口味。 b.直接驱动多个蓝牙音箱实现直正的立体声效果,让您听不出来音箱放在何处,实现空间上的3D环绕效果,如果采用的蓝牙箱重低音效果不错的话,能够带给你无法语言表达的震撼效果,您可以试试播放《天之大-韩红》这首曲子。 c.适合于户外开展训练活动,您不需要携带笨重的音箱进行彩排训练,效果可以与专业级音箱相媲美,无需220V电源也可以把活动搞起来! 3. 安装必读 本版本软件是PC版本,需要安装在Windows XP/WIN7/WIN8/WIN10 操作系统上,支持主流的音乐播放软件,如百度音乐、QQ音乐、酷狗音乐、foobar2000等,只要音乐播放软件支持ASIO驱动就可以使用本软件。 硬件要求: a.适配绝大部分市面上标准音箱,像科凌的A8/A5、爱度、力勤、雅兰仕等音箱,尽量选用同款同型号音箱,否则输出延时差别较大影响音乐体验。 b.笔记本/台式机需要支持蓝牙,没有蓝牙功能可以到淘宝上购买蓝牙适配器,插在USB上即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值