ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

基于Visual C++之Windows核心编程代码分析(1)实现设备管理器枚举设备

2019-03-08 10:41:34  阅读:255  来源: 互联网

标签:GetLastError 管理器 lpDeviceInterfaceDetailData Windows ClassGuid C++ DeviceInfoDat


分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

我们进行Windows编程的时候,有些时候需要枚举设备,例如光盘,光驱,硬盘等等,

我们如何实现功能呢,请见代码分析

 

 

#include <windows.h>
#include <setupapi.h>
#include <stdio.h>
#include <devguid.h>
#include <regstr.h>
/* 函数声明 */
BOOL EnumPresentDevice( const GUID * InterfaceClassGuid );
BOOL EnumAllDevice();
/*************************************
* BOOL EnumClassDevice( const GUID * InterfaceClassGuid )
* 功能	根据类型列举当前存在的设备
* 参数	InterfaceClassGuid,所需列举设备接口类的GUID
**************************************/
BOOL EnumClassDevice( const GUID * InterfaceClassGuid )

{
	HDEVINFO DeviceInfoSet;
	HDEVINFO NewDeviceInfoSet;

	SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
	PSP_DEVICE_INTERFACE_DETAIL_DATA lpDeviceInterfaceDetailData;

	DWORD dwBufferSize = 0;
	DWORD i;
	// 创建空设备信息列表
	DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);

	if(DeviceInfoSet == INVALID_HANDLE_VALUE) 
	{
		printf("CreateDeviceInfoList failed: %d\n", GetLastError());
		return 0;
	}

	// 根据接口类型获得新的设备信息列表

	NewDeviceInfoSet = SetupDiGetClassDevsEx(
		InterfaceClassGuid,
		NULL,
		NULL,
		DIGCF_PRESENT | DIGCF_DEVICEINTERFACE,
		DeviceInfoSet,// 之前创建的设备信息列表
		NULL,
		NULL
		);
	if(NewDeviceInfoSet == INVALID_HANDLE_VALUE)
	{
		printf( "SetupDiGetClassDevsEx failed: %d\n", GetLastError() );
		return 0;
	}
	// 设置 SP_DEVICE_INTERFACE_DATA 大小
	DeviceInterfaceData.cbSize 
		= sizeof(SP_DEVICE_INTERFACE_DATA);

	for (i=0; ;i++)
	{
		// 列举接口信息
		BOOL bResult = SetupDiEnumDeviceInterfaces(
			NewDeviceInfoSet,
			NULL,
			InterfaceClassGuid,
			i,
			&DeviceInterfaceData
			);
		if(!bResult)
		{
			if ( GetLastError()!=NO_ERROR &&
				GetLastError()!=ERROR_NO_MORE_ITEMS )
			{
				printf("ERROR: (%d)",GetLastError());
				return FALSE;
			}
			break;
		}
		else
		{
			// 为PSP_DEVICE_INTERFACE_DETAIL_DATA结构分配内存,填充
			lpDeviceInterfaceDetailData = HeapAlloc(
				GetProcessHeap(), 0,
				sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA));
			lpDeviceInterfaceDetailData->cbSize 
				= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
			dwBufferSize = lpDeviceInterfaceDetailData->cbSize;
			// 获得接口详细信息
			while(!SetupDiGetDeviceInterfaceDetail(
				NewDeviceInfoSet,
				&DeviceInterfaceData,
				lpDeviceInterfaceDetailData,
				dwBufferSize,
				&dwBufferSize,
				NULL))
			{
				// 如果内存空间不足,再次分配,直到可以成功调用
				if(ERROR_INSUFFICIENT_BUFFER==GetLastError())
				{
					lpDeviceInterfaceDetailData = HeapReAlloc(
						GetProcessHeap(), 0, 
						lpDeviceInterfaceDetailData, dwBufferSize);
					lpDeviceInterfaceDetailData->cbSize 
						= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
				}               
			}
			// 显示信息
			printf("DevicePath: %s\n",lpDeviceInterfaceDetailData->DevicePath);
			// lpDeviceInterfaceDetailData->DevicePath可作为CreateFile的参数,进行IO控制
			
			// 释放内存
			HeapFree(GetProcessHeap(),0,lpDeviceInterfaceDetailData);
		}
	}
	SetupDiDestroyDeviceInfoList(DeviceInfoSet);
	return TRUE;
}
/*************************************
* BOOL EnumAllDevice( )
* 功能	列举当前存在的设备
* 返回值	是否成功
**************************************/
BOOL EnumAllDevice()
{
	HDEVINFO hDevInfo;
	SP_DEVINFO_DATA DeviceInfoData;
	DWORD i;

	printf("Displaying the Installed Devices\n\n");

	// 得到所有设备 HDEVINFO 
	hDevInfo = SetupDiGetClassDevs(NULL,
		0, // 无类型
		0, // 无回调函数
		DIGCF_PRESENT | DIGCF_ALLCLASSES );
	if (hDevInfo == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	// 循环列举
	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
		&DeviceInfoData);i++)
	{
		DWORD DataT;
		LPTSTR buffer = NULL;
		DWORD buffersize = 0;

		// 获取详细信息
		while (!SetupDiGetDeviceRegistryProperty(
			hDevInfo,
			&DeviceInfoData,
			SPDRP_DEVICEDESC,
			&DataT,
			(PBYTE)buffer,
			buffersize,
			&buffersize))
		{
			if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
			{
				// 内存不足
				if (buffer) HeapFree(GetProcessHeap(), 0, buffer);
				buffer = (LPTSTR)HeapAlloc(GetProcessHeap(), 0,  buffersize);
			}
			else
				break;
		}
// 输出
		printf("GUID:{%.8X-%.4X-%.4X--%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X} "
			"Device: %s\n",
			DeviceInfoData.ClassGuid.Data1,
			DeviceInfoData.ClassGuid.Data2,
			DeviceInfoData.ClassGuid.Data3,
			DeviceInfoData.ClassGuid.Data4[0],
			DeviceInfoData.ClassGuid.Data4[1],
			DeviceInfoData.ClassGuid.Data4[2],
			DeviceInfoData.ClassGuid.Data4[3],
			DeviceInfoData.ClassGuid.Data4[4],
			DeviceInfoData.ClassGuid.Data4[5],
			DeviceInfoData.ClassGuid.Data4[6],
			DeviceInfoData.ClassGuid.Data4[7],buffer);

		if (buffer) HeapFree(GetProcessHeap(), 0, buffer);
	}

	if ( GetLastError()!=NO_ERROR &&
		GetLastError()!=ERROR_NO_MORE_ITEMS )
	{
		return FALSE;
	}
	//  释放
	SetupDiDestroyDeviceInfoList(hDevInfo);
	return TRUE;
}

int main( int argc, char *argv[ ], char *envp[ ] )
{
	// 列举所有设备
	printf("Enumerating All Device\n\n");
	EnumAllDevice();
	// 列举磁盘分卷驱动器设备
	printf("\n\nEnumerating Present Volume \n\n");
	EnumClassDevice(&GUID_DEVINTERFACE_VOLUME);
	return 0;
}


 

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

标签:GetLastError,管理器,lpDeviceInterfaceDetailData,Windows,ClassGuid,C++,DeviceInfoDat
来源: https://www.cnblogs.com/wicnwicnwh/p/10494270.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有