您的位置:首页 > 其它

使用windows API区分移动硬盘和本地硬盘

2013-04-03 17:29 1106 查看
在程序中,有时候需要区分移动硬盘和本地硬盘,U盘的检测比较简单,首先用GetLogicalDriveStrings获取盘符,然后用GetDriveType获取类型,返回结果为DRIVE_REMOVABLE,则为U盘。这里有个问题,就是如果电脑中存在可移动磁盘的盘符,却没有插入移动磁盘,这时候如果试图打开这个磁盘,系统会提示你插入磁盘。所以,应该在检测到类型为DRIVE_REMOVABLE之后,再使用GetVolumeInformation获取卷信息,如果获取成功,则说明该盘符已插入磁盘。

对于移动硬盘,使用GetDriveType返回的结果永远为DRIVE_FIXED,就是说系统将其与本地硬盘归为一类。那么,如何区分指定盘符是移动硬盘还是本地硬盘呢?

首先用CreateFile通过指定的盘符打开设备,返回设备句柄,然后用DeviceIoControl获取设备信息,通过总线类型判断是否USB接入,如果总线类型为USB则是移动硬盘。

代码如下:

bool CopyFileThread::checkRemoveDisk(vector<LPTSTR>* drivePath) //参数存储所有移动盘的盘符

{

bool flag=false;

DWORD dw=GetLogicalDriveStrings(0,NULL);

LPTSTR lpDriveStrings=(LPTSTR)HeapAlloc(GetProcessHeap(),0,dw*sizeof(TCHAR));

GetLogicalDriveStrings(dw,lpDriveStrings); //获取盘符,字符串形式。

do

{

UINT drivetype=GetDriveType(lpDriveStrings); //获取驱动器类型

if(drivetype==DRIVE_REMOVABLE)

//驱动器类型为DRIVE_REMOVABLE,进一步获取卷信息,如果获取成功,则将盘符保存。

{

TCHAR szFileSNBuffer[512];

DWORD dwFSystemFlags;

//获取卷信息,如果获取成功,则说明已插入U盘。

if(GetVolumeInformation(lpDriveStrings,NULL,0,NULL,NULL,&dwFSystemFlags,szFileSNBuffer,512))

{

drivePath->push_back(lpDriveStrings);

flag=true;

}

}

else if(drivetype==DRIVE_FIXED) //驱动器类型为DRIVE_FIXED,需要进一步判断是移动硬盘还是本地硬盘。

{

if(GetDisksProperty( lpDriveStrings)==TRUE) //GetDisksProperty区分移动硬盘和本地硬盘,返回TRUE为移动硬盘.

{

drivePath->push_back(lpDriveStrings);

flag=true;

}

}

lpDriveStrings+=(lstrlen(lpDriveStrings)+1);

}

while(*lpDriveStrings!='\x00');

return flag;

}

GetDisksProperty定义如下:

BOOL CopyFileThread::GetDisksProperty(TCHAR *drive)

{

STORAGE_PROPERTY_QUERY Query;

DWORD dwOutBytes;

BOOL bResult;

Query.PropertyId = StorageDeviceProperty;

Query.QueryType = PropertyStandardQuery;

CString cstr(drive);

cstr="\\\\.\\"+cstr;

cstr.Delete(cstr.GetLength()-1,1);

HANDLE hDevice=CreateFile(

cstr, // 要打开的驱动器设备;格式必须为“\\.\C:”,否则打开失败,返回错误码2:系统找不到指定的文件。

GENERIC_READ | GENERIC_WRITE, // 访问权限

FILE_SHARE_READ | FILE_SHARE_WRITE, //共享模式

NULL, // 使用默认的安全属性

OPEN_EXISTING, // 打开存在的设备

NULL,

NULL

);

if (hDevice == INVALID_HANDLE_VALUE)

{

return FALSE;

}

STORAGE_DESCRIPTOR_HEADER *pDevDescHeader;

pDevDescHeader = (STORAGE_DESCRIPTOR_HEADER *)malloc(sizeof(STORAGE_DESCRIPTOR_HEADER));

if (NULL == pDevDescHeader)

{

return FALSE;

}

bResult = DeviceIoControl(

hDevice, // 设备句柄

IOCTL_STORAGE_QUERY_PROPERTY, // 操作控制码

&Query,sizeof Query, //输入参数及缓冲区大小

pDevDescHeader, //输出参数

sizeof(STORAGE_DESCRIPTOR_HEADER), //输出参数的缓冲区大小

&dwOutBytes, //实际输出的大小

NULL);

if (!bResult)

{

free(pDevDescHeader);

(void)CloseHandle(hDevice);

return FALSE;

}

PSTORAGE_DEVICE_DESCRIPTOR pDevDesc;

pDevDesc=(STORAGE_DEVICE_DESCRIPTOR *)malloc(pDevDescHeader->Size);

bResult = DeviceIoControl(hDevice,

IOCTL_STORAGE_QUERY_PROPERTY,

&Query, sizeof Query,

pDevDesc, pDevDescHeader->Size,

&dwOutBytes,

NULL);

free(pDevDescHeader);

(void)CloseHandle(hDevice);

if(pDevDesc->BusType==BusTypeUsb)//总线类型为USB,返回TRUE

{

free(pDevDesc);

return TRUE;

}

free(pDevDesc);

return FALSE;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: