通过设备接口寻找设备

设备接口

在WDM驱动中,一般很少用到设备名,也很少用到符号链接,而是用一个设备接口
来指定设备。设备接口其实就是一组全局标识,它是一个128位组成的数字,并能保证在
全世界范围内不会产生冲突。

引入设备接口的主要原因是避免设备名冲突,例如,不同的网卡厂商可能都将自己的
设备名命名为“NetCardDevice",当用户插入两块网卡时,就会引起命名冲突。而引入设
备接口的概念,各个网卡厂商用自己定义的128位数字指定自己的设备,从小概率意义上,
保证了各个设备的设备接口不会一样。

WDM驱动中设置接口

在WDM驱动程序中使用设备接口,首先在创建设备的时候,不能指定设备名,这样
系统会为设备自动创建一个设备名, 该设备名就是一个数字,新设备加入的时候,数字依
次递增。
另外不用IoCreateSymbolicLink创建符号链接,而是用loRegisterDeviceInterface为设备创
建设备接口。应用程序通过设备接口来寻找到设备.

//需要包含此头文件
#include <initguid.h>
//在VS中使用生成GUID  选第二种方式
DEFINE_GUID(MY_WDM_DEVICE, 0xe57c50f, 0xccc, 0x4ad2, 0xa8, 0x95, 0x93, 0xc5, 0xed, 0x11, 0x98, 0x60);

NTSTATUS IoRegisterDeviceInterface(
	IN PDEVICE OBJECT PhysicalDeviceobject,	//物理设备对象 也就是pdo
	IN CONST GUID *InterfaceClassGuid,	//设备接口的指针,这里是GUID类型的指针
	IN PUNICODE STRING ReferenceString OPTIONAL,	//一般设置为NULL
	OUT PUNICODE_STRING SymbolicLinkName	//将GUID输出一串UNICODE字符串
)

创建设备接口

#pragma PAGEDCODE
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject)
{ 
	//判断代码是否运行在分页内存中
	PAGED_CODE();
	KdPrint(("Enter HelloWDMAddDevice\n"));

	NTSTATUS status;
	PDEVICE_OBJECT fdo;
	status = IoCreateDevice(
		DriverObject,
		sizeof(DEVICE_EXTENSION),
		NULL,//没有指定设备名
		FILE_DEVICE_UNKNOWN,
		0,
		FALSE,
		&fdo);
	if( !NT_SUCCESS(status))
		return status;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
	pdx->fdo = fdo;
	//附加设备到pdo上
	pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);

	//创建设备接口
	status = IoRegisterDeviceInterface(PhysicalDeviceObject, &MY_WDM_DEVICE, NULL, &pdx->interfaceName);

	if( !NT_SUCCESS(status))
	{
		IoDeleteDevice(fdo);
		return status;
	}
	DbgPrint("SymbolLIinkName=%wZ\n", &pdx->interfaceName);
	//设置接口状态
	IoSetDeviceInterfaceState(&pdx->interfaceName, TRUE);

	if( !NT_SUCCESS(status))
	{
		if( !NT_SUCCESS(status))
		{
			return status;
		}
	}

	fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
	fdo->Flags &= ~DO_DEVICE_INITIALIZING;

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

其实pdx->interfaceName就是暴露给应用程序的符号链接,也就是符号链
接。而这种新符号链接由以下四部分组成:

(1)第一部分是何种总线的设备,如图13-3中的设备就是根总线上的设备,即ROOT。
(2)第二部分是类设备的名称,如图13-3中的设备就是ZHANGFANDEVICE.

(3)第三部分是这种设备的第几个设备,
(4)第四部分是指定的设备接口的GUID。
在后面的讲述中可以看出,应用程序就是通过这组符号链接找到设备的。

应用程序寻找接口

