unknowndevice

更新时间:2023-01-01 18:56:56 阅读: 评论:0


2023年1月1日发(作者:英语诗歌朗诵稿)

通过设备接口打开设备详细步骤

一、驱动程序

1.驱动程序框架的创建

(1)用VC建立一个新工程。在VCIDE环境中选择File|New,弹出New对话框。在对话框中,选

择Project选项卡。在Project选项卡中,选择Win32Application。设置工程名为OpenGuid.如图1所示,

单击OK,进入下一个对话框,在对话框中选择一个空的工程。如图2。

图1

图2

(2).新建两个文件GuidOpen.h和.这两个文件的具体写法,详见程序编写。也能够直截了

当添加现成的差不多写好的文件,张帆这本书中,一样差不多上用的HelloWDM.h和.

(3).增加新的编译版本,去掉Debug和Relea版本。在Build|Configuration如图3和图4。

图3

图4

(4).修改工程属性。选择Project|Setting,在弹出的对话框中,选择General选项卡,将Intermediatefiles

和Outputfiles改为MyDriver_Check,那个名字英语C/C++中,所设置的Fo和Fd后面的文件名相一致。

如图5。

图5

将C/C++选项卡中,原有的ProjectOptions内容全部删掉,换成一下内容。

/nologo/Gz/MLd/W3/WX/Z7/Od/DWIN32=100/D_X86_=1/DWINVER=0x500/DDBG=1

/Fo"MyDriver_Check/"/Fd"MyDriver_Check/"/FD/c

其中:

/nologo:表示不显示编译的版本信息

/Gz:默认函数调用采纳标准调用(_stdcall)

/MLd

/W3:采纳第三级警告模式

/WX:将警告信息转换为错误信息,最大程度保证代码可靠

/Z7:用Z7模式产生调试信息?

/Od:关闭调试模式,VC的调试命令不能调试内核下的程序

/DWIN32=100/D_X86_=1/DWINVER=0x500/DDBG=1:定义4个宏(不明白什么缘故)

/Fo"MyDriver_Check/:MyDriver_Check/为OutputDirectories中“创建”的文件夹,存放中间生成的目标代码

路径

/Fd"MyDriver_Check/":MyDriver_Check/为存放.PDB文件的文件夹

/FD:生成文件依奈

/c:只进行编译,不连接

图6

选择Link选项卡,将原有的ProjectOptions内容全部删除,替换成如下内容:

/nologo/ba:"0x10000"/stack:0x400000,0x1000/entry:"DriverEntry"/subsystem:console

/incremental:no/pdb:"MyDriver_Check/"/debug/machine:I386/nodefaultlib

/out:"MyDriver_Check/"/pdbtype:pt/subsystem:native/driver/SECTION:INIT,D/IGNORE:4078

其中:

:链接WDM库

/nologo:链接时不显示版本信息

/ba:"0x10000":加载驱动时,设定加载到虚拟内存的地址

/stack:0x400000,0x1000:设定函数使用堆栈的地址与大小

/entry:"DriverEntry":入口函数的地址(为符合标准函数调用的)

/subsystem:console:设置子系统

/incremental:no:非递曾式链接

/pdb:"MyDriver_Check/":设置pdb文件的文件名为GuidOpen,储存于MyDriver_Check文件

夹下面C/C++属性页中的设置一样。

/debug:以Debug方式链接

/machine:I386:产生代码为386兼容的平台下的

/nodefaultlib:不使用默认的库

/out:"MyDriver_Check/":输出2进制的代码的文件名,储存于MyDriver_Check文件夹下与

C/C++属性页中的设置一样。

/pdbtype:pt:设置pdb文件的类型

/subsystem:native:子系统为内核系统

/driver:编译驱动

/SECTION:INIT,D:将INIT的段设置为可抛弃的

/IGNORE:4078:忽略4078号警告错误

图7

(5).修改VC的lib名目和include名目。

Tools->Options->Directories属性页下的

Showdirectoriesfor

切换到Includefie

添加DDK的头文件(安装的ddk的名目文件夹)\Inc\w2k

(ddk的名目文件夹)\Inc\ddkwdmw2k

置于最上面

添加库文件(安装的ddk的名目文件夹)libw2ki386

置于最上面

2.驱动程序说明

(1)重要驱动程序中重要的数据结构

