如何识别移动硬盘

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; 

}

你可能感兴趣的:(移动)