DDK

想要实现类似设备管理器的功能,其实也不是很难,无非就是调用一些API函数,就像本文描述的,采用的API函数就是SetupDi系列的函数。不过这类函数有很多,具体的请参见MSDN,而实现设备启用、停用仅需要用到的就只有5个函数:
       SetupDiGetClassDevs                   // 获取设备信息集
       SetupDiEnumDeviceInfo                 // 从设备信息集中枚举每个设备的具体信息
       SetupDiGetDeviceRegistryProperty      // 从注册表中读取PnP设备的属性
       SetupDiSetClassInstallParams          // 设置(包括取消)设备类的安装参数
       SetupDiCallClassInstaller             // 安装指定设备
以上函数均在setupapi.h头文件中声明,该头文件包含在setupapi.lib函数库中(使用以上函数前需要声明这个头文件)。

接下来就是如何实现设备的启用与停用。
从原理上讲,设备的启用与停用其实就是对该设备进行重安装。

首先,我们需要声明两个变量用来保存指定设备类的属性信息:
    HDEVINFO        m_hDevInfo;              // 类似设备句柄,以下暂且称为设备句柄
    SP_DEVINFO_DATA m_DeviceInfoData;        // 设备详细属性信息

然后调用SetupDiGetClassDevs函数获取设备句柄的值。(在这个函数中,需要指定设备类的GUID,如果不清楚这个GUID,可以在相应的安装文件.inf中查找。注意:设备类的GUID,不是设备的GUID!)

接着循环使用SetupDiEnumDeviceInfo函数枚举对应设备类中的设备,并使用SetupDiGetDeviceRegistryProperty函数获取得到的设备的详细信息,进行判断是否为所需的设备(判断的方式有多种,具体参考MSDN,本文采用设备描述进行判断)。
一旦枚举结束(即枚举不成功,而且用GetLastError()可以得到错误码259)即可退出循环。当然如果找到设备,即可break退出。

如果找到对应的设备,就调用SetupDiSetClassInstallParams函数设置安装的属性。这里有个注意的地方需要详细说明一下:
SetupDiSetClassInstallParams的函数原型如下:
WINSETUPAPI BOOL WINAPI
  SetupDiSetClassInstallParams(
    IN HDEVINFO  DeviceInfoSet,
    IN PSP_DEVINFO_DATA  DeviceInfoData,  OPTIONAL
    IN PSP_CLASSINSTALL_HEADER  ClassInstallParams,  OPTIONAL
    IN DWORD  ClassInstallParamsSize
    );
注意第三个参数PSP_CLASSINSTALL_HEADER  ClassInstallParams,
这里我们不采用这个结构,而是采用另外一个结构:SP_PROPCHANGE_PARAMS
并在这个结构中,
设置ClassInstallHeader字段中(我们发现这个字段也是一个结构,就是PSP_CLASSINSTALL_HEADER结构)的InstallFunction字段值为DIF_PROPERTYCHANGE,
设置StateChange值为DICS_ENABLE(该值为启用,若是停用则为DICS_DISABLE)
然后采用强行转换将其转为PSP_CLASSINSTALL_HEADER结构。

最后,调用SetupDiCallClassInstaller函数执行设备的安装(即:启用或者停用),注意该函数第一个参数值应为DIF_PROPERTYCHANGE。
从设备管理器中,可以验证我们的做法。

ON_WM_DEVICECHANGE() 消息可以检测到设备插拔

BOOL CDirverDemoDlg::OnDeviceChange( UINT nEventType, DWORD dwData )
{
 m_mobileDevice.Analysis();
 if(nEventType == DBT_DEVICEARRIVAL)         //插入事件
  //AfxMessageBox(_T("插入设置")) ;
 if(nEventType == DBT_DEVICEREMOVECOMPLETE)    //弹出事件
  //AfxMessageBox(_T("弹出设置")) ;
 return TRUE;

}

Windows设备的具体属性

#define SPDRP_DEVICEDESC                  (0x00000000) 

// DeviceDesc (R/W)

//设备描述,如:Realtek RTL8139 Family PCI Fast Ethernet NIC,Intel(R) PRO/100 VE Network Connection
#define SPDRP_HARDWAREID                  (0x00000001) 