驱动对象(DRIVER_OBJECT)在驱动加载时被内核中的对象治理程序所创建,由内核中的I/O治理器负

责加载。

typedefstruct_DRIVER_OBJECT{

CSHORTType;

CSHORTSize;

PDEVICE_OBJECTDeviceObject;

ULONGFlags;

PVOIDDriverStart;

ULONGDriverSize;

PVOIDDriverSection;

PDRIVER_EXTENSIONDriverExtension;

UNICODE_STRINGDriverName;

PUNICODE_STRINGHardwareDataba;

PFAST_IO_DISPATCHFastIoDispatch;

PDRIVER_INITIALIZEDriverInit;

PDRIVER_STARTIODriverStartIo;

PDRIVER_UNLOADDriverUnload;

PDRIVER_DISPATCHMajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1];

}DRIVER_OBJECT;

typedefstruct_DRIVER_OBJECT*PDRIVER_OBJECT;

DeviceObject:每个驱动程序会有一个或多个设备对象。设备对象是由程序员自己创建的,而非操作系统完

成,在驱动被卸载时,遍历每个设备对象,并将其删除。

设备对象(DEVICE_OBJECT)

typedefstruct_DEVICE_OBJECT{

struct_DRIVER_OBJECT*DriverObject;

struct_DEVICE_OBJECT*NextDevice;

struct_DEVICE_OBJECT*AttachedDevice;

struct_IRP*CurrentIrp;

ULONGFlags;

struct_DEVOBJ_EXTENSION*DeviceObjectExtension;

......................

}DEVICE_OBJECT;

typedefstruct_DEVICE_OBJECT*PDEVICE_OBJECT;//ntndis

设备扩展是由程序员制定内容和大小,由I/O治理器创建的,同时储存在非分页内存中。

(2)WDM驱动程序差不多结构,在WDM驱动程序中,完成一个设备操作,至少需要两个设备对象共同

完成,一个是物理设备对象(PhysicalDeviceObject)PDO和功能设备对象(FunctionDeviceObject)FDO。

当PC插入一个设备时,PDO会自动创建。确切的说是由总线驱动创建的,PDO不能单独操作设备,需要

配合FDO一起使用。系统会检测到新设备,要求安装驱动程序,需要安装的驱动程序指的确实是WDM

程序,此驱动程序负责创建FDO,同时附加到PDO上。

(3)驱动程序分析

头文件中,除了生命函数之外,还要定义一个设备扩展。

typedefstruct_DEVICE_EXTENSION

{

PDEVICE_OBJECTfdo;

PDEVICE_OBJECTNextStackDevice;

UNICODE_STRINGinterfaceName;//设备接口

}DEVICE_EXTENSION,*PDEVICE_EXTENSION;

当驱动程序被加载时,第一进入DriverEntry函数。DriverEntry要紧是对驱动程序进行初始化,它

是由系统进程所调用的,在Windows中有个专门的进程叫做系统进程,打开进程治理器,里面有一个名为

System的进程确实是系统进程。系统进程在系统启动的时候就被创建了。驱动加载时,系统进程启动新的

线程,调用执行体组建中的对象治理器,创建一个驱动对象。那个驱动对象是一个DRIVER_OBJECT的结

构体。另外,系统进程调用执行体组建中的配置治理器程序,查询词驱动程序对应的注册表项。

DriverEntry函数由两个参数PDRIVER_OBJECTpDeriverObject是刚才被创建的驱动对象的指针,和

PUNICODE_STRINGpRegistryPath,设备服务键的的键名字符串的指针。在那个函数中,要紧是对系统进程

创建的驱动对象进行初始化。

DriverEntry函数中,它对驱动对象的初始化一样是对例程的设置,卸载例程,AddDevice和IRP

派遣函数。具体代码如下:

pDriverObject->DriverExtension->AddDevice=GuidOpenAddDevice;

pDriverObject->MajorFunction[IRP_MJ_PNP]=GuidOpenPnp;

pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=

pDriverObject->MajorFunction[IRP_MJ_CREATE]=

pDriverObject->MajorFunction[IRP_MJ_CLOSE]=

pDriverObject->MajorFunction[IRP_MJ_READ]=

pDriverObject->MajorFunction[IRP_MJ_WRITE]=GuidOpenDispatchRoutine;

pDriverObject->DriverUnload=GuidOpenUnload;

另外,设备服务键的键名有时候需要储存下来,因为那个字符串不是长期存在的,假如以后想使用

