说明:
有时候我们在做设备监控的时候,要识别一些链接设备,在使用函数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
#define DRIVE_NO_ROOT_DIR 1
#define DRIVE_REMOVABLE 2
#define DRIVE_FIXED 3
#define DRIVE_REMOTE 4
#define DRIVE_CDROM 5
#define DRIVE_RAMDISK 6 //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; //下面附一段代码测试: int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwReturnLen = 0;
PWCHAR pDrive = NULL;
WCHAR wszDrive[MAX_PATH] = { 0 };
dwReturnLen = GetLogicalDriveStringsW(MAX_PATH, wszDrive);
//WCHAR wszName[MAX_PATH] = { 0 };
HANDLE hDevice = NULL; if (dwReturnLen < MAX_PATH)
{
pDrive = wszDrive; while (*pDrive)
{
UINT uType = 0; uType = GetDriveTypeW(pDrive);
if (uType == DRIVE_REMOVABLE)
{
printf("%ws:U盘.\n", pDrive);
}
else if (uType == DRIVE_CDROM)
{
printf("%ws:光驱.\n", pDrive);
} else if (uType == DRIVE_FIXED)
{
//进一步判断移动硬盘或者本地硬盘 wstring wstrName(L"\\\\.\\");
wstrName.append(pDrive, 2); /*经测试\\.\C:\这种格式打不开, *如换成\\.\C:就可以打开了 */ hDevice = CreateFileW(
wstrName.c_str(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (INVALID_HANDLE_VALUE == hDevice)
{
printf("createFile error code:(0x%08x).\n", GetLastError());
getchar();
return 0;
}
//输入查询参数
STORAGE_PROPERTY_QUERY PropertyQuery;
//初始化PropertyQuery
PropertyQuery.PropertyId = StorageDeviceProperty;
PropertyQuery.QueryType = PropertyStandardQuery; BOOL bResult;
DWORD dwBytesReturned = 0;
//查询结果结构
STORAGE_DEVICE_DESCRIPTOR deviceDescriptor = { 0 };
deviceDescriptor.Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);
//STORAGE_BUS_TYPE
bResult = DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY, //系统内置控制码
&PropertyQuery,
sizeof(STORAGE_PROPERTY_QUERY),
&deviceDescriptor,
deviceDescriptor.Size,
&dwBytesReturned,
NULL);
if (bResult)
{
//依据总线类型来判断
//printf("device:%ws storage bus type:%d \n", pDrive, deviceDescriptor.BusType);
if (BusTypeUsb == deviceDescriptor.BusType)
printf("%ws:移动硬盘 \n", pDrive);
else //这里还可以再进一步详细划分 printf("%ws:本地硬盘 \n", pDrive);
}
CloseHandle(hDevice);
hDevice = NULL;
}
else //if (uType == DRIVE_UNKNOWN)
{
printf("%ws:未知.\n", pDrive);
}
pDrive += 4;
}
} getchar();
return 0;
}

测试结果:

说明:这里的结果是我自己的电脑上插了两个U盘,分别是8G和16G的,还有一个移动硬盘,自带一个光驱,安装了一个虚拟光驱。可以都能正确的识别出来

参考链接:

http://blog.sina.com.cn/s/blog_56f9f160010009gp.html

http://blog.csdn.net/sloan6/article/details/7874554

