qintangtao

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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; 
}
posted on 2013-01-17 15:45  qintangtao  阅读(994)  评论(0编辑  收藏  举报