那个UNICODE字符串,就必须先把它复制到安全的地点,那个字符串的内容一样是

REGISTRYMACHINESYSTEMControlSetService[服务名].DriverEntry的返回值是NTSTATUS,是被定

义的为32位的无符号长整形。0~0X7FFFFFFF被认为是正确的。而0X80000000~0XFFFFFFFF被认为是错

误的。

接着驱动程序进入GuidOpenAddDevice例程。它的要紧任务是创建设备对象(功能设备对象)并

将其附加到PDO之上。它有两个参数PDRIVER_OBJECTDriverObject,驱动对象和PDEVICE_OBJECT

PhysicalDeviceObject设备对象,确实是底层总线驱动创建的PDO对象。

创建设备对象,用IoCreatDevice(

INPDRIVER_OBJECTDriverObject,//系统创建的驱动对象

INULONGDeviceExtensionSize,//程序员自己定义的(在头文件中)设备扩展的大小

INPUNICODE_STRINGDeviceNameOPTIONAL,//设备名,能够为空,现在,I/O治理器会自动以一

个数字作为该设备对象的名称

INDEVICE_TYPEDeviceType,//设备类型

INULONGDeviceCharacteristics,//对设备的进一步描述

INBOOLEANExclusize,//是否一次只能进行一次IRP处理

OUTPDEVICE_OBJECT*DeviceObject)//新创建的设备对象

具体代码如下

PDEVICE_OBJECTfdo;

status=IoCreateDevice(

DriverObject,

sizeof(DEVICE_EXTENSION),

NULL,//没有指定设备名

FILE_DEVICE_UNKNOWN,

0,

FALSE,

&fdo);

现在,功能设备对象,创建完毕,接着是将,功能设备对象FDO附加到物理设备对象上PDO。利用函数

PDEVICE_OBJECTIoAttachDeviceToDeviceStack(

INPDEVICE_OBJECTSourceDevice,//新创建的功能设备对象FDO

INPDEVICE_OBJECTTargetDevice//物理设备对象PDO

);

该函数调用成功的话返回一个设备对象,附加设备对象的设备对象,例如在那个地点,返回的是PDO,假

如,ThereturneddeviceobjectpointercandifferfromTargetDeviceifTargetDevicehadadditionaldrivers

layeredontopofit.假如该函数运行失败,则返回NULL。

具体程序,我们将该函数返回的设备对象,储存在,设备扩展中,如此一来,我们就需要先得到新创建的

功能设备对象的设备扩展。

//得到设备扩展

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

pdx->fdo=fdo;

//将FDO附加到PDO上

pdx->NextStackDevice=IoAttachDeviceToDeviceStack(fdo,PhysicalDeviceObject);

WDM驱动程序,设备名无法被用户模式下的应用程序查询到,应用程序能够通过符号链接,设备名或者

是设备接口来访问设备。本文只介绍设备接口方式。设备接口确实是一组全局标志,他是一个128位组成

的数字,并能保证在全世界范畴内可不能冲突。VC中有一个创建GUID的工具,叫,它在

D:ProgramFilesMicrosoftVisualStudioCommonTools中,运行它,它为用户提供了四种方式产生guid,

事实上它们差不多上128位的,只是输出的形式不同而已,一样选择第二种,单击NewGUID会产生新的

的guid,单击Copy将那个guid复制到新建的guid.h头文件中。

DEFINE_GUID(<>,

0x5dada759,0xde9a,0x45e2,0x8f,0xb4,0x1a,0xa8,0x8b,0x1d,0xe7,0x8);

需要将《name》换成自己为那个接口而起的名字,例如MY_WDM_DEVICE.另外需要注意,在创建guid

时,程序中应该包含头文件#include,其中initguid.h只能在一个.cpp中包含,DEFINE_GUID

()宏定义了,假如包含了一个initguid.h,那么定义一个guid,假如没有包含一个initguid.h,则定义一个

externguid指向定义的那个guid,因此项目中必须有一个文件.cpp包含initguid.h,否则会出错。但假如包含

了多个的initguid.h,也会出错否则会显现错误。

unresolvedexternalsymbol_MY_WDM_DEVICE

创建设备接口用函数NTSTATUS