vc 识别移动硬盘 U盘,本地硬盘的更多相关文章

  1. (免量产,免格式化)手动将PE安装到移动硬盘/U盘或无系统硬盘!

    在一台没有装系统的电脑上,只要把XP系统启动文件,及引导菜单文件(ntldr,boot.ini,”bootfont.bin这个可有可无,主要作用是显示中文菜单”)和GRUB引导文件和PE系统文件复制到 ...

  2. 使用MBROSTool 工具制作本地硬盘多启动盘的方法总结

    前段时间写了一个自用五合一多启动盘分享--分别用来维护娱乐,wifi密码破解,win&mac登陆密码绕过/清除,反馈的同学还是挺多,觉得大家都有这方面的需求,于是再把自己的使用经验总结一下. ...

  3. 移动硬盘/U盘装Windows 7旗舰版(VHD版)

    真正的移动版WIN7,在移动硬盘/U盘上运行的WIN7 工具准备 - 联想Y450本本,已安装Windows 7旗舰版(或者WINPE3.0版),用来给移动WIN7做引导 -Win7.vhd,15G, ...

  4. 使用MBROSTool 工具制作本地硬盘F3救急模式的方法总结

    前面写了一篇使用MBROSTool 工具制作本地硬盘多启动盘的方法总结.里面就是可以把一些系统安装到硬盘上面方便使用,比如安装PE到硬盘,不过启动的时候会先进入多UDm菜单,然后选择[启动本地系统]后 ...

  5. Mac通过type-c接口无法识别移动硬盘

      最近买了一块移动硬盘以及硬盘盒连接到Mac上来使用,最近发现了一个问题,就是当我使用完后将硬盘推出第二天再次连接上的时候硬盘不能被识别了,连硬盘和上的数据指示灯也不会亮,但是连接的鼠标键盘却没问题 ...

  6. 移动硬盘/U盘上装Windows 7旗舰版(VHD版)

    真正的移动版WIN7,在移动硬盘/U盘上运行的WIN7 工具准备 - 联想Y450本本,已安装Windows 7旗舰版(或者WINPE3.0版),用来给移动WIN7做引导 -Win7.vhd,15G, ...

  7. Linux下挂载NTFS格式的U盘或硬盘

    我们知道在Linux下挂载fat32的U盘非常容易,使用mount /dev/drive_name /mnt/指定目录这样就可以挂载了,但是如果U盘或者硬盘的格式是NTFS的话,那么Linux是不能识 ...

  8. 如何将win7安装到 移动硬盘/U盘 及 VHD、BCD等相关知识 链接汇总

    如何将win7安装到 移动硬盘/U盘? 从u盘启动win7/2008 R2的方法,更新:换机器免sysprep的方法:http://www.360doc.com/content/11/1103/14/ ...

  9. Openwrt 安装软件到U盘或硬盘

    http://blog.licess.org/openwrt-install-software-to-udisk-harddisk/ 运行一个多月的DDNAS被结婚来玩的小孩给关了,于是趁机更新了一下 ...

随机推荐

  1. ggplot2在一幅图上画两条曲线

    ggplot2在一幅图上画两条曲线 print(data)后的结果是 C BROWN.P MI.P 0 0.9216 0.9282 30 0.9240 0.9282 100 0.9255 0.9282 ...

  2. CentOS 启动提示unexpected inconsistency;RUN fsck MANUALLY, ntfs的input/output Error,InPageError c000009c使用chkdsk修复磁盘,12款Linux系统恢复工具

    CentOS这两天服务器出了问题了,提示如下: unexpected inconsistency;RUN fsck MANUALLY An error occurred during the file ...

  3. Greenplum(PostgreSql)函数实现批量删除表

    项目做库迁移,前期需要经常调整表结构语句,涉及多次的批量drop,本着偷懒精神写了这个函数.鉴于本函数在生产环境有巨大风险,建议测试完毕后立即删除. 主要步骤很简单:1)从pg_tables查询得到相 ...

  4. PE头里的东西更多。。。越看越恶心了,我都不想看了

    winnt.h 中,定义的PE头结构体 typedef struct _IMAGE_NT_HEADERS{DWORD Signature;//PE文件头标志:PE\0\0.在开始DOS header的 ...

  5. C++中的指针(*)、引用(&)、const详解(一、定义变量)

    一.前言 本人作为一个工作了5年的程序员,程序生涯最初是从c/c++开始的,但是始终不能很熟悉的理解c语言中的指针和c++中的引用,归其原因,一部分自己没有静下心来思考,一部分原因是其自身的复杂性. ...

  6. 在线文库解决方案Jacob+SwfTools+FlexPaper

    课程作业,准备做一个类似于豆丁之类的在线文库,解决方案也就是将文档(doc ppt xls)等转换成pdf,然后转成swf展示在页面中,今天下午经过研究,参考其他人的博客,实现了这个主要功能,这里也做 ...

  7. JS函数 返回值的函数 return sum;或者result = add2(3,4);

    返回值的函数 思考:上一节函数中,通过"document.write"把结果输出来,如果想对函数的结果进行处理怎么办呢? 我们只要把"document.write(sum ...

  8. innodb_file_per_table 理解

    MYSQL innodb存储引擎 默认将所有的数据库 innodb 引擎的表数据存储在一个共享空间中:ibdata1,当增删数据库的时候, ibdata1文件不会自动收缩,单个数据库的备份也会成为问题 ...

  9. 威布尔weibull distribution

    data = wblrnd(0.5,0.8,100,1); 生成威布尔随机函数,尺寸参数为0.5,形状参数为0.8,生成数列100行,一列: parmhat = wblfit(data) 对data的 ...

  10. LeetCode第二题—— Add Two Numbers(模拟两数相加)

    Description: You are given two non-empty linked lists representing two non-negative integers. The di ...