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

我们进行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://blog.csdn.net/yincheng01/article/details/7078719

你可能感兴趣的:(基于Visual C++之Windows核心编程代码分析(1)实现设备管理器枚举设备)