IoRegisterDeviceInterface(

INPDEVICE_OBJECTPhysicalDeviceObject,

INCONSTGUID*InterfaceClassGuid,

INPUNICODE_STRINGReferenceStringOPTIONAL,

OUTPUNICODE_STRINGSymbolicLinkName//将GUID输出一串UNICODE字符串

);

具体代码创建设备接口

status=IoRegisterDeviceInterface(PhysicalDeviceObject,&MY_WDM_DEVICE,NULL,

&pdx->interfaceName);其中pdx->interfaceName确实是暴露给应用程序的符号链接。包括四部分如图8

图8

(1)何种总线设备,例如ROOT

(2)类设备的名称,LIUYOUJINDEVICE

(3)这种设备的第几个设备#0000

(4)制定的设备接口GUID。

设置接口

IoSetDeviceInterfaceState(&pdx->interfaceName,TRUE);

//设置操作模式

fdo->Flags|=DO_BUFFERED_IO|DO_POWER_PAGABLE;

fdo->Flags&=~DO_DEVICE_INITIALIZING;

实现即插即用

即插即用IRP即IRP_MJ_PNP,它一样是由即插即用治理器发送给WDM驱动程序的。不同情形下,

即插即用治理器会发送不同子类型的IRP_MJ_PNPIRP。在IRP_MJ_PNP派遣函数中要处理不同子功

能代码的IRP,本程序采纳函数指针的方法。第一初始化一个函数指针组成的数组,然后在派遣函数中判

定是那种子功能代码。依照那个子功能代码区查找行的函数指针,再通过指针找到针对具体子功能代码所

作的操作函数。加载驱动时,所用到的各个IRP_MJ_PNP子功能代码。

1.953DefaultEnterDefaultPnpHandler

11.953DefaultLeaveDefaultPnpHandler

11.953DefaultEnterGuidOpenPnp

11.953DefaultPNPRequest(IRP_MN_FILTER_RESOURCE_REQUIREMENTS)修改I/O资源需求

列表

11.953DefaultEnterDefaultPnpHandler

11.953DefaultLeaveDefaultPnpHandler

11.953DefaultLeaveGuidOpenPnp

11.953DefaultEnterGuidOpenPnp

11.953DefaultPNPRequest(IRP_MN_START_DEVICE)配置并初始化设备

11.953DefaultEnterHandleStartDevice

11.953DefaultEnterDefaultPnpHandler

11.953DefaultLeaveDefaultPnpHandler

11.953DefaultLeaveHandleStartDevice

11.953DefaultLeaveGuidOpenPnp

11.953DefaultEnterGuidOpenPnp

11.953DefaultPNPRequest(IRP_MN_QUERY_CAPABILITIES)取设备能力

11.953DefaultEnterDefaultPnpHandler

11.953DefaultLeaveDefaultPnpHandler

11.953DefaultLeaveGuidOpenPnp

11.953DefaultEnterGuidOpenPnp

11.953DefaultPNPRequest(IRP_MN_QUERY_PNP_DEVICE_STATE)取设备状态

11.953DefaultEnterDefaultPnpHandler

11.953DefaultLeaveDefaultPnpHandler

11.953DefaultLeaveGuidOpenPnp

11.953DefaultEnterGuidOpenPnp

11.953DefaultPNPRequest(IRP_MN_QUERY_DEVICE_RELATIONS)给出与制定特点相关的设

备列表

11.953DefaultEnterDefaultPnpHandler

11.953DefaultLeaveDefaultPnpHandler

11.953DefaultLeaveGuidOpenPnp

对IRP_MN_DEVICE的处理

3.应用程序说明

创建一个对话框类型的驱动程序框架。

(1)第一需要将驱动程序中的guid.h文件copy到应用程序中,同时添加到应用程序的工程里。

(2)应用程序的Porject|Setting|Link的Object/librarymodules里要添加库,否则会有类似如此

的错误:GuidOpen_:unresolvedexternalsymbol__imp__SetupDiGetDeviceInterfaceDetailA@24

GuidOpen_:errorLNK2001:unresolvedexternalsymbol__imp__SetupDiDestroyDeviceInfoList@4

GuidOpen_:errorLNK2001:unresolvedexternalsymbol

__imp__SetupDiEnumDeviceInterfaces@20

GuidOpen_:errorLNK2001:unresolvedexternalsymbol__imp__SetupDiGetClassDevsA@16

程序中应该包含tupapi.h头文件,否则,会显现如此的错误:

errorC2065:'HDEVINFO':undeclaredidentifier

errorC2146:syntaxerror:missing';'beforeidentifier'info'

errorC2065:'info':undeclaredidentifier

errorC2065:'SetupDiGetClassDevs':undeclaredidentifier

errorC2065:'DIGCF_PRESENT':undeclaredidentifier

errorC2065:'DIGCF_INTERFACEDEVICE':undeclaredidentifier

...............................................................................................................................

同时还必须包含的一个头文件是#include

打开设备的代码如下:

voidCGuidOpen_AppDlg::OnOPENDEVICE()

{

//TODO:Addyourcontrolnotificationhandlercodehere

HANDLEhDevice=GetDeviceViaInterface((LPGUID)&MY_WDM_DEVICE,0);

if(hDevice==INVALID_HANDLE_VALUE)

{

MessageBox("打开设备出错!");

//return1;

}

MessageBox("设备打开成功");

CloHandle(hDevice);

//return0;

}

HANDLECGuidOpen_AppDlg::GetDeviceViaInterface(GUID*pGuid,DWORDinstance)

{

//获得类信息

HDEVINFOinfo=SetupDiGetClassDevs(pGuid,NULL,NULL,DIGCF_PRESENT|

DIGCF_INTERFACEDEVICE);

if(info==INVALID_HANDLE_VALUE)

{

MessageBox("NoHDEVINFOavailableforthisGUID");

returnNULL;

}

//Getinterfacedatafortherequestedinstance

SP_INTERFACE_DEVICE_DATAifdata;

=sizeof(ifdata);

if(!SetupDiEnumDeviceInterfaces(info,NULL,pGuid,instance,&ifdata))

{

MessageBox("NoSP_INTERFACE_DEVICE_DATAavailableforthisGUIDinstance");

SetupDiDestroyDeviceInfoList(info);

returnNULL;

}

//Getsizeofsymboliclinkname

DWORDReqLen;

SetupDiGetDeviceInterfaceDetail(info,&ifdata,NULL,0,&ReqLen,NULL);

PSP_INTERFACE_DEVICE_DETAIL_DATAifDetail=

(PSP_INTERFACE_DEVICE_DETAIL_DATA)(newchar[ReqLen]);

if(ifDetail==NULL)

{

SetupDiDestroyDeviceInfoList(info);

returnNULL;

}

//Getsymboliclinkname

ifDetail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

if(!SetupDiGetDeviceInterfaceDetail(info,&ifdata,ifDetail,ReqLen,NULL,NULL))

{

SetupDiDestroyDeviceInfoList(info);

deleteifDetail;

returnNULL;

}

//printf("Symboliclinkis%sn",ifDetail->DevicePath);

//Openfile

HANDLErv=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;

deleteifDetail;

SetupDiDestroyDeviceInfoList(info);

returnrv;

}

函数解析:

WINSETUPAPIBOOLWINAPI

SetupDiGetDeviceInterfaceDetail(

INHDEVINFODeviceInfoSet,

INPSP_DEVICE_INTERFACE_DATADeviceInterfaceData,

OUTPSP_DEVICE_INTERFACE_DETAIL_DATADeviceInterfaceDetailData..OPTIONAL,

INDWORDDeviceInterfaceDetailDataSize,

OUTPDWORDRequiredSize..OPTIONAL,

OUTPSP_DEVINFO_DATADeviceInfoDataOPTIONAL

);

参数

DeviceInfoSet

指向设备信息集的指针,它包含了所要接收信息的接口。该句柄通常由SetupDiGetClassDevs函数返回。

DeviceInterfaceData

一个指向SP_DEVICE_INTERFACE_DATA结构的指针,该结构指定了DeviceInfoSet参数中设备的接

口。那个类型的指针通常由SetupDiEnumDeviceInterfaces函数返回。

DeviceInterfaceDetailData

一个指向SP_DEVICE_INTERFACE_DETAIL_DATA结构的指针,该结构用于接收指定接口的信息。该参

数是可选的且能够为NULL。假如DeviceInterfaceDetailSize参数为0,该参数必须为NULL。假如该参数

被指定,主调者必须在调用该函数之前,设置SP_DEVICE_INTERFACE_DETAIL_DATA结构的cbSize

成员为sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)。cbSize成员总是包含数据结构的固定部分的长

度。

DeviceInterfaceDetailDataSize