// HardwareID (R/W)

//硬件ID(如:PCI/VEN_10EC&DEV_8139&SUBSYS_813910EC&REV_10,PCI/VEN_10EC&DEV_8139&SUBSYS_813910EC&REV_10, PCI/VEN_8086&DEV_1039&SUBSYS_026A1014&REV_81)
#define SPDRP_COMPATIBLEIDS               (0x00000002) 

// CompatibleIDs (R/W)

(如:PCI/VEN_10EC&DEV_8139&REV_10,PCI、VEN_8086&DEV_1039&REV_81)
#define SPDRP_NTDEVICEPATHS               (0x00000003) 

// Unsupported, DO NOT USE
#define SPDRP_SERVICE                     (0x00000004) 

// Service (R/W)

(如:rtl8139、E100B)
#define SPDRP_CONFIGURATION               (0x00000005) 

// Configuration (R)

(如:其它)
#define SPDRP_CONFIGURATIONVECTOR         (0x00000006) 

// ConfigurationVector (R)

(如:其它)
#define SPDRP_CLASS                       (0x00000007) 

// Class (R--tied to ClassGUID)

(如:Net)
#define SPDRP_CLASSGUID                   (0x00000008) 

// ClassGUID (R/W)

//设备的类别标识(如:网卡{4D36E972-E325-11CE-BFC1-08002BE10318})
#define SPDRP_DRIVER                      (0x00000009) 

// Driver (R/W)

//(如:{4D36E972-E325-11CE-BFC1-08002BE10318}/0016)
#define SPDRP_CONFIGFLAGS                 (0x0000000A) 

// ConfigFlags (R/W)

(如:其它)
#define SPDRP_MFG                         (0x0000000B) 

// Mfg (R/W)

//供应商的名称
#define SPDRP_FRIENDLYNAME                (0x0000000C) 

// FriendlyName (R/W)

//直观的名字
#define SPDRP_LOCATION_INFORMATION        (0x0000000D) 

// LocationInformation (R/W)

//本地环境属性(如:PCI 总线 2、设备 10、功能 0)
#define SPDRP_PHYSICAL_DEVICE_OBJECT_NAME (0x0000000E) 

// PhysicalDeviceObjectName (R)

//(如:/Device/NTPNP_PCI0012)
#define SPDRP_CAPABILITIES                (0x0000000F) 

// Capabilities (R)

(如:其它)
#define SPDRP_UI_NUMBER                   (0x00000010) 

// UiNumber (R)

(如:其它)
#define SPDRP_UPPERFILTERS                (0x00000011) 

// UpperFilters (R/W)

(如:其它)
#define SPDRP_LOWERFILTERS                (0x00000012) 

// LowerFilters (R/W)

(如:其它)
#define SPDRP_MAXIMUM_PROPERTY            (0x00000013) 

// Upper bound on ordinals

(如:其它)

  GUID_DEVCLASS_FDC 软盘控制器

  GUID_DEVCLASS_DISPLAY 显示卡

  GUID_DEVCLASS_CDROM 光驱

  GUID_DEVCLASS_KEYBOARD 键盘

  GUID_DEVCLASS_COMPUTER 计算机

  GUID_DEVCLASS_SYSTEM 系统

  GUID_DEVCLASS_DISKDRIVE 磁盘驱动器

  GUID_DEVCLASS_MEDIA 声音、视频和游戏控制器

  GUID_DEVCLASS_MODEMMODEM

  GUID_DEVCLASS_MOUSE 鼠标和其他指针设备

  GUID_DEVCLASS_NET 网络设备器

  GUID_DEVCLASS_USB 通用串行总线控制器

    GUID_DEVCLASS_FLOPPYDISK 软盘驱动器

  GUID_DEVCLASS_UNKNOWN 未知设备

  GUID_DEVCLASS_SCSIADAPTER  SCSI 和 RAID 控制器

  GUID_DEVCLASS_HDCIDE  ATA/ATAPI 控制器

  GUID_DEVCLASS_PORTS端口 (COM 和 LPT)

  GUID_DEVCLASS_MONITOR 监视器


原文地址:https://www.cnblogs.com/hgy413/p/3693636.html