vc 判断某个盘符是否为移动硬盘盘符

时间:2022-06-02 00:15:41

在使用GetDriveType获取磁盘类型时,一般小容量的U盘直接返回DRIVE_REMOVABLE,倒是不用再进行下一步的判断,而大容量U盘和移动硬盘的盘符返回值和本地硬盘盘符返回值都是DRIVE_FIXED,需要再进行判断,如果是IDE硬盘的话,则盘符所属的磁盘为本地磁盘,否则为可移动磁盘。下面的函数可判断一个磁盘是否为IDE硬盘的分区,传递的磁盘盘符参数形式为C:的形式:

BOOL IsIDE(CString   DriveName)   
{
////本段程序的前提是DriveName是已经过GetDriveType的判断是本地磁盘,否则报错,作用是判断是否是真正的本地磁盘////////
//////////////////111111111111111111111111111111111111111/////////////////////////////////////////////
///////////////////////获得某分区(目的地址)的信息/////////////////////////
HANDLE hDeviceDest = NULL;
DWORD nBytesRead = 0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度
DWORD nBufferSize = sizeof(PARTITION_INFORMATION);
PPARTITION_INFORMATION lpPartInfo = (PPARTITION_INFORMATION)malloc(nBufferSize);
if(lpPartInfo == NULL)
{
//MessageBox("缓冲区分配出错!","失败!",MB_OK);
return FALSE;
}
memset(lpPartInfo, 0, nBufferSize);//将缓冲区lpPartInfo的内容设为nDiskBufferSize个NULL
//CString DriveName="J:";//为判断提供接口
DriveName=_T("\\\\.\\")+DriveName;

hDeviceDest = CreateFile(LPCTSTR(DriveName),//注意一定要是\\\\.\\的形式,CreateFile的要求 ""\\??\\Volume{e9233817-90be-11d6-88b7-00e04c3de005}
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
0, NULL);

if(hDeviceDest == NULL)
{
//MessageBox("CreateFile出错!","失败!",MB_OK);
return FALSE;
}
/////////////获得该分区信息/////////////////////////
BOOL ret1=DeviceIoControl(
hDeviceDest,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
(LPVOID) lpPartInfo,
(DWORD) nBufferSize,
(LPDWORD) &nBytesRead,
NULL//指向一个异步的结构体
);

if (!ret1)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
//::MessageBox( NULL,(LPCTSTR)lpMsgBuf, _T("Error"), MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
//MessageBox("DeviceIoControl出错!","失败!",MB_OK);
return FALSE;
}
///////////////////导出该分区信息///////////////////////////////////
LARGE_INTEGER StartingOffset=lpPartInfo->StartingOffset;
LONGLONG QuadPart=StartingOffset.QuadPart;//取上面的值之一情形,支持64位整型
LARGE_INTEGER PartitionLength=lpPartInfo->PartitionLength;
LONGLONG QuadPart1=PartitionLength.QuadPart;//取上面的值之一情形,支持64位整型
DWORD HiddenSectors=lpPartInfo->HiddenSectors;
DWORD PartitionNumber=lpPartInfo->PartitionNumber;
BYTE PartitionType=lpPartInfo->PartitionType;
BOOLEAN BootIndicator=lpPartInfo->BootIndicator;
BOOLEAN RecognizedPartition=lpPartInfo->RecognizedPartition;
BOOLEAN RewritePartition=lpPartInfo->RewritePartition;

free(lpPartInfo);
CloseHandle(hDeviceDest);

/////////////////////查询注册表中COUNT(Disk)的值//////////////////////////////////////
UINT IDESeqNum;//IDE的序号
BOOL FindIDE=FALSE;

HKEY hKEY;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum"), 0, KEY_READ, &hKEY);
///////////接收DWORD型/////////////

DWORD Type;//仅仅用于接收数据类型
DWORD dwValue;
DWORD dwBufLen = sizeof(DWORD);
long ret2=::RegQueryValueEx(hKEY, _T("Count"), NULL, &Type, (BYTE*)&dwValue, &dwBufLen);
if(ret2!=ERROR_SUCCESS)
{
//MessageBox("找不到磁盘的个数","提示",MB_OK);
return FALSE;//失败
}
for (UINT k=0; k<dwValue; k++)
{
///////////接收字符型/////////////
TCHAR str[256];
DWORD sl = 256;
CString nDisk;
nDisk.Format(_T("%u"),k);
RegQueryValueEx(hKEY, nDisk, NULL, NULL, (LPBYTE)str, &sl); //注意第三项必须设为NULL,否则接收到的字符数据出错
CString temp=str;
if (temp.Left(3)== _T("IDE") )
{
IDESeqNum=k;//IDE的序号
FindIDE=TRUE;
}

}
if (!FindIDE)
return FALSE; // IDESeqNum=0;
RegCloseKey(hKEY);