DeviceInterfaceDetailData参数指定的缓冲的大小。该缓冲的大小不能小于

(offtof(SP_DEVICE_INTERFACE_DETAIL_DATA,DevicePath)+sizeof(TCHAR))字节。

假如DeviceInterfaceDetailData参数为NULL,该参数必须为0.

RequiredSize

一个指向变量的指针,该变量接收要求的DeviceInterfaceDetailData缓冲的大小。那个大小包含了结构的

固定部分的大小再加上设备路径字符串的长度。该参数是可选的,也能够是NULL。

DeviceInfoData

一个指向缓冲的指针,该缓冲接收关于支持要求的接口的设备的信息。主调者必须设置

成员为sizeof(SP_DEVINFO_DATA)。该参数是可选的,也能够为NULL。

返回值

假如函数顺利完成,则返回TRUE,假如有错误,则返回FALSE。

SetupDiGetDeviceInterfaceDetail函数用来传回另外一个与前一个函数所识别的接口有关的结构

InterfaceClassGuid。包括设备的路径InterfaceClassGuid->DevicePath成员是一个设备路径。它能够作为应

用程序打开设备时CreateFile的第一个参数。值得注意的是:第一次调用该函数时,其中的

DeviceInterfaceDetailDataSize无法预知。故能够两次调用。第一次猎取长度,第二次猎取正确值。

WINSETUPAPIBOOLWINAPI

SetupDiEnumDeviceInterfaces(

INHDEVINFODeviceInfoSet,//指向设备信息集的指针,它包含了所要接收信息的接口。该句柄通常

由SetupDiGetClassDevs函数返回。

INPSP_DEVINFO_DATADeviceInfoData,OPTIONAL

INLPGUIDInterfaceClassGuid,//指向GUID的指针

INDWORDMemberIndex,

OUTPSP_DEVICE_INTERFACE_DATADeviceInterfaceData//Thecallermustt

tosizeof(SP_DEVICE_INTERFACE_DATA)beforecallingthisfunction.);

SetupDiEnumDeviceInterfaces函数用来读取识别一个接口的结构指针,每一次调用必须传第一个数组的索

引来指定一个接口

HDEVINFO

SetupDiGetClassDevs(

INLPGUIDClassGuid,OPTIONAL

INPCTSTREnumerator,OPTIONAL

INHWNDhwndParent,OPTIONAL

INDWORDFlags

);

输入参数:

PGUIDClassGuid

在创建设备列表的时候提供一个指向GUID的指针。假如设定了标志DIGCF_ALLCLASSES,则那个参数

能够忽略,且列表结果中包括所有差不多安装的设备类别。

PCTSTREnumerator

提供包含设备实例的枚举注册表分支下的键名,能够通过它猎取设备信息。假如那个参数没有指定,则要

从整个枚举树中猎取所有设备实例的设备信息。

HWNDhwndParent

提供顶级窗口的句柄,所有用户接口能够使用它来与成员联系。

DWORDFlags

提供在设备信息结构中使用的操纵选项。能够是以下数值:

DIGCF_PRESENT-只返回当前存在的设备。

DIGCF_ALLCLASSES-返回所有已安装的设备。假如那个标志设置了,ClassGuid参数将被忽略。

DIGCF_PROFILE-只返回当前硬件配置文件中的设备。

编辑本段返回值

HDEVINFO

假如函数运行成功,返回设备信息结构的句柄,该结构包含与指定参数匹配的所有已安装设备。假如失败,

则返回INVALID_HANDLE_VALUE。调用GetLastError能够获得更多错误信息。

编辑本段说明

使用此函数,需要包含头文件tupapi.h。

此外,在projecttting中的link页面需要添加。

在tuapi.h中有如下定义:

typedefPVOIDHDEVINFO;

即HDEVINFO是个无类型指针

也确实是那个函数能返回一个包含某个设备集合信息的一个指针。那个地点的handle暂且这么明白得。

用SetupDiGetClassDevs得到的那个handle,最后记得要调用SetupDiDestroyDeviceInfoList来删除。

Thecallerofthisfunctionmustdeletethereturneddeviceinformationtwhenitisnolongerneededbycalling

SetupDiDestroyDeviceInfoList

本文发布于:2023-01-01 18:56:56,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/73723.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:nec笔记本电脑
下一篇:农远资源网
标签:unknowndevice
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图