如何识别移动硬盘

Ring 3下的方法:
童鞋们应该已经发现了,GetDriveType函数只能识别出U盘,无法识别移动硬盘。移动硬盘和本地硬盘将返回相同的类型DRIVE_FIXED。MSDN上的建议是用一个蛋疼无比的函数SetupDiGetDeviceRegistryProperty来识别USB设备。

其实有个更方便的方法,可以通过DeviceIoControl函数查询总线类型来识别USB设备。贴代码:

BOOL IsUsbDriver(TCHAR tchDrvName) 
/*++
Routine Description:
    判断某分区是否是USB设备。

Arguments:
    tchDrvName - 输入参数,驱动器号。

Return Value:
    是USB设备则返回TRUE,否则返回FALSE,
    查询失败也返回FALSE。

Author:
    Fypher
    http://hi.baidu.com/nmn714
    2011/5/1
--*/ 
{ 
TCHAR tcsDrvName[8] = TEXT(".//X:"); 
tcsDrvName[4] = tchDrvName; 
HANDLE hDevice = CreateFile( tcsDrvName,
                                 GENERIC_READ,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                                 OPEN_EXISTING,
                                 FILE_ATTRIBUTE_NORMAL, NULL ); 
if ( hDevice == INVALID_HANDLE_VALUE ) 
{ 
  return FALSE; 
} 
STORAGE_PROPERTY_QUERY StoragePropertyQuery; 
StoragePropertyQuery.PropertyId = StorageDeviceProperty; 
StoragePropertyQuery.QueryType = PropertyStandardQuery; 
BYTE buff[1024] = {0}; 
PSTORAGE_DEVICE_DESCRIPTOR pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)buff; 
pDevDesc->Size = sizeof(buff); 
DWORD dwOutLen; 
BOOL res = DeviceIoControl( hDevice,
                                IOCTL_STORAGE_QUERY_PROPERTY, &StoragePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
                                pDevDesc,
                                pDevDesc->Size, &dwOutLen, NULL ); 
CloseHandle(hDevice); 

if (res) { // 返回结果 
  return pDevDesc->BusType == BusTypeUsb; 
} 
else
{ // 查询失败 
  return FALSE; 
} 
} 

Ring 0下的方法:

在Ring 0下,通过DiskDeviceObject的名字在一定概率上能判断该DiskDeviceObject对应的卷设备是否是USB设备。即名称为HardDiskVolumeXXX的DiskDeviceObject通常是本地硬盘。不过这个方法其实也很不靠谱,尤其是Win7下,插个U盘都是HardDiskVolumeXXX。

其实最好的方法同样是查询总线类型。贴代码:

BOOLEAN IsUsbDriver(IN PDEVICE_OBJECT pDeviceObject) 
/*++
Routine Description:
    判断某磁盘设备是否是USB设备。

Arguments:
    pDeviceObject - 输入参数,卷设备对应的 DiskDeviceObject。
                       卷设备与 DiskDeviceObject 之间的关系可以参考:
                       http://hi.baidu.com/nmn714/blog/item/3d2ccccad529e994c8176842.html

Return Value:
    是USB设备则返回TRUE,否则返回FALSE,
    查询失败也返回FALSE。
--*/ 
{ 
PIRP pNewIrp; 
PSTORAGE_DEVICE_DESCRIPTOR pStorageDeviceDescriptor; 
STORAGE_PROPERTY_QUERY StoragePropertyQuery; 
CHAR buff[128]; 
KEVENT WaitEvent; 
NTSTATUS Status; 
IO_STATUS_BLOCK IoStatus; 
StoragePropertyQuery.PropertyId = StorageDeviceProperty; 
StoragePropertyQuery.QueryType = PropertyStandardQuery; 
KeInitializeEvent(&WaitEvent, NotificationEvent, FALSE); 
pNewIrp = IoBuildDeviceIoControlRequest( IOCTL_STORAGE_QUERY_PROPERTY,pDeviceObject, (PVOID)&StoragePropertyQuery, sizeof(StoragePropertyQuery), (PVOID)buff, sizeof(buff), FALSE, &WaitEvent, &IoStatus ); 
if (!pNewIrp) 
{
   // 创建 IRP 失败 
  return FALSE; 
} 
  Status = IoCallDriver(pDeviceObject, pNewIrp); 
if (Status == STATUS_PENDING) 
{ 
  Status = KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL); 
  Status = IoStatus.Status; 
} 
if (!NT_SUCCESS(Status)) 
{   // 查询失败 
  return FALSE; 
} 
  pStorageDeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)buff; // 返回结果 
  return pStorageDeviceDescriptor->BusType == BusTypeUsb; 
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值