新买来的硬盘是未初始化的,以我的理解就是没有引导扇区的,通常是没有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 flagDWORD junk; // discard resultschar diskPath[256]; //磁盘内部路径//生成磁盘内部路径sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);hDevice = CreateFile(TEXT(diskPath), // drive 或者 用"\\\\.\\PhysicalDrive0" 代表第一块磁盘GENERIC_READ, // no access to the driveFILE_SHARE_READ | // share modeFILE_SHARE_WRITE,NULL, // default security attributesOPEN_EXISTING, // disposition0, // file attributesNULL); // do not copy file attributesif (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive{return (FALSE);}GET_LENGTH_INFORMATION pdg;bResult = DeviceIoControl(hDevice, // device to be queriedIOCTL_DISK_GET_LENGTH_INFO, // operation to performNULL, 0, // no input buffer&pdg, sizeof(pdg), // output buffer&junk, // # bytes returned(LPOVERLAPPED)NULL); // synchronous I/OCloseHandle(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 examinedBOOL result; //结果标志 results flagDWORD readed; // discard resultshDevice = 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 examinedBOOL result; //结果标志 results flagDWORD readed; // discard resultshDevice = 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 examinedBOOL result; //结果标志 results flagDWORD readed; // discard resultsDWORD 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//创建主分区的MBRprintf("创建主分区的MBR\n");newDisk.PartitionStyle = PARTITION_STYLE_MBR;signature = (DWORD)time(0); // 原为time(NULL), get signature from current timenewDisk.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 partitionsfor (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)); //32256dl->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 tableprintf("刷新分区表\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 effectreturn 0;
}//获取磁盘几何信息
BOOL CMDiskManager::GetDriveGeometry(DWORD vDiskNo, DISK_GEOMETRY *pdg)
{HANDLE hDevice; // handle to the drive to be examinedBOOL bResult; // results flagDWORD junk; // discard resultschar diskPath[256]; //磁盘内部路径sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);hDevice = CreateFile(TEXT(diskPath), // drive0, // no access to the driveFILE_SHARE_READ | // share modeFILE_SHARE_WRITE,NULL, // default security attributesOPEN_EXISTING, // disposition0, // file attributesNULL); // do not copy file attributesif (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive{return (FALSE);}bResult = DeviceIoControl(hDevice, // device to be queriedIOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to performNULL, 0, // no input bufferpdg, sizeof(*pdg), // output buffer&junk, // # bytes returned(LPOVERLAPPED)NULL); // synchronous I/OCloseHandle(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 examinedBOOL result; // results flagDWORD readed; // discard resultsCHAR diskPath[256];sprintf(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);hDevice = CreateFile(diskPath, // drive to openGENERIC_READ | GENERIC_WRITE, // access to the driveFILE_SHARE_READ | FILE_SHARE_WRITE, //share modeNULL, // default security attributesOPEN_EXISTING, // disposition0, // file attributesNULL // 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 deviceIOCTL_DISK_DELETE_DRIVE_LAYOUT, // dwIoControlCodeNULL, // lpInBuffer0, // nInBufferSizeNULL, // lpOutBuffer0, // nOutBufferSize&readed, // number of bytes returnedNULL // OVERLAPPED structure);if (!result){//fprintf(stderr, "IOCTL_DISK_DELETE_DRIVE_LAYOUT Error: %ld\n", GetLastError());(void)CloseHandle(hDevice);return DWORD(-1);}//fresh the partition tableresult = 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 examinedBOOL result; // results flagDWORD readed; // discard resultsSTORAGE_DEVICE_NUMBER number; //use this to get disk numbersCHAR path[256];sprintf(path, "\\\\.\\%c:", letter);hDevice = CreateFile(path, // drive to openGENERIC_READ | GENERIC_WRITE, // access to the driveFILE_SHARE_READ | FILE_SHARE_WRITE, //share modeNULL, // default security attributesOPEN_EXISTING, // disposition0, // file attributesNULL); // do not copy file attributeif (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive{fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());return DWORD(-1);}result = DeviceIoControl(hDevice, // handle to deviceIOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCodeNULL, // lpInBuffer0, // nInBufferSize&number, // output buffersizeof(number), // size of output buffer&readed, // number of bytes returnedNULL // 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 changesprintf(path, "%c:\\", letter);driveType = GetDriveType(path);if (driveType != DRIVE_FIXED){bmLetters &= ~mask; //clear this bitcontinue;}diskNumber = GetPhysicalDriveFromPartitionLetter(letter);if (diskNumber != vDiskNo){bmLetters &= ~mask; //clear this bitcontinue;}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 changes.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 0x0Fclass CMDiskManager {public:CMDiskManager(); //获取磁盘几何BOOL GetDriveGeometry(DWORD vDiskNo, DISK_GEOMETRY *pdg);//获取磁盘大小,单位是MBint GetDiskSize(DWORD vDiskNo);/*获取磁盘分区信息vDiskNo:磁盘序号 */DWORD GetLayoutInfo(DWORD vDiskNo);//读MBR信息BOOL ReadMBR(int vDiskNo, LPVOID *pBuffer);/*获取磁盘分区个数vDiskNo:磁盘序号*/int GetPartNum(DWORD vDiskNo);/*初始化磁盘,创建分区vDiskNo:磁盘序号,千万要避开系统盘,系统盘一般是0vPartNum:分区数,只要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;
}