转载自:https://blog.csdn.net/wuzuyu365/article/details/52881692
新买来的硬盘是未初始化的,以我的理解就是没有引导扇区的,通常是没有MBR,如下图磁盘1,右边有大小,但显示“未分配”,
左边显示“没有初始化”, 点鼠标右键就可以【初始化磁盘】。
初始化时可以选择MBR和GPT, MBR方式顶多支持2T硬盘的。
初始化后
初始化后可以新建简单卷了,之前是不行的:
CreateDisk(1, 3) 就是把磁盘1分为3个分区
奇怪,如果只分1个区,就是自动以NTFS格式化掉, 而分3个区,还会提示是否格式化。
如果想回到刚买回来的空白状态怎么办呢? 用DestroyDisk()就可以了
代码:
CPP:CMDiskManager.cpp
-
#include "stdafx.h"
-
#include "CMDiskManager.h"
-
CMDiskManager::CMDiskManager(){}
-
//获取磁盘大小,单位是MB
-
int CMDiskManager::GetDiskSize(DWORD vDiskNo)
-
{
-
HANDLE hDevice; // handle to the drive to be examined
-
BOOL bResult; // results flag
-
DWORD junk; // discard results
-
char diskPath[256]; //磁盘内部路径
-
//生成磁盘内部路径
-
sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);
-
hDevice = CreateFile(TEXT(diskPath), // drive 或者 用"\\\\.\\PhysicalDrive0" 代表第一块磁盘
-
GENERIC_READ, // no access to the drive
-
FILE_SHARE_READ | // share mode
-
FILE_SHARE_WRITE,
-
NULL, // default security attributes
-
OPEN_EXISTING, // disposition
-
0, // file attributes
-
NULL); // do not copy file attributes
-
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
-
{
-
return (FALSE);
-
}
-
GET_LENGTH_INFORMATION pdg;
-
bResult = DeviceIoControl(hDevice, // device to be queried
-
IOCTL_DISK_GET_LENGTH_INFO, // operation to perform
-
NULL, 0, // no input buffer
-
&pdg, sizeof(pdg), // output buffer
-
&junk, // # bytes returned
-
(LPOVERLAPPED)NULL); // synchronous I/O
-
CloseHandle(hDevice);
-
/* INT64 nUseSize = disk_len.Length.QuadPart;
-
INT64 sizeGB = nUseSize / 1014 / 1024 / 1024;
-
CString szSize;
-
szSize.Format(L"C盘大小 %I64d GB", sizeGB);
-
*/
-
int MB = pdg.Length.QuadPart >> 20;
-
//CString s;
-
//s.Format("C盘大小 %f GB", MB/1024.0);
-
//AfxMessageBox(s, 0, MB_OK);
-
//float x = (float) MB ;
-
return MB ;
-
}
-
/*
-
获取磁盘分区个数
-
vDiskNo:磁盘序号
-
*/
-
int CMDiskManager::GetPartNum(DWORD vDiskNo)
-
{
-
char diskPath[256]; //磁盘内部路径
-
//生成磁盘内部路径
-
sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);
-
HANDLE hDevice; //硬盘句柄 handle to the drive to be examined
-
BOOL result; //结果标志 results flag
-
DWORD readed; // discard results
-
hDevice = CreateFile(
-
diskPath,
-
GENERIC_READ | GENERIC_WRITE,
-
FILE_SHARE_READ | FILE_SHARE_WRITE,
-
NULL, //default security attributes
-
OPEN_EXISTING, // disposition
-
0, // file attributes
-
NULL
-
);
-
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
-
{
-
fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
-
return int(-1);
-
}
-
DRIVE_LAYOUT_INFORMATION_EX* dl;
-
DWORD tSize = 0x4000; // sizeof(DRIVE_LAYOUT_INFORMATION_EX) * 10;
-
dl = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(tSize);
-
if (NULL == dl)
-
{
-
(void)CloseHandle(hDevice);
-
return (int)-2;
-
}
-
result = DeviceIoControl(
-
hDevice,
-
IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
-
NULL,
-
0,
-
dl,
-
tSize,
-
&readed,
-
NULL
-
);
-
if (!result)
-
{
-
fprintf(stderr, "IOCTL_DISK_GET_DRIVE_LAYOUT_EX Error: %ld\n", GetLastError());
-
(void)CloseHandle(hDevice);
-
return int(-3);
-
}
-
CString tPartitionStyle = "RAW";
-
switch (dl->PartitionStyle){
-
case 0:
-
tPartitionStyle = "MBR";
-
break;
-
case 1:
-
tPartitionStyle = "GPT";
-
break;
-
}
-
//printf("dl->PartitionCount = %d", dl->PartitionCount);
-
TRACE("dl->PartitionCount = %d, tPartitionStyle:%s \n", dl->PartitionCount, tPartitionStyle.GetBuffer());
-
//printf("dl->PartitionCount = %d", dl->PartitionCount);
-
int tRet = dl->PartitionCount/4;
-
//TRACE("dl->PartitionCount tRet = %d", tRet);
-
free(dl);
-
(void)CloseHandle(hDevice);
-
return tRet;
-
}
-
//读MBR信息
-
BOOL CMDiskManager::ReadMBR(int vDiskNo, LPVOID *pBuffer)
-
{
-
HANDLE hDevice;
-
DWORD dwSize;
-
DWORD dwOverRead;
-
BOOL bRet = TRUE;
-
char diskPath[256]; //磁盘内部路径
-
//生成磁盘内部路径
-
sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);
-
hDevice = CreateFile(TEXT(diskPath),
-
GENERIC_READ | GENERIC_WRITE,
-
FILE_SHARE_READ | FILE_SHARE_WRITE,
-
NULL,
-
OPEN_EXISTING,
-
0,
-
NULL);
-
if (hDevice == INVALID_HANDLE_VALUE) {
-
TRACE("Open \\\\.\\PhysicalDrive failed. Error=%u\n", GetLastError());
-
return FALSE;
-
}
-
if (!DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL)) {
-
CloseHandle(hDevice);
-
TRACE("FSCTL_LOCK_VOLUME \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());
-
return FALSE;
-
}
-
DISK_GEOMETRY Geometry;
-
if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &Geometry, sizeof(DISK_GEOMETRY), &dwSize, NULL)) {
-
bRet = FALSE;
-
TRACE("IOCTL_DISK_GET_DRIVE_GEOMETRY \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());
-
goto _out;
-
}
-
*pBuffer = (LPVOID)GlobalAlloc(GPTR, Geometry.BytesPerSector);
-
if (*pBuffer) {
-
if (!ReadFile(hDevice, *pBuffer, Geometry.BytesPerSector, &dwOverRead, NULL)) {
-
printf("ReadFile \\\\.\\PhysicalDrive %u bytes failed. Error=%u\n", Geometry.BytesPerSector, GetLastError());
-
bRet = FALSE;
-
}
-
}
-
_out:
-
DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);
-
CloseHandle(hDevice);
-
return bRet;
-
}
-
/*
-
获取磁盘分区信息
-
vDiskNo:磁盘序号
-
*/
-
DWORD CMDiskManager::GetLayoutInfo(DWORD vDiskNo)
-
{
-
char diskPath[256]; //磁盘内部路径
-
//生成磁盘内部路径
-
sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);
-
HANDLE hDevice; //硬盘句柄 handle to the drive to be examined
-
BOOL result; //结果标志 results flag
-
DWORD readed; // discard results
-
hDevice = CreateFile(
-
diskPath,
-
GENERIC_READ | GENERIC_WRITE,
-
FILE_SHARE_READ | FILE_SHARE_WRITE,
-
NULL, //default security attributes
-
OPEN_EXISTING, // disposition
-
0, // file attributes
-
NULL
-
);
-
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
-
{
-
fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
-
return DWORD(-1);
-
}
-
DRIVE_LAYOUT_INFORMATION_EX* dl;
-
DWORD tSize = 0x4000; // sizeof(DRIVE_LAYOUT_INFORMATION_EX) * 10;
-
dl = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(tSize);
-
if (NULL == dl)
-
{
-
(void)CloseHandle(hDevice);
-
return (WORD)-1;
-
}
-
result = DeviceIoControl(
-
hDevice,
-
IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
-
NULL,
-
0,
-
dl,
-
tSize,
-
&readed,
-
NULL
-
);
-
if (!result)
-
{
-
fprintf(stderr, "IOCTL_DISK_GET_DRIVE_LAYOUT_EX Error: %ld\n", GetLastError());
-
(void)CloseHandle(hDevice);
-
return DWORD(-1);
-
}
-
CString tPartitionStyle = "RAW";
-
switch (dl->PartitionStyle){
-
case 0:
-
tPartitionStyle = "MBR";
-
break;
-
case 1:
-
tPartitionStyle = "GPT";
-
break;
-
}
-
//printf("dl->PartitionCount = %d", dl->PartitionCount);
-
TRACE("dl->PartitionCount = %d, tPartitionStyle:%s", dl->PartitionCount, tPartitionStyle.GetBuffer());
-
free(dl);
-
(void)CloseHandle(hDevice);
-
return 0;
-
}
-
/*
-
初始化磁盘,创建分区
-
vDiskNo:磁盘序号,千万要避开系统盘,系统盘一般是0
-
vPartNum:分区数,只要1个分区就可以了
-
*/
-
DWORD CMDiskManager::CreateDisk(DWORD vDiskNo, WORD vPartNum)
-
{
-
printf("准备CreateDisk, vDiskNo=%d, vPartNum=%d \n", vDiskNo, vPartNum);
-
//第0块磁盘是系统盘,不能格式化掉!!!但不排除某些情况下新插入的移动硬盘会是第0块磁盘
-
if (0 == vDiskNo){
-
printf("第0块磁盘是系统盘,不能格式化掉\n");
-
return 0;
-
}
-
HANDLE hDevice; //硬盘句柄 handle to the drive to be examined
-
BOOL result; //结果标志 results flag
-
DWORD readed; // discard results
-
DWORD ret;
-
WORD i;
-
char diskPath[256]; //磁盘内部路径
-
DISK_GEOMETRY pdg;
-
DWORD sectorSize; //扇区大小
-
DWORD signature; //签名
-
LARGE_INTEGER diskSize; //磁盘大小
-
LARGE_INTEGER partSize; //分区大小
-
BYTE actualPartNum; //实际上的分区数
-
DWORD layoutStructSize; //
-
DRIVE_LAYOUT_INFORMATION_EX *dl; //磁盘分区信息
-
CREATE_DISK newDisk; //创建磁盘(初始化?)
-
//生成磁盘内部路径
-
sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);
-
actualPartNum = 4;
-
if (vPartNum > actualPartNum)
-
{
-
printf("vPartNum > 4\n");
-
return (WORD)-1;
-
}
-
hDevice = CreateFile(
-
diskPath,
-
GENERIC_READ | GENERIC_WRITE,
-
FILE_SHARE_READ | FILE_SHARE_WRITE,
-
NULL, //default security attributes
-
OPEN_EXISTING, // disposition
-
0, // file attributes
-
NULL
-
);
-
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
-
{
-
fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
-
return DWORD(-1);
-
}
-
// Create primary partition MBR
-
//创建主分区的MBR
-
printf("创建主分区的MBR\n");
-
newDisk.PartitionStyle = PARTITION_STYLE_MBR;
-
signature = (DWORD)time(0); // 原为time(NULL), get signature from current time
-
newDisk.Mbr.Signature = signature;
-
result = DeviceIoControl(
-
hDevice,
-
IOCTL_DISK_CREATE_DISK,
-
&newDisk,
-
sizeof(CREATE_DISK),
-
NULL,
-
0,
-
&readed,
-
NULL
-
);
-
if (!result)
-
{
-
fprintf(stderr, "IOCTL_DISK_CREATE_DISK Error: %ld\n", GetLastError());
-
(void)CloseHandle(hDevice);
-
return DWORD(-1);
-
}
-
//fresh the partition table
-
//刷新分区表
-
printf("刷新分区表\n");
-
result = DeviceIoControl(
-
hDevice,
-
IOCTL_DISK_UPDATE_PROPERTIES,
-
NULL,
-
0,
-
NULL,
-
0,
-
&readed,
-
NULL
-
);
-
if (!result)
-
{
-
fprintf(stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: %ld\n", GetLastError());
-
(void)CloseHandle(hDevice);
-
return DWORD(-1);
-
}
-
//Now create the partitions
-
//现在创建分区
-
ret = GetDriveGeometry(vDiskNo, &pdg);
-
if ((DWORD)-1 == ret)
-
{
-
return ret;
-
}
-
//扇区大小
-
sectorSize = pdg.BytesPerSector;
-
diskSize.QuadPart = pdg.Cylinders.QuadPart * pdg.TracksPerCylinder *
-
pdg.SectorsPerTrack * pdg.BytesPerSector; //calculate the disk size;
-
partSize.QuadPart = diskSize.QuadPart / vPartNum;
-
//分区结构大小
-
layoutStructSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + (actualPartNum - 1) * sizeof(PARTITION_INFORMATION_EX);
-
dl = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(layoutStructSize);
-
if (NULL == dl)
-
{
-
(void)CloseHandle(hDevice);
-
return (WORD)-1;
-
}
-
dl->PartitionStyle = (DWORD)PARTITION_STYLE_MBR;
-
dl->PartitionCount = actualPartNum;
-
dl->Mbr.Signature = signature;
-
//clear the unused partitions
-
//清除未用的分区
-
printf("清除未用的分区\n");
-
for (i = 0; i < actualPartNum; i++){
-
dl->PartitionEntry[i].RewritePartition = 1;
-
dl->PartitionEntry[i].Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
-
}
-
//set the profile of the partitions
-
for (i = 0; i < vPartNum; i++){
-
dl->PartitionEntry[i].PartitionStyle = PARTITION_STYLE_MBR;
-
dl->PartitionEntry[i].StartingOffset.QuadPart =
-
(partSize.QuadPart * i) + ((LONGLONG)(pdg.SectorsPerTrack) * (LONGLONG)(pdg.BytesPerSector)); //32256
-
dl->PartitionEntry[i].PartitionLength.QuadPart = partSize.QuadPart;
-
dl->PartitionEntry[i].PartitionNumber = i + 1;
-
dl->PartitionEntry[i].RewritePartition = TRUE;
-
dl->PartitionEntry[i].Mbr.PartitionType = PARTITION_IFS;
-
dl->PartitionEntry[i].Mbr.BootIndicator = FALSE;
-
dl->PartitionEntry[i].Mbr.RecognizedPartition = TRUE;
-
dl->PartitionEntry[i].Mbr.HiddenSectors =
-
pdg.SectorsPerTrack + (DWORD)((partSize.QuadPart / sectorSize) * i);
-
}
-
//execute the layout
-
result = DeviceIoControl(
-
hDevice,
-
IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
-
dl,
-
layoutStructSize,
-
NULL,
-
0,
-
&readed,
-
NULL
-
);
-
if (!result)
-
{
-
fprintf(stderr, "IOCTL_DISK_SET_DRIVE_LAYOUT_EX Error: %ld\n", GetLastError());
-
free(dl);
-
(void)CloseHandle(hDevice);
-
return DWORD(-1);
-
}
-
//fresh the partition table
-
printf("刷新分区表\n");
-
result = DeviceIoControl(
-
hDevice,
-
IOCTL_DISK_UPDATE_PROPERTIES,
-
NULL,
-
0,
-
NULL,
-
0,
-
&readed,
-
NULL
-
);
-
if (!result)
-
{
-
fprintf(stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: %ld\n", GetLastError());
-
free(dl);
-
(void)CloseHandle(hDevice);
-
return DWORD(-1);
-
}
-
free(dl);
-
(void)CloseHandle(hDevice);
-
printf("CreateDisk完成\n");
-
Sleep(3000); //wait the operations take effect
-
return 0;
-
}
-
//获取磁盘几何信息
-
BOOL CMDiskManager::GetDriveGeometry(DWORD vDiskNo, DISK_GEOMETRY *pdg)
-
{
-
HANDLE hDevice; // handle to the drive to be examined
-
BOOL bResult; // results flag
-
DWORD junk; // discard results
-
char diskPath[256]; //磁盘内部路径
-
sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);
-
hDevice = CreateFile(TEXT(diskPath), // drive
-
0, // no access to the drive
-
FILE_SHARE_READ | // share mode
-
FILE_SHARE_WRITE,
-
NULL, // default security attributes
-
OPEN_EXISTING, // disposition
-
0, // file attributes
-
NULL); // do not copy file attributes
-
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
-
{
-
return (FALSE);
-
}
-
bResult = DeviceIoControl(hDevice, // device to be queried
-
IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to perform
-
NULL, 0, // no input buffer
-
pdg, sizeof(*pdg), // output buffer
-
&junk, // # bytes returned
-
(LPOVERLAPPED)NULL); // synchronous I/O
-
CloseHandle(hDevice);
-
return (bResult);
-
}
-
/******************************************************************************
-
* Function: delete the partition layout of the disk
-
删除磁盘分区信息(恢复出厂设置)
-
* input: disk, disk name
-
* output: N/A
-
* return: Succeed, 0
-
* Fail, -1
-
******************************************************************************/
-
DWORD CMDiskManager::DestroyDisk(DWORD vDiskNo)
-
{
-
if (0 == vDiskNo){
-
//系统盘是0号盘,为了安全,不能删除
-
return 0;
-
}
-
HANDLE hDevice; // handle to the drive to be examined
-
BOOL result; // results flag
-
DWORD readed; // discard results
-
CHAR diskPath[256];
-
sprintf(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);
-
hDevice = CreateFile(
-
diskPath, // drive to open
-
GENERIC_READ | GENERIC_WRITE, // access to the drive
-
FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode
-
NULL, // default security attributes
-
OPEN_EXISTING, // disposition
-
0, // file attributes
-
NULL // do not copy file attribute
-
);
-
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
-
{
-
fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
-
return DWORD(-1);
-
}
-
result = DeviceIoControl(
-
hDevice, // handle to device
-
IOCTL_DISK_DELETE_DRIVE_LAYOUT, // dwIoControlCode
-
NULL, // lpInBuffer
-
0, // nInBufferSize
-
NULL, // lpOutBuffer
-
0, // nOutBufferSize
-
&readed, // number of bytes returned
-
NULL // OVERLAPPED structure
-
);
-
if (!result)
-
{
-
//fprintf(stderr, "IOCTL_DISK_DELETE_DRIVE_LAYOUT Error: %ld\n", GetLastError());
-
(void)CloseHandle(hDevice);
-
return DWORD(-1);
-
}
-
//fresh the partition table
-
result = DeviceIoControl(
-
hDevice,
-
IOCTL_DISK_UPDATE_PROPERTIES,
-
NULL,
-
0,
-
NULL,
-
0,
-
&readed,
-
NULL
-
);
-
if (!result)
-
{
-
fprintf(stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: %ld\n", GetLastError());
-
(void)CloseHandle(hDevice);
-
return DWORD(-1);
-
}
-
(void)CloseHandle(hDevice);
-
return 0;
-
}
-
/******************************************************************************
-
* Function:快速格式化某个磁盘,文件系统NTFS,
-
如果在CreateDisk()创建磁盘后,磁盘的文件系统是RAW的话,才需要调用该函数
-
* input: disk, disk name
-
* output: N/A
-
* return: Succeed, 0
-
* Fail, 1
-
******************************************************************************/
-
DWORD CMDiskManager::FormatVolume(CHAR letter)
-
{
-
DWORD ret;
-
CHAR cmd[64];
-
sprintf(cmd, "format %c: /FS:NTFS /Q /Y", letter);
-
ret = (DWORD)system(cmd);
-
return ret;
-
}
-
//获取第dwNum个磁盘的信息
-
void CMDiskManager::GetDiskInfo(DWORD &dwNum, CString chDriveInfo[])
-
{
-
DWORD DiskCount = 0;
-
//利用GetLogicalDrives()函数可以获取系统中逻辑驱动器的数量,函数返回的是一个32位无符号整型数据。
-
DWORD DiskInfo = GetLogicalDrives();
-
//通过循环操作查看每一位数据是否为1,如果为1则磁盘为真,如果为0则磁盘不存在。
-
while (DiskInfo)
-
{
-
//通过位运算的逻辑与操作,判断是否为1
-
Sleep(10);
-
if (DiskInfo & 1)
-
{
-
DiskCount++;
-
}
-
DiskInfo = DiskInfo >> 1;//通过位运算的右移操作保证每循环一次所检查的位置向右移动一位。*/
-
}
-
if (dwNum < DiskCount)
-
{
-
return;//实际的磁盘数目大于dwNum
-
}
-
dwNum = DiskCount;//将磁盘分区数量保存
-
//-------------------------------------------------------------------//
-
//通过GetLogicalDriveStrings()函数获取所有驱动器字符串信息长度
-
int DSLength = GetLogicalDriveStrings(0, NULL);
-
CHAR* DStr = new CHAR[DSLength];
-
memset(DStr, 0, DSLength);
-
//通过GetLogicalDriveStrings将字符串信息复制到堆区数组中,其中保存了所有驱动器的信息。
-
GetLogicalDriveStrings(DSLength, DStr);
-
int DType;
-
int si = 0;
-
BOOL fResult;
-
unsigned _int64 i64FreeBytesToCaller;
-
unsigned _int64 i64TotalBytes;
-
unsigned _int64 i64FreeBytes;
-
//读取各驱动器信息,由于DStr内部数据格式是A:\NULLB:\NULLC:\NULL,所以DSLength/4可以获得具体大循环范围
-
for (int i = 0; i<DSLength / 4; ++i)
-
{
-
Sleep(10);
-
CString strdriver = DStr + i * 4;
-
CString strTmp, strTotalBytes, strFreeBytes;
-
DType = GetDriveType(strdriver);//GetDriveType函数,可以获取驱动器类型,参数为驱动器的根目录
-
switch (DType)
-
{
-
case DRIVE_FIXED:
-
{
-
strTmp.Format(_T("本地磁盘"));
-
}
-
break;
-
case DRIVE_CDROM:
-
{
-
strTmp.Format(_T("DVD驱动器"));
-
}
-
break;
-
case DRIVE_REMOVABLE:
-
{
-
strTmp.Format(_T("可移动磁盘"));
-
}
-
break;
-
case DRIVE_REMOTE:
-
{
-
strTmp.Format(_T("网络磁盘"));
-
}
-
break;
-
case DRIVE_RAMDISK:
-
{
-
strTmp.Format(_T("虚拟RAM磁盘"));
-
}
-
break;
-
case DRIVE_UNKNOWN:
-
{
-
strTmp.Format(_T("虚拟RAM未知设备"));
-
}
-
break;
-
default:
-
strTmp.Format(_T("未知设备"));
-
break;
-
}
-
//GetDiskFreeSpaceEx函数,可以获取驱动器磁盘的空间状态,函数返回的是个BOOL类型数据
-
fResult = GetDiskFreeSpaceEx(strdriver,
-
(PULARGE_INTEGER)&i64FreeBytesToCaller,
-
(PULARGE_INTEGER)&i64TotalBytes,
-
(PULARGE_INTEGER)&i64FreeBytes);
-
if (fResult)
-
{
-
strTotalBytes.Format(_T("磁盘总容量%.2fMB"), (float)i64TotalBytes / 1024 / 1024);
-
strFreeBytes.Format(_T("磁盘剩余空间%.2fMB"), (float)i64FreeBytesToCaller / 1024 / 1024);
-
}
-
else
-
{
-
strTotalBytes.Format(_T(""));
-
strFreeBytes.Format(_T(""));
-
}
-
chDriveInfo[i] = strTmp + _T("(") + strdriver + _T("):") + strTotalBytes + ", " +strFreeBytes;
-
si += 4;
-
}
-
}
-
/******************************************************************************
-
* Function: get disk's physical number from its drive letter
-
根据逻辑盘符找到物理硬盘号
-
* e.g. C-->0 (C: is on disk0)
-
* input: letter, drive letter
-
* output: N/A
-
* return: Succeed, disk number
-
* Fail, -1
-
******************************************************************************/
-
//根据逻辑盘符找到物理硬盘号
-
DWORD CMDiskManager::GetPhysicalDriveFromPartitionLetter(CHAR letter)
-
{
-
HANDLE hDevice; // handle to the drive to be examined
-
BOOL result; // results flag
-
DWORD readed; // discard results
-
STORAGE_DEVICE_NUMBER number; //use this to get disk numbers
-
CHAR path[256];
-
sprintf(path, "\\\\.\\%c:", letter);
-
hDevice = CreateFile(path, // drive to open
-
GENERIC_READ | GENERIC_WRITE, // access to the drive
-
FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode
-
NULL, // default security attributes
-
OPEN_EXISTING, // disposition
-
0, // file attributes
-
NULL); // do not copy file attribute
-
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
-
{
-
fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
-
return DWORD(-1);
-
}
-
result = DeviceIoControl(
-
hDevice, // handle to device
-
IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode
-
NULL, // lpInBuffer
-
0, // nInBufferSize
-
&number, // output buffer
-
sizeof(number), // size of output buffer
-
&readed, // number of bytes returned
-
NULL // OVERLAPPED structure
-
);
-
if (!result) // fail
-
{
-
fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: %ld\n", GetLastError());
-
(void)CloseHandle(hDevice);
-
return (DWORD)-1;
-
}
-
//printf("%d %d %d\n\n", number.DeviceType, number.DeviceNumber, number.PartitionNumber);
-
(void)CloseHandle(hDevice);
-
return number.DeviceNumber;
-
}
-
/******************************************************************************
-
* Function: get disk's drive letters from physical number
-
获取一个物理硬盘上的所有盘符
-
* e.g. 0-->{C, D, E} (disk0 has 3 drives, C:, D: and E:)
-
* input: vDiskNo, disk's physical number
-
* output: letters, letters array
-
* return: Succeed, the amount of letters
-
* Fail, -1
-
******************************************************************************/
-
CString CMDiskManager::GetPartitionLetterFromPhysicalDrive(DWORD vDiskNo)
-
{
-
DWORD mask;
-
DWORD driveType;
-
DWORD bmLetters;
-
DWORD diskNumber;
-
CHAR path[256];
-
CHAR letter;
-
DWORD letterNum;
-
WORD i;
-
CHAR *p;
-
CString tRet = "";
-
bmLetters = GetLogicalDrives();
-
if (0 == bmLetters)
-
{
-
return "";
-
}
-
letterNum = 0;
-
for (i = 0; i < sizeof(DWORD) * 8; i++)
-
{
-
mask = 0x1u << i;
-
if ((mask & bmLetters) == 0) //get one letter
-
{
-
continue;
-
}
-
letter = (CHAR)(0x41 + i); //ASCII change
-
sprintf(path, "%c:\\", letter);
-
driveType = GetDriveType(path);
-
if (driveType != DRIVE_FIXED)
-
{
-
bmLetters &= ~mask; //clear this bit
-
continue;
-
}
-
diskNumber = GetPhysicalDriveFromPartitionLetter(letter);
-
if (diskNumber != vDiskNo)
-
{
-
bmLetters &= ~mask; //clear this bit
-
continue;
-
}
-
letterNum++;
-
}
-
//build the result
-
/*letters = (CHAR *)malloc(letterNum);
-
if (NULL == *letters)
-
{
-
return (DWORD)-1;
-
}
-
p = *letters;
-
*/
-
CString s;
-
for (i = 0; i < sizeof(DWORD) * 8; i++)
-
{
-
mask = 0x1u << i;
-
if ((mask & bmLetters) == 0)
-
{
-
continue;
-
}
-
letter = (CHAR)(0x41 + i); //ASCII change
-
s.Format("%c", letter);
-
if (!tRet.IsEmpty()){
-
tRet += ",";
-
}
-
tRet += s + ":";
-
}
-
return tRet;
-
}
头文件:CMDiskManager.h
-
#include <windows.h>
-
#include <winioctl.h>
-
#include <stdio.h>
-
#include "time.h"
-
#include <stdlib.h>
-
#include <tchar.h>
-
#pragma pack(1)
-
#define MAX_MBR_PARTITIONS 4
-
#define MBR_DISK_SIGNATURE_OFFSET 440
-
#define MBR_DISK_PPT_OFFSET 446
-
#define MBR_SIGNATURE_OFFSET 510
-
//
-
// MBR Partition Entry
-
//
-
typedef struct {
-
UINT8 BootIndicator;
-
UINT8 StartHead;
-
UINT8 StartSector;
-
UINT8 StartTrack;
-
UINT8 OSType;
-
UINT8 EndHead;
-
UINT8 EndSector;
-
UINT8 EndTrack;
-
UINT32 StartingLBA;
-
UINT32 SizeInLBA;
-
} MBR_PARTITION_RECORD;
-
//
-
// MBR Partition table
-
//
-
typedef struct {
-
UINT8 BootCode[440];
-
UINT32 UniqueMbrSignature;
-
UINT16 Unknown;
-
MBR_PARTITION_RECORD PartitionRecord[MAX_MBR_PARTITIONS];
-
UINT16 Signature;
-
} MASTER_BOOT_RECORD;
-
#pragma pack()
-
#define MBR_SIGNATURE 0xAA55
-
#define EXTENDED_DOS_PARTITION 0x05
-
#define EXTENDED_WINDOWS_PARTITION 0x0F
-
class CMDiskManager {
-
public:
-
CMDiskManager();
-
//获取磁盘几何
-
BOOL GetDriveGeometry(DWORD vDiskNo, DISK_GEOMETRY *pdg);
-
//获取磁盘大小,单位是MB
-
int GetDiskSize(DWORD vDiskNo);
-
/*
-
获取磁盘分区信息
-
vDiskNo:磁盘序号
-
*/
-
DWORD GetLayoutInfo(DWORD vDiskNo);
-
//读MBR信息
-
BOOL ReadMBR(int vDiskNo, LPVOID *pBuffer);
-
/*
-
获取磁盘分区个数
-
vDiskNo:磁盘序号
-
*/
-
int GetPartNum(DWORD vDiskNo);
-
/*
-
初始化磁盘,创建分区
-
vDiskNo:磁盘序号,千万要避开系统盘,系统盘一般是0
-
vPartNum:分区数,只要1个分区就可以了
-
*/
-
DWORD CreateDisk(DWORD vDiskNo, WORD vPartNum);
-
/*
-
回复磁盘到空白状态,删除MBR分区信息
-
*/
-
DWORD DestroyDisk(DWORD vDiskNo);
-
};
如果CreateDisk之后文件系统格式还是RAW的,那么可以用这个:
-
/******************************************************************************
-
* Function:快速格式化某个磁盘,文件系统NTFS
-
* input: disk, disk name
-
* output: N/A
-
* return: Succeed, 0
-
* Fail, 1
-
******************************************************************************/
-
DWORD CMDiskManager::FormatVolume(CHAR letter)
-
{
-
DWORD ret;
-
CHAR cmd[64];
-
sprintf(cmd, "format %c: /FS:NTFS /Q /Y", letter);
-
ret = (DWORD)system(cmd);
-
return ret;
-
}