在应用程序中寻找设备,是通过设备接口和设备号决定的。这里的设备号是指如果PC
中安装了两个相同驱动程序的网卡,第一 个网卡就是第0号网卡,而第二个网卡就是第1
号网卡。
在应用程序中主要是通过SetupDiXX系列函数得到设备接口,SetupDiXX用法十分灵
活,具体内容可以查看MSDN的相关资料,下面列出 了寻找接口的程序。

SetupDiGetClassDevs
用来查询与指定参数匹配的所有已安装设备
在这里插入图片描述

#include "stdafx.h"
#include<windows.h>
#include <stdio.h>
#include <InitGuid.h>
#include <SetupAPI.h>
#pragma comment(lib,"SetupAPI.lib")

//使用VS的生成GUID工具,选择第二种方式生成。
DEFINE_GUID(MY_WDM_DEVICE, 0xe57c50f, 0xccc, 0x4ad2, 0xa8, 0x95, 0x93, 0xc5, 0xed, 0x11, 0x98, 0x60);

HANDLE GetDeviceViaInterface(const GUID* pGuid)
{
	//SetupDiGetClassDevs 通过GUID找到对应的设备接口
	HDEVINFO info = SetupDiGetClassDevs(pGuid, 
										NULL,	//总线类型 虚拟设备不用管这个值
										NULL, 	//父窗口
										DIGCF_PRESENT |  //设备在系统中
										DIGCF_INTERFACEDEVICE); //查找的是接口
	if(info==INVALID_HANDLE_VALUE)
	{
		printf("No HDEVINFO available for this GUID\n");
		return NULL;
	}

	// Get interface data for the requested instance
	SP_INTERFACE_DEVICE_DATA IfData;
	ifdata.cbSize = sizeof(IfData);
	//枚举设备接口  一个驱动设备可以创建多个接口 插入一个相同设备就会创建一个设备接口.
	// i 指定了多个设备中的其中一个设备序号 如果没有这个序号就会枚举失败

	for(int i=0;;i++)
	{
		if(!SetupDiEnumDeviceInterfaces(info, NULL, pGuid, i, &IfData))
		{
			if (i==0)
			{
				printf("No SP_INTERFACE_DEVICE_DATA available for this GUID instance\n");
			}
			SetupDiDestroyDeviceInfoList(info);
			return NULL;
		}
			DWORD ReqLen;
		//获取指定接口的详细信息 主要是获得ReqLen
		SetupDiGetDeviceInterfaceDetail(info, &IfData, NULL, 0, &ReqLen, NULL);
		
		//分配符号链接名长度的内存
		PSP_INTERFACE_DEVICE_DETAIL_DATA IfDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]);
		if( IfDetail==NULL)
		{
			SetupDiDestroyDeviceInfoList(info);
			return NULL;
		}
	
		// Get symbolic link name
		ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
		if( !SetupDiGetDeviceInterfaceDetail(info, &IfData, IfDetail, ReqLen, NULL, NULL))
		{
			SetupDiDestroyDeviceInfoList(info);
			delete ifDetail;
			return NULL;
		}

		printf("Symbolic link is %S\n",ifDetail->DevicePath);
		
	}
	// Open file
	/*HANDLE rv = CreateFile( ifDetail->DevicePath, 
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if( rv==INVALID_HANDLE_VALUE) rv = NULL;

	delete ifDetail;
	SetupDiDestroyDeviceInfoList(info);*/
	return 0;
}

int main()
{
	GetDeviceViaInterface(&MY_WDM_DEVICE);
	getchar();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: JTAG和SWD是用于调试和联机编程的标准接口协议,用于连接调试器和目标设备。在安装JTAG和SWD设备驱动时,需要按照以下步骤进行操作: 1. 首先,确保你已经获得了正确的设备驱动程序。驱动程序通常由设备厂商提供,可以在他们的官方网站上下载到。确保下载的驱动程序与你的设备型号和操作系统相兼容。 2. 下载驱动程序后,双击运行安装程序。在安装向导中,按照指示进行操作。通常,你需要阅读并同意最终用户许可协议,选择安装位置,以及其他额外的设置。 3. 完成安装后,重新启动计算机,以使驱动程序生效。 4. 连接JTAG或SWD调试器与目标设备。通常,JTAG调试器通过连接器与设备的JTAG端口连接,而SWD调试器则通过SWD线缆与设备的SWD端口连接。 5. 打开调试工具软件,例如Keil、IAR等。在软件中选择正确的目标设备和调试接口(JTAG或SWD),然后点击连接或启动调试。 6. 完成上述步骤后,调试工具将尝试与目标设备建立连接。如果一切正常,你将能够在软件中访问目标设备的寄存器、内存等,并进行调试和烧录操作。 总之,在安装JTAG和SWD设备驱动时,重要的是确保驱动程序与你的设备型号和操作系统相兼容,并按照安装向导指示进行操作。在完成驱动程序安装后,就可以通过调试工具与目标设备建立连接,并进行调试和联机编程操作。 ### 回答2: JTAG(Joint Test Action Group)和SWD(Serial Wire Debug)是用于嵌入式设备调试和编程的通信接口。为了在电脑上使用JTAG和SWD设备,需要进行设备驱动的安装。 首先,要确定使用的JTAG或SWD设备的型号和制造商。然后,从制造商的官方网站或其它可信赖的来源下载设备驱动程序。这些驱动程序通常是以压缩文件的形式提供,需要解压缩后才能安装。 解压缩后,在操作系统上找到设备驱动的安装程序。对于Windows系统,通常是一个.exe文件;对于Mac系统,通常是一个.pkg文件;对于Linux系统,通常是一个.sh或.run文件。 双击安装程序,根据安装向导的提示进行安装。在安装过程中,可能会出现需要勾选或选择相关选项的情况。确保选择正确的选项,以便正确安装设备驱动。 安装完成后,将JTAG或SWD设备连接到电脑上。设备驱动会自动识别设备并建立通信连接。在操作系统的设备管理器(Windows)或系统信息(Mac)中,可以查看到设备已成功连接并安装了相应的驱动。 安装完成后,可以使用调试和编程软件进行相关操作。具体的操作方式和使用方法,需要查阅设备的操作手册或官方文档。 总结一下,安装JTAG和SWD设备驱动需要下载适用于设备型号和制造商的驱动程序,并根据操作系统的要求进行安装。安装完成后,设备将成功连接到电脑并可以进行调试和编程操作。 ### 回答3: JTAG(Joint Test Action Group)和SWD(Serial Wire Debug)是用于调试和程序烧录的接口标准。在使用JTAG或SWD设备之前,需要进行设备驱动的安装。 设备驱动是一种软件程序,用于使计算机系统与特定设备进行通信。在安装JTAG或SWD设备驱动之前,首先需要确定设备驱动的来源。通常,设备制造商会提供相应的设备驱动程序,你可以从他们的官方网站上下载。 下载完设备驱动程序后,可以按照以下步骤进行安装: 1. 解压设备驱动程序的压缩包,你会看到一个文件夹。 2. 进入该文件夹,寻找一个以“.inf”为扩展名的文件。这个文件是设备驱动程序的安装文件。 3. 右键点击“.inf”文件,选择“安装”选项。这会启动驱动程序的安装向导。 4. 按照设备驱动程序的安装向导中的指示,完成驱动程序的安装过程。 安装完成后,你可以连接JTAG或SWD设备到计算机上。系统会自动识别设备并安装相应的驱动程序。在安装驱动程序之后,你可以使用相应的调试或烧录软件来连接和操作JTAG或SWD设备。 总结起来,JTAG和SWD设备驱动的安装过程包括下载设备驱动程序、解压文件、运行安装向导,并在完成后连接设备。这样,你就可以开始使用JTAG或SWD设备进行调试和程序烧录了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值