CString temp;
temp.Format(_T("%u"),IDESeqNum);
temp=_T("\\\\.\\PHYSICALDRIVE")+temp;//为下一步检测作准备
//////////////////22222222222222222222222222222222222222222 /////////////////////////////////////////


HANDLE hDevice = NULL;
DWORD nDiskBytesRead = 0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度
DWORD nDiskBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + sizeof(PARTITION_INFORMATION)*104;//26*4
PDRIVE_LAYOUT_INFORMATION lpDiskPartInfo = (PDRIVE_LAYOUT_INFORMATION)malloc(nDiskBufferSize);

if(lpDiskPartInfo == NULL)
{
//MessageBox("缓冲区分配出错!","失败!",MB_OK);
return FALSE;
}
memset(lpDiskPartInfo, 0, nDiskBufferSize);//将缓冲区lpDiskPartInfo的内容设为nDiskBufferSize个NULL

//////////////////////获得所有分区的信息///////////////////////////////////////
hDevice = CreateFile(LPCTSTR(temp),//注意一定要是\\\\.\\的形式,CreateFile的要求 ""\\??\\Volume{e9233817-90be-11d6-88b7-00e04c3de005}
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
0, NULL);

if(hDevice == NULL)
{
//MessageBox("CreateFile出错!","失败!",MB_OK);
return FALSE;
}

/////////////获得某磁盘上的所有分区信息/////////////////////////
BOOL ret=DeviceIoControl(
hDevice,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
(LPVOID) lpDiskPartInfo,
(DWORD) nDiskBufferSize,
(LPDWORD) &nDiskBytesRead,
NULL
);

if (!ret)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
//MessageBox( (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
//MessageBox("DeviceIoControl出错!","失败!",MB_OK);
return FALSE;
}

//////////////////////////////导出分区信息///////////////////////////////////////
DWORD PartitionCount=lpDiskPartInfo->PartitionCount; //永远是实际的分区数的4倍,不能用的分区将会显示类型PARTITION_ENTRY_UNUSED,即分区类型为0
///////////////////依次获取导出某分区信息,并与目的驱动器进行比较///////////////////////////////////
for (UINT i=0; i<PartitionCount; i=i+4)//+4是因为只有下标为4的整数倍的值才是正确的引用
{
PARTITION_INFORMATION DiskPartInfo=lpDiskPartInfo->PartitionEntry[i];//0为C:,4为D:,8为e:,12为F

LARGE_INTEGER DiskStartingOffset = DiskPartInfo.StartingOffset;
LONGLONG DiskQuadPart = DiskStartingOffset.QuadPart; //取上面的值之一情形,支持64位整型
LARGE_INTEGER DiskPartitionLength = DiskPartInfo.PartitionLength;
LONGLONG DiskQuadPart1 = DiskPartitionLength.QuadPart; //取上面的值之一情形,支持64位整型
DWORD DiskHiddenSectors = DiskPartInfo.HiddenSectors;
DWORD DiskPartitionNumber = DiskPartInfo.PartitionNumber;
BYTE DiskPartitionType = DiskPartInfo.PartitionType;
BOOLEAN DiskBootIndicator = DiskPartInfo.BootIndicator;
BOOLEAN DiskRecognizedPartition = DiskPartInfo.RecognizedPartition;
BOOLEAN DiskRewritePartition = DiskPartInfo.RewritePartition;
if ((DiskQuadPart==QuadPart) && (DiskQuadPart1==QuadPart1)
&& (DiskHiddenSectors==HiddenSectors) && (DiskPartitionNumber==PartitionNumber)
&& (DiskPartitionType==PartitionType ) && (DiskBootIndicator==BootIndicator)
&& (DiskRecognizedPartition==RecognizedPartition) && (DiskRewritePartition==RewritePartition))
{
free(lpDiskPartInfo);
CloseHandle(hDevice);
//::MessageBox(NULL,_T("属于本地驱动器!"),_T("提示"),MB_OK);
return TRUE;
}
}
free(lpDiskPartInfo);
CloseHandle(hDevice);
//::MessageBox(NULL,_T("非本地驱动器!"),_T("提示"),MB_OK);//改为return IDCANCEL;
return FALSE;
}