C++ 实现判断插入USB的设备是U盘,移动硬盘,光驱
今天做项目,要求代码能区分出U盘,移动硬盘,光驱等。
有时候我们在做设备监控的时候,要识别一些链接设备,在使用函数GetDriveType的时候,U盘可以返回DRIVE_REMOVABLE,而本地硬盘硬盘和移动硬盘DRIVE_FIXED,因此还需要进一步来识别。识别方法为判断设备的总线类型即可:需要用到的数据类型以及函数有:
//将所有的卷存储在buffer中,格式为:C:/NULLD:/NULLE:/NULL
DWORD GetLogicalDriveStrings(
DWORD nBufferLength, // size of buffer
LPTSTR lpBuffer // drive strings buffer);
//判断设备类型:
UINT
GetDriveType(
LPCTSTR
lpRootPathName
// root directory);
返回值有:
#define DRIVE_UNKNOWN 0 //
The drive type cannot be determined. 未知
#define DRIVE_NO_ROOT_DIR 1 //
The root path is invalid; for example, there is no volume is mounted at the path. 可移动磁盘
#define DRIVE_REMOVABLE 2 //
The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader. U盘,软盘
#define DRIVE_FIXED 3//
The drive has fixed media; for example, a hard drive or flash drive. 本地硬盘,移动硬盘
#define DRIVE_REMOTE 4 //
The drive is a remote (network) drive.网络磁盘
#define DRIVE_CDROM 5 //
The drive is a CD-ROM drive. CD-ROM
#define DRIVE_RAMDISK 6 //
The drive is a RAM disk. RAM磁盘
//DeviceIoControl要查询的类型
typedef struct _STORAGE_PROPERTY_QUERY {
// ID of the property being retrieved
STORAGE_PROPERTY_ID PropertyId;//使用前要对此字段赋值
// Flags indicating the type of query being performed
STORAGE_QUERY_TYPE QueryType; //使用前要对此字段赋值
// Space for additional parameters if necessary
BYTE AdditionalParameters[1];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
// STORAGE_PROPERTY_ID枚举类型
typedef enum _STORAGE_PROPERTY_ID {
StorageDeviceProperty = 0,
StorageAdapterProperty,
StorageDeviceIdProperty,
StorageDeviceUniqueIdProperty, // See storduid.h for details
StorageDeviceWriteCacheProperty,
StorageMiniportProperty,
StorageAccessAlignmentProperty,
StorageDeviceSeekPenaltyProperty,
StorageDeviceTrimProperty,
StorageDeviceWriteAggregationProperty,
StorageDeviceDeviceTelemetryProperty,
StorageDeviceLBProvisioningProperty,
StorageDevicePowerProperty,
StorageDeviceCopyOffloadProperty,
StorageDeviceResiliencyProperty,
StorageDeviceMediumProductType,
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
//STORAGE_QUERY_TYPE枚举
typedef enum _STORAGE_QUERY_TYPE {
PropertyStandardQuery = 0, // Retrieves the descriptor
PropertyExistsQuery, // Used to test whether the descriptor is supported
PropertyMaskQuery, // Used to retrieve a mask of writeable fields in the descriptor
PropertyQueryMaxDefined // use to validate the value
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
//我们的输出结构:
typedef _Struct_size_bytes_(Size) struct _STORAGE_DEVICE_DESCRIPTOR {
// Sizeof(STORAGE_DEVICE_DESCRIPTOR)
DWORD Version;
// Total size of the descriptor, including the space for additional data and id strings
DWORD Size;
// The SCSI-2 device type
BYTE DeviceType;
// The SCSI-2 device type modifier (if any) - this may be zero
BYTE DeviceTypeModifier;
// Flag indicating whether the device's media (if any) is removable. This
// field should be ignored for media-less devices
BOOLEAN RemovableMedia;
// Flag indicating whether the device can support mulitple outstanding
// commands. The actual synchronization in this case is the responsibility of the port driver.
BOOLEAN CommandQueueing;
// Byte offset to the zero-terminated ascii string containing the device's
// vendor id string. For devices with no such ID this will be zero
DWORD VendorIdOffset;
// Byte offset to the zero-terminated ascii string containing the device's
// product id string. For devices with no such ID this will be zero
DWORD ProductIdOffset;
// Byte offset to the zero-terminated ascii string containing the device's
// product revision string. For devices with no such string this will be zero
DWORD ProductRevisionOffset;
// Byte offset to the zero-terminated ascii string containing the device's
// serial number. For devices with no serial number this will be zero
DWORD SerialNumberOffset;
// Contains the bus type (as defined above) of the device. It should be
// used to interpret the raw device properties at the end of this structure
// (if any)
STORAGE_BUS_TYPE BusType;
// The number of bytes of bus-specific data which have been appended to this descriptor
DWORD RawPropertiesLength;
// Place holder for the first byte of the bus specific property data
BYTE RawDeviceProperties[1];
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
//最后要根据BusType字段来判断 看一些这个类型:
typedef enum _STORAGE_BUS_TYPE {
BusTypeUnknown = 0x00,
BusTypeScsi,
BusTypeAtapi,
BusTypeAta,
BusType1394,
BusTypeSsa,
BusTypeFibre,
BusTypeUsb,//这个就是移动硬盘了
BusTypeRAID,
BusTypeiScsi,
BusTypeSas,
BusTypeSata,
BusTypeSd,
BusTypeMmc,
BusTypeVirtual,
BusTypeFileBackedVirtual,
BusTypeSpaces,
BusTypeNvme,
BusTypeMax,
BusTypeMaxReserved = 0x7F
} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;
封装的函数代码如下:
#include "stdafx.h"
#include <Windows.h>
#include <Winioctl.h>
INT GetBusType(TCHAR driver)
{
bool bResult = true;
INT BusType = BusTypeUnknown;
HANDLE hDrv = INVALID_HANDLE_VALUE;
STORAGE_DEVICE_DESCRIPTOR DevDesc;
STORAGE_PROPERTY_QUERY ProQuery;
TCHAR tszSymbol[MAX_PATH] = {TEXT("\\\\?\\*:")};
ULONG ulBytesResults = 0;
memset(&ProQuery, 0 ,sizeof(ProQuery));
memset(&DevDesc, 0, sizeof(DevDesc));
if ((driver >= TEXT('A') && driver <= TEXT('Z')) || (driver >= TEXT('a') && driver <= TEXT('z')))
{
}
else
{
return false;
}
tszSymbol[4] = driver;
hDrv = CreateFile(tszSymbol, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDrv == INVALID_HANDLE_VALUE)
goto jump_ret;
ProQuery.QueryType = PropertyStandardQuery;
ProQuery.PropertyId = StorageDeviceProperty;
if (DeviceIoControl(hDrv,IOCTL_STORAGE_QUERY_PROPERTY, &ProQuery,sizeof(ProQuery), &DevDesc, sizeof (DevDesc), &ulBytesResults, NULL) == FALSE)
goto jump_ret;
BusType = DevDesc.BusType;
jump_ret:
if (hDrv != INVALID_HANDLE_VALUE)
{
CloseHandle(hDrv);
hDrv = INVALID_HANDLE_VALUE;
}
return BusType;
}
bool IsCDRom(TCHAR driver) //判断是否是光盘
{
UINT DriverType = DRIVE_UNKNOWN;
TCHAR tszDriver[4] = {TEXT("*:\\")};
tszDriver[0] = driver;
DriverType = GetDriveType(tszDriver);
return DriverType == DRIVE_CDROM;
}
bool IsRemovableDrive(TCHAR driver) //判断是可移动硬盘 true:移动硬盘,false:本地硬盘
{
UINT DriverType = DRIVE_UNKNOWN;
TCHAR tszDriver[4] = {TEXT("*:\\")};
tszDriver[0] = driver;
DriverType = GetDriveType(tszDriver);
bool bRemovableDrive = false;
if (DriverType == DRIVE_FIXED)
{
if (GetBusType(driver) == BusTypeUsb)
bRemovableDrive = true;
}
return bRemovableDrive;
}
bool IsUDrive(TCHAR driver) //判断是否是U盘
{
TCHAR tszDriver[4] = {TEXT("*:\\")};
UINT DriverType = DRIVE_UNKNOWN;
tszDriver[0] = driver;
DriverType = GetDriveType(tszDriver);
return DriverType == DRIVE_REMOVABLE;
}
int _tmain(int argc, _TCHAR* argv[])
{
bool bU = IsUDrive(L'H');
bool bRemovable = IsRemovableDrive(L'H');
bool bIsCD = IsCDRom(L'H');
getchar();
return 0;
}
C++ 实现判断插入USB的设备是U盘,移动硬盘,光驱相关推荐
- Android中使用外置存储设备(U盘/移动硬盘等)
本来是计划每个月至少写2篇博客的,可是2018年的第一个月就失言了.上个月实在是太忙了,从元旦收假上班开始,就开启了天天加班的新年征程,周六一样不放过. 谁让我是IT人呢?不过偶尔加班也没什么不好,对 ...
- 树莓派linux系统识别u盘启动,树莓派Raspberry Pi实战之命令行下实现USB存储设备自动挂载...
简单介绍实现命令行下USB存储设备自动挂载的方法,Linux gnome/kde窗口环境下有移动存储的管理程序,可以实现自动挂载移动存储设备,但是在命令行下 通常需要用mount命令手动挂载USB存储 ...
- linux 自动挂载usb设备,Raspberry Pi 自动挂载USB存储设备
简单介绍实现命令行下USB存储设备自动挂载的方法,Linux gnome/kde窗口环境下有移动存储的管理程序,可以实现自动挂载移动存储设备,但是在命令行下 通常需要用mount命令手动挂载USB存储 ...
- 计算机怎样发现路由器上u盘,360 P2 无线路由器通过电脑终端查看路由USB存储设备操作流程 路由器...
首先,将您的U盘 或 插入存储卡的读卡器 或 移动硬盘(以下称为USB存储设备),插入5G路由后面的USB接口上,如下图 插入USB存储设备后,5G路由面板上的USB指示灯(左数第三个)和后面USB卸 ...
- 掀开USB存储设备自动运行的面纱(精简版)
前前言2:为什么有精简版? 考虑原文(http://blog.sina.com.cn/u/56b798f8010007ht)太长而且比较罗嗦,部分新手会失去耐心看完,因此特地修改原文推出精简版.精简版 ...
- 树莓派USB存储设备自动挂载
树莓派USB存储设备自动挂载 简单介绍实现命令行下USB存储设备自动挂载的方法,Linux gnome/kde窗口环境下有移动存储的管理程序,可以实现自动挂载移动存储设备,但是在命令行下 通常需要用m ...
- 树莓派实现USB存储设备自动挂载
简单介绍实现命令行下USB存储设备自动挂载的方法, linux gnome/kde窗口环境下有移动存储的管理程序,可以实现自动挂载移动存储设备 但是在命令行下 通常需要用mount命令手动挂载USB存 ...
- 树莓派Raspberry Pi实战之命令行下实现USB存储设备自动挂载
此方法对树莓派Jessie系统不适用 简单介绍实现命令行下USB存储设备自动挂载的方法,Linux gnome/kde窗口环境下有移动存储的管理程序,可以实现自动挂载移动存储设备,但是在命令行下 通常 ...
- Ubuntu - usb转串口设备的访问权限设置
可以用如下命令查看串口信息: ls -l /dev/ttyUSB* 但是普通用户没有usb操作权限,下面介绍如何设置usb串口操作权限: 用命令增加访问权限: sudo chmod 666 /dev/ ...
最新文章
- Unable to inject views for BcFragment{8d4c0 #1 id=0x7f0d00a1}
- crypt函数的使用(仅限LINUX)
- php无表单上传文件,php – 如何使用没有实体类的表单上传文件
- 《系统集成项目管理工程师》必背100个知识点-47质量保证人员(QA)的主要工作...
- hdu 1576(拓展欧几里得)
- 2345电脑管家_如何彻底清除流氓的2345安全卫士及2345SafeCenterSvc服务?
- 安卓投屏大师_苹果,安卓手机如何免费投屏?只要悄悄按下这里,便能轻松实现...
- bzoj5324:[Jxoi2018]守卫
- C#解析单层html的中的文本,然后拼接起来
- 菜鸟喜欢的C# 入门认识和添加,修改,删除 文件夹 文件 大全(转)
- 微信小程序瀑布流列表
- 项目1:交换机后台管理程序(待续1……)
- centos7安装terminator
- gradle相关配置内容解析
- 在服务器上使用 gradle 打包 android 源码
- 计算机关机键 自动重启,我的电脑总是关机后自动重启怎么办?
- 大众点评社区运营攻略
- hadoop如何解除safemode-安全模式
- 【记录30】条形码的生成
- QT OpenGL图形放大缩小旋转移动