vc++如何获取usb接口个数?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vc++如何获取usb接口个数?相关的知识,希望对你有一定的参考价值。
笔记本上有三个usb插口,我想通过vc来检测出机器上usb插口的个数。我试了一下createfile和deviceiocontrol,打开\\.\HCDxx然后检测出driver key name和Hub name,顺序是通过枚举USB控制器->枚举此控制器上的USB HUB,这里我只想获取usb接口个数,所以就没有获取usb设备信息,但是通过测试,我发现我的笔记本和公司的台式机都只能打开HCD1\2 (台式机的usb接口有10个,我的电脑只有3个)。这是怎么回事呢?我又如何检测机器上的usb接口个数?(之前通过注册表查了串口接口个数,很简单,到了usb这里就不行了。。。)目前代码:
问题有更新 ,这是发在csdn上的同一个问题,请关注我3#的回帖问题,谢谢~
http://bbs.csdn.net/topics/391031218
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <setupapi.h>
#include <devguid.h>
#pragma comment(lib, "setupapi")
int main(int argc, char* argv[])
// 得到设备信息集
HDEVINFO hDevInfo = SetupDiGetClassDevs(
(LPGUID)&GUID_DEVCLASS_PORTS,
NULL,
0,
DIGCF_PRESENT/* | DIGCF_ALLCLASSES*/);
if (hDevInfo == INVALID_HANDLE_VALUE)
printf("Error! SetupDiGetClassDevs() return %d\\n", GetLastError());
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0;
TCHAR szBuf[MAX_PATH];
SP_DEVINFO_DATA spDevInfoData = sizeof(SP_DEVINFO_DATA);
// 开始列举设备
DWORD i = 0;
for ( i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &spDevInfoData); i++)
// 得到设备类描述
if ( SetupDiGetClassDescription(
&spDevInfoData.ClassGuid,
szBuf,
MAX_PATH,
NULL) )
_tprintf("\\n%03d : ClassDescription = %s\\n", i, szBuf);
// 得到设备实例的唯一标识ID(由注册表路径组成)
if ( SetupDiGetDeviceInstanceId(
hDevInfo,
&spDevInfoData,
szBuf,
MAX_PATH,
NULL) )
printf("%03d : InstanceId = %s\\n", i, szBuf);
// 得到设备名称
if ( SetupDiGetDeviceRegistryProperty(
hDevInfo,
&spDevInfoData,
SPDRP_DEVICEDESC,
NULL,
(PBYTE)szBuf,
MAX_PATH,
NULL) )
printf("%03d : DeviceDesc = %s\\n", i, szBuf);
// 得到设备型号
if ( SetupDiGetDeviceRegistryProperty(
hDevInfo,
&spDevInfoData,
SPDRP_FRIENDLYNAME,
NULL,
(PBYTE)szBuf,
MAX_PATH,
NULL) )
printf("%03d : FriendName = %s\\n", i, szBuf);
// 得到设备在注册表中的子路径
if ( SetupDiGetDeviceRegistryProperty(
hDevInfo,
&spDevInfoData,
SPDRP_DRIVER,
NULL,
(PBYTE)szBuf,
MAX_PATH,
NULL) )
printf("%03d : Regedit Path = %s\\n", i, szBuf);
printf("\\nPort count = %d\\n", i);
getchar();
return 0;
参考技术A
vc++如何获取usb接口个数:
#include <windows.h>#include <stdio.h>
#include <Shlwapi.h>
#include <conio.h>
extern "C"
// Declare the C libraries used
#include <setupapi.h> // Must link in setupapi.lib
#include <hidsdi.h> // Must link in hid.lib
static /*const*/ GUID GUID_DEVINTERFACE_USB_DEVICE =
0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED ;
TCHAR * GetErrString(TCHAR *str, DWORD errcode)
LPVOID lpbuf;
if(FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errcode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpbuf,
0,
NULL
))
lstrcpy(str,(LPCWSTR)lpbuf);
LocalFree(lpbuf);
return str;
int main(int argc, char* argv[])
char szTraceBuf[256];
// Get device interface info set handle for all devices attached to system
HDEVINFO hDevInfo = SetupDiGetClassDevs(
&GUID_DEVINTERFACE_USB_DEVICE, /* CONST GUID * ClassGuid - USB class GUID */
NULL, /* PCTSTR Enumerator */
NULL, /* HWND hwndParent */
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE /* DWORD Flags */
);
if (hDevInfo == INVALID_HANDLE_VALUE)
sprintf(szTraceBuf, "SetupDiClassDevs() failed. GetLastError() " \\
"returns: 0x%x\\n", GetLastError());
OutputDebugStringA(szTraceBuf);
return 1;
sprintf(szTraceBuf, "Device info set handle for all devices attached to " \\
"system: 0x%x\\n", hDevInfo);
OutputDebugStringA(szTraceBuf);
// Retrieve a context structure for a device interface of a device
// information set.
DWORD dwIndex = 0;
SP_DEVICE_INTERFACE_DATA devInterfaceData;
ZeroMemory(&devInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA));
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
BOOL bRet = FALSE;
ULONG neededLength,requiredLength;
PSP_DEVICE_INTERFACE_DETAIL_DATA ClassDeviceData;
HIDD_ATTRIBUTES attributes;
while(TRUE)
bRet = SetupDiEnumDeviceInterfaces(
hDevInfo, /* HDEVINFO DeviceInfoSet */
NULL, /* PSP_DEVINFO_DATA DeviceInfoData */
&GUID_DEVINTERFACE_USB_DEVICE, /* CONST GUID * InterfaceClassGuid */
dwIndex,
&devInterfaceData /* PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData */
);
if (!bRet)
TCHAR buffer[1024];
TCHAR szTraceBuf[1024];
GetErrString(buffer,GetLastError());
wsprintf(szTraceBuf, L"SetupDiEnumDeviceInterfaces failed msg:%s",buffer);
OutputDebugStringW(szTraceBuf);
if (GetLastError() == ERROR_NO_MORE_ITEMS)
break;
else
// 发现一个HID设备,获取设备的详细信息
// 第一次调用SetupDiGetDeviceInterfaceDetail得到ClassDeviceData的大小,但返回错误
SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInterfaceData,
NULL,0,&requiredLength,NULL);
neededLength =requiredLength;
ClassDeviceData =(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(neededLength);
ClassDeviceData-> cbSize =sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
//第二次调用SetupDiGetDeviceInterfaceDetail
// 使用 合适的neededLength.
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInterfaceData,
ClassDeviceData,neededLength,&requiredLength,NULL))
free(ClassDeviceData);
SetupDiDestroyDeviceInfoList(hDevInfo);
return -1;
// 建立HID设备的句柄
HANDLE handle=CreateFile(ClassDeviceData-> DevicePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,0,NULL);
// 获取 attributes 以便得到Vendor ID 和 Product ID
HidD_GetAttributes(handle,&attributes);
TCHAR buffer[1024];
wsprintf(buffer,L"name:%s pid=%d vid=%d version=%d \\n",ClassDeviceData-> DevicePath,attributes.ProductID,attributes.VendorID,attributes.VersionNumber);
OutputDebugStringW(buffer);
CloseHandle(handle);
free(ClassDeviceData);
dwIndex++;
sprintf(szTraceBuf, "Number of device interface sets representing all " \\
"devices attached to system: %d\\n", dwIndex);
OutputDebugStringA(szTraceBuf);
SetupDiDestroyDeviceInfoList(hDevInfo);
getch();
return 0;
参考技术B 这涉及到驱动方面的知识.建议下载WinSDK 关于vxd驱动方面的知识 参考技术C 我也写过,然后一个都没有找出来。你可以把你的全部代码给我观摩一下嘛。能找到的例子太少了。
拜托。小白急需拯救。
还有我私信你了。
VC++获取电脑的各个磁盘盘符及容量信息(附源码)
目录
1、调用GetLogicalDrives接口获取逻辑磁盘个数
2、调用GetLogicalDriveStrings接口获取磁盘盘符列表字串
4、调用GetDiskFreeSpaceEx接口获取磁盘的容量信息
有时我们需要获取电脑上所有磁盘及容量信息,本文将详细讲述如何调用系统API函数来获取这些信息。
1、调用GetLogicalDrives接口获取逻辑磁盘个数
首先,我们先调用系统API接口GetLogicalDrives获取逻辑磁盘的个数,该函数返回的是个4字节32位整型值,每个bit位标记着是否是有效的逻辑磁盘,1为磁盘,0为非磁盘,所以我通过遍历该函数返回的32位整型数值的每一个bit去得到当前电脑上的逻辑磁盘个数。相关代码如下所示:
int nDiskCount = 0;
// GetLogicalDrives函数返回的是个4字节32位整型值,每个bit位标记着是否是有效的磁盘,1为磁盘,0为非磁盘
DWORD nDiskMask = GetLogicalDrives();
while ( nDiskMask )
// 判断最低位是否为1
if ( nDiskMask & 1 )
++nDiskCount;
// 进行右移操作,检查最低位是否为1
nDiskMask = nDiskMask >> 1;
2、调用GetLogicalDriveStrings接口获取磁盘盘符列表字串
调用系统API接口GetLogicalDriveStrings获取的磁盘符号列表字串的格式为:C:\\\\0D:\\\\0E:\\0(注意此处的\\0是分隔符,\\0是一个字符),此处讲的字串不是我们平时用的字符串,因为字符串是以\\0结尾的,而此处获取的磁盘符号列表字串中是以\\0为分隔符的。
我们在调用GetLogicalDriveStrings时,最开始给该函数的第一个参数传0,这样GetLogicalDriveStrings返回的就是用来存放磁盘符号列表字串所需要的buffer长度。然后我们用这个长度值去创建buffer,然后再调用GetLogicalDriveStrings函数接口即可获取。相关代码如下:
// 先传入0,获取装载磁盘字串的缓冲区长度
int nDiskStringsLen = GetLogicalDriveStrings( 0, NULL );
//通过获取装载磁盘字串的缓冲区长度,去创建缓冲区buffer
TCHAR* szDiskStringsBuf = new TCHAR[nDiskStringsLen+1];
memset( szDiskStringsBuf, 0, (nDiskStringsLen+1)*sizeof(TCHAR) );
// 用创建的buffer去获取磁盘符号字串
GetLogicalDriveStrings( nDiskStringsLen, (LPTSTR)szDiskStringsBuf );
3、从磁盘列表字串中解析出每个磁盘盘符并获取对应的磁盘类型
获取的磁盘符号列表字串的格式为:C:\\\\0D:\\\\0E:\\0,我们按照这个格式,每四个字节就包含了一个磁盘盘符,按照这个规律去截取,然后再调用系统API接口GetDriveType,来获取该磁盘的类型。常见的磁盘类型有硬盘、移动式磁盘(移动硬盘和U盘)、光驱、网络磁盘和虚拟RAM磁盘等。相关的代码如下所示:
// 磁盘符号列表串是这样子的:C:\\NULLD:\\NULLE:\\NULL(其中NULL为\\0),所以每个磁盘符号占用4个TCHAR
for (int i = 0; i < nDiskStringsLen / 4; ++i)
// 考虑到程序是Unicode宽字节的版本,所以可能会用到wcout,所以用UNICODE宏判断一下
#ifdef UNICODE
wcout << szDiskStringsBuf[nDiskStartIdx]<<" ";
#else
cout << szDiskStringsBuf[nDiskStartIdx]<<" ";
#endif
nDiskType = GetDriveType( szDiskStringsBuf + i*4 );
if ( nDiskType == DRIVE_FIXED )
cout << "硬盘";
else if ( nDiskType == DRIVE_REMOVABLE )
cout << "移动式磁盘";
else if ( nDiskType == DRIVE_CDROM )
cout << "光驱";
else if ( nDiskType == DRIVE_REMOTE )
cout << "网络磁盘";
else if ( nDiskType == DRIVE_RAMDISK )
cout << "虚拟RAM磁盘";
else if ( nDiskType == DRIVE_UNKNOWN )
cout << "未知设备";
//......(此处省略代码)
4、调用GetDiskFreeSpaceEx接口获取磁盘的容量信息
我们拿到盘符后,然后就可以调用系统API接口GetDiskFreeSpaceEx去获取对应盘的容量信息了,包含总的容量和可用容量信息。
unsigned _int64 u64FreeBytesAvailableToCaller = 0;
unsigned _int64 u64TotalNumberOfBytes = 0;
unsigned _int64 u64TotalNumberOfFreeBytes = 0;
TCHAR szhRootPath[64] = 0 ;
_stprintf( szhRootPath, _T("%c:\\\\"), szDiskStringsBuf[nDiskStartIdx] );
// 调用GetDiskFreeSpaceEx函数获取磁盘的容量信息
BOOL bRet = GetDiskFreeSpaceEx( szhRootPath, (PULARGE_INTEGER)&u64FreeBytesAvailableToCaller,
(PULARGE_INTEGER)&u64TotalNumberOfBytes, (PULARGE_INTEGER)&u64TotalNumberOfFreeBytes );
if (bRet)
tstring strTotalSizeText = GetSizeDescText( u64TotalNumberOfBytes );
tstring strTotalFreeSizeText = GetSizeDescText( u64TotalNumberOfFreeBytes );
#ifdef UNICODE
wcout << " 磁盘总容量:" << strTotalSizeText.c_str();
wcout << " 磁盘可用容量:" << strTotalFreeSizeText.c_str();
#else
cout << " 磁盘总容量:" << strTotalSizeText.c_str();
cout << " 磁盘可用容量:" << strTotalFreeSizeText.c_str();
#endif
else
cout << " 获取容量信息失败";
这个地方有几点需要说明一下。为了方便操作字符串,我们使用了C++的string类,为了兼容Unicode宽字节,我们还使用了wstring,所以我们特意定义了一个tstring类型,如下所示:
#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif
在Unicode宽字节下tstring对应的就是宽字节版本的wstring,在ANSI窄字节下对应窄字节版本的string。工程到底使用的是Unicode宽字节还是ANSI窄字节,是在工程属性中设定的,如下:
此外,上述代码中缓冲区buffer使用了支持Unicode的TCHAR类型,该类型对应的定义为:
#ifdef _UNICODE
typedef WCHAR TCHAR, *PTCHAR;
#else
typedef char TCHAR, *PTCHAR;
#endif
所以我们在使用cout打印信息时,也使用了wcout和cout,即Unicode下用wcout、ANSI下用cout。另外,我们在显示磁盘容量大小时,我们实现了一个根据实际容量大小选择合适单位来显示,比如B、KB、MB、GB、TB等,函数内部实现如下:
tstring GetSizeDescText( unsigned __int64 u64Size )
TCHAR* typeText[] =
_T("B"),
_T("KB"),
_T("MB"),
_T("GB"),
_T("TB")
;
int nArrSize = 5; // 数组typeText大小,要严格和typeText对应起来
int index = 0; // typeText数组索引
double douSize = (double)u64Size;
while( douSize >= 1024 && index < nArrSize )
douSize /= 1024.0;
index++;
tstring strSizeText;
TCHAR szSizeNum[256] = 0 ;
_stprintf( szSizeNum, _T("%0.1f"), douSize ); // 保留一位小数点
strSizeText = szSizeNum;
strSizeText += typeText[index];
return strSizeText;
5、完整代码展示
可以用Visual Studio创建一个控制台工程,然后将下面给出的代码拷贝到工程中运行即可。完整代码如下:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif
tstring GetSizeDescText( unsigned __int64 u64Size )
TCHAR* typeText[] =
_T("B"),
_T("KB"),
_T("MB"),
_T("GB"),
_T("TB")
;
int nArrSize = 5; // 数组typeText大小,要严格和typeText对应起来
int index = 0; // typeText数组索引
double douSize = (double)u64Size;
while( douSize >= 1024 && index < nArrSize )
douSize /= 1024.0;
index++;
tstring strSizeText;
TCHAR szSizeNum[256] = 0 ;
_stprintf( szSizeNum, _T("%0.1f"), douSize ); // 保留一位小数点
strSizeText = szSizeNum;
strSizeText += typeText[index];
return strSizeText;
int _tmain(int argc, _TCHAR* argv[])
// 1、先获取逻辑磁盘的个数
int nDiskCount = 0;
// GetLogicalDrives函数返回的是个4字节32位整型值,每个bit位标记着是否是有效的磁盘,1为磁盘,0为非磁盘
DWORD nDiskMask = GetLogicalDrives();
while ( nDiskMask )
// 判断最低位是否为1
if ( nDiskMask & 1 )
++nDiskCount;
// 进行右移操作,检查最低位是否为1
nDiskMask = nDiskMask >> 1;
cout << endl;
cout << "逻辑磁盘数量:" << nDiskCount << endl;
// 2、获取磁盘符号列表串:C:\\NULLD:\\NULLE:\\NULL(其中NULL为\\0)
// 先传入0,获取装载磁盘字串的缓冲区长度
int nDiskStringsLen = GetLogicalDriveStrings( 0, NULL );
//通过获取装载磁盘字串的缓冲区长度,去创建缓冲区buffer
TCHAR* szDiskStringsBuf = new TCHAR[nDiskStringsLen+1];
memset( szDiskStringsBuf, 0, (nDiskStringsLen+1)*sizeof(TCHAR) );
// 用创建的buffer去获取磁盘符号字串
GetLogicalDriveStrings( nDiskStringsLen, (LPTSTR)szDiskStringsBuf );
int nDiskType = 0;
int nDiskStartIdx = 0;
unsigned _int64 u64FreeBytesAvailableToCaller = 0;
unsigned _int64 u64TotalNumberOfBytes = 0;
unsigned _int64 u64TotalNumberOfFreeBytes = 0;
// 3、从磁盘符号列表串中解析出每个盘符,并获取每个盘的容量
// 磁盘符号列表串是这样子的:C:\\NULLD:\\NULLE:\\NULL(其中NULL为\\0),所以每个磁盘符号占用4个TCHAR
for (int i = 0; i < nDiskStringsLen / 4; ++i)
// 考虑到程序是Unicode宽字节的版本,所以可能会用到wcout,所以用UNICODE宏判断一下
#ifdef UNICODE
wcout << szDiskStringsBuf[nDiskStartIdx]<<" ";
#else
cout << szDiskStringsBuf[nDiskStartIdx]<<" ";
#endif
nDiskType = GetDriveType( szDiskStringsBuf + i*4 );
if ( nDiskType == DRIVE_FIXED )
cout << "硬盘";
else if ( nDiskType == DRIVE_REMOVABLE )
cout << "移动式磁盘";
else if ( nDiskType == DRIVE_CDROM )
cout << "光驱";
else if ( nDiskType == DRIVE_REMOTE )
cout << "网络磁盘";
else if ( nDiskType == DRIVE_RAMDISK )
cout << "虚拟RAM磁盘";
else if ( nDiskType == DRIVE_UNKNOWN )
cout << "未知设备";
TCHAR szhRootPath[64] = 0 ;
_stprintf( szhRootPath, _T("%c:\\\\"), szDiskStringsBuf[nDiskStartIdx] );
// 调用GetDiskFreeSpaceEx函数获取磁盘的容量信息
BOOL bRet = GetDiskFreeSpaceEx( szhRootPath, (PULARGE_INTEGER)&u64FreeBytesAvailableToCaller,
(PULARGE_INTEGER)&u64TotalNumberOfBytes, (PULARGE_INTEGER)&u64TotalNumberOfFreeBytes );
if (bRet)
//cout << " 磁盘总容量:" << (float)u64TotalNumberOfBytes/1024/1024 /1024 << " G";
//cout << " 磁盘可用容量:" << (float)u64TotalNumberOfFreeBytes/1024/1024/1024 << " G";
tstring strTotalSizeText = GetSizeDescText( u64TotalNumberOfBytes );
tstring strTotalFreeSizeText = GetSizeDescText( u64TotalNumberOfFreeBytes );
#ifdef UNICODE
wcout << " 磁盘总容量:" << strTotalSizeText.c_str();
wcout << " 磁盘可用容量:" << strTotalFreeSizeText.c_str();
#else
cout << " 磁盘总容量:" << strTotalSizeText.c_str();
cout << " 磁盘可用容量:" << strTotalFreeSizeText.c_str();
#endif
else
cout << " 获取容量信息失败";
cout << endl;
nDiskStartIdx += 4;
cout << endl;
system("pause");
我机器的运行结果是:(机器上插入了一个U盘)
以上是关于vc++如何获取usb接口个数?的主要内容,如果未能解决你的问题,请参考以下文章