windows下初始化格式化磁盘

转载自: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

 
  1. #include "stdafx.h"

  2. #include "CMDiskManager.h"

  3.  
  4. CMDiskManager::CMDiskManager(){}

  5.  
  6. //获取磁盘大小,单位是MB

  7. int CMDiskManager::GetDiskSize(DWORD vDiskNo)

  8. {

  9. HANDLE hDevice; // handle to the drive to be examined

  10. BOOL bResult; // results flag

  11. DWORD junk; // discard results

  12.  
  13. char diskPath[256]; //磁盘内部路径

  14. //生成磁盘内部路径

  15. sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);

  16.  
  17. hDevice = CreateFile(TEXT(diskPath), // drive 或者 用"\\\\.\\PhysicalDrive0" 代表第一块磁盘

  18. GENERIC_READ, // no access to the drive

  19. FILE_SHARE_READ | // share mode

  20. FILE_SHARE_WRITE,

  21. NULL, // default security attributes

  22. OPEN_EXISTING, // disposition

  23. 0, // file attributes

  24. NULL); // do not copy file attributes

  25.  
  26. if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

  27. {

  28. return (FALSE);

  29. }

  30.  
  31. GET_LENGTH_INFORMATION pdg;

  32. bResult = DeviceIoControl(hDevice, // device to be queried

  33. IOCTL_DISK_GET_LENGTH_INFO, // operation to perform

  34. NULL, 0, // no input buffer

  35. &pdg, sizeof(pdg), // output buffer

  36. &junk, // # bytes returned

  37. (LPOVERLAPPED)NULL); // synchronous I/O

  38.  
  39. CloseHandle(hDevice);

  40.  
  41. /* INT64 nUseSize = disk_len.Length.QuadPart;

  42. INT64 sizeGB = nUseSize / 1014 / 1024 / 1024;

  43. CString szSize;

  44. szSize.Format(L"C盘大小 %I64d GB", sizeGB);

  45. */

  46. int MB = pdg.Length.QuadPart >> 20;

  47. //CString s;

  48. //s.Format("C盘大小 %f GB", MB/1024.0);

  49. //AfxMessageBox(s, 0, MB_OK);

  50. //float x = (float) MB ;

  51. return MB ;

  52. }

  53.  
  54.  
  55. /*

  56. 获取磁盘分区个数

  57. vDiskNo:磁盘序号

  58. */

  59. int CMDiskManager::GetPartNum(DWORD vDiskNo)

  60. {

  61. char diskPath[256]; //磁盘内部路径

  62. //生成磁盘内部路径

  63. sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);

  64. HANDLE hDevice; //硬盘句柄 handle to the drive to be examined

  65. BOOL result; //结果标志 results flag

  66. DWORD readed; // discard results

  67.  
  68. hDevice = CreateFile(

  69. diskPath,

  70. GENERIC_READ | GENERIC_WRITE,

  71. FILE_SHARE_READ | FILE_SHARE_WRITE,

  72. NULL, //default security attributes

  73. OPEN_EXISTING, // disposition

  74. 0, // file attributes

  75. NULL

  76. );

  77. if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

  78. {

  79. fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());

  80. return int(-1);

  81. }

  82.  
  83. DRIVE_LAYOUT_INFORMATION_EX* dl;

  84. DWORD tSize = 0x4000; // sizeof(DRIVE_LAYOUT_INFORMATION_EX) * 10;

  85. dl = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(tSize);

  86. if (NULL == dl)

  87. {

  88. (void)CloseHandle(hDevice);

  89. return (int)-2;

  90. }

  91.  
  92. result = DeviceIoControl(

  93. hDevice,

  94. IOCTL_DISK_GET_DRIVE_LAYOUT_EX,

  95. NULL,

  96. 0,

  97. dl,

  98. tSize,

  99. &readed,

  100. NULL

  101. );

  102.  
  103. if (!result)

  104. {

  105. fprintf(stderr, "IOCTL_DISK_GET_DRIVE_LAYOUT_EX Error: %ld\n", GetLastError());

  106. (void)CloseHandle(hDevice);

  107. return int(-3);

  108. }

  109.  
  110. CString tPartitionStyle = "RAW";

  111. switch (dl->PartitionStyle){

  112. case 0:

  113. tPartitionStyle = "MBR";

  114. break;

  115. case 1:

  116. tPartitionStyle = "GPT";

  117. break;

  118. }

  119.  
  120. //printf("dl->PartitionCount = %d", dl->PartitionCount);

  121. TRACE("dl->PartitionCount = %d, tPartitionStyle:%s \n", dl->PartitionCount, tPartitionStyle.GetBuffer());

  122.  
  123. //printf("dl->PartitionCount = %d", dl->PartitionCount);

  124. int tRet = dl->PartitionCount/4;

  125. //TRACE("dl->PartitionCount tRet = %d", tRet);

  126.  
  127. free(dl);

  128. (void)CloseHandle(hDevice);

  129.  
  130. return tRet;

  131. }

  132.  
  133. //读MBR信息

  134. BOOL CMDiskManager::ReadMBR(int vDiskNo, LPVOID *pBuffer)

  135. {

  136. HANDLE hDevice;

  137. DWORD dwSize;

  138. DWORD dwOverRead;

  139. BOOL bRet = TRUE;

  140. char diskPath[256]; //磁盘内部路径

  141. //生成磁盘内部路径

  142. sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);

  143.  
  144. hDevice = CreateFile(TEXT(diskPath),

  145. GENERIC_READ | GENERIC_WRITE,

  146. FILE_SHARE_READ | FILE_SHARE_WRITE,

  147. NULL,

  148. OPEN_EXISTING,

  149. 0,

  150. NULL);

  151. if (hDevice == INVALID_HANDLE_VALUE) {

  152. TRACE("Open \\\\.\\PhysicalDrive failed. Error=%u\n", GetLastError());

  153. return FALSE;

  154. }

  155.  
  156. if (!DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL)) {

  157. CloseHandle(hDevice);

  158. TRACE("FSCTL_LOCK_VOLUME \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());

  159. return FALSE;

  160. }

  161.  
  162. DISK_GEOMETRY Geometry;

  163. if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &Geometry, sizeof(DISK_GEOMETRY), &dwSize, NULL)) {

  164. bRet = FALSE;

  165. TRACE("IOCTL_DISK_GET_DRIVE_GEOMETRY \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());

  166. goto _out;

  167. }

  168.  
  169. *pBuffer = (LPVOID)GlobalAlloc(GPTR, Geometry.BytesPerSector);

  170. if (*pBuffer) {

  171. if (!ReadFile(hDevice, *pBuffer, Geometry.BytesPerSector, &dwOverRead, NULL)) {

  172. printf("ReadFile \\\\.\\PhysicalDrive %u bytes failed. Error=%u\n", Geometry.BytesPerSector, GetLastError());

  173. bRet = FALSE;

  174. }

  175. }

  176.  
  177. _out:

  178. DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);

  179. CloseHandle(hDevice);

  180. return bRet;

  181.  
  182. }

  183.  
  184.  
  185. /*

  186. 获取磁盘分区信息

  187. vDiskNo:磁盘序号

  188. */

  189. DWORD CMDiskManager::GetLayoutInfo(DWORD vDiskNo)

  190. {

  191. char diskPath[256]; //磁盘内部路径

  192. //生成磁盘内部路径

  193. sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);

  194. HANDLE hDevice; //硬盘句柄 handle to the drive to be examined

  195. BOOL result; //结果标志 results flag

  196. DWORD readed; // discard results

  197.  
  198. hDevice = CreateFile(

  199. diskPath,

  200. GENERIC_READ | GENERIC_WRITE,

  201. FILE_SHARE_READ | FILE_SHARE_WRITE,

  202. NULL, //default security attributes

  203. OPEN_EXISTING, // disposition

  204. 0, // file attributes

  205. NULL

  206. );

  207. if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

  208. {

  209. fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());

  210. return DWORD(-1);

  211. }

  212.  
  213. DRIVE_LAYOUT_INFORMATION_EX* dl;

  214. DWORD tSize = 0x4000; // sizeof(DRIVE_LAYOUT_INFORMATION_EX) * 10;

  215. dl = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(tSize);

  216. if (NULL == dl)

  217. {

  218. (void)CloseHandle(hDevice);

  219. return (WORD)-1;

  220. }

  221.  
  222. result = DeviceIoControl(

  223. hDevice,

  224. IOCTL_DISK_GET_DRIVE_LAYOUT_EX,

  225. NULL,

  226. 0,

  227. dl,

  228. tSize,

  229. &readed,

  230. NULL

  231. );

  232.  
  233. if (!result)

  234. {

  235. fprintf(stderr, "IOCTL_DISK_GET_DRIVE_LAYOUT_EX Error: %ld\n", GetLastError());

  236. (void)CloseHandle(hDevice);

  237. return DWORD(-1);

  238. }

  239.  
  240. CString tPartitionStyle = "RAW";

  241. switch (dl->PartitionStyle){

  242. case 0:

  243. tPartitionStyle = "MBR";

  244. break;

  245. case 1:

  246. tPartitionStyle = "GPT";

  247. break;

  248. }

  249.  
  250. //printf("dl->PartitionCount = %d", dl->PartitionCount);

  251. TRACE("dl->PartitionCount = %d, tPartitionStyle:%s", dl->PartitionCount, tPartitionStyle.GetBuffer());

  252.  
  253. free(dl);

  254. (void)CloseHandle(hDevice);

  255.  
  256. return 0;

  257. }

  258.  
  259. /*

  260. 初始化磁盘,创建分区

  261. vDiskNo:磁盘序号,千万要避开系统盘,系统盘一般是0

  262. vPartNum:分区数,只要1个分区就可以了

  263. */

  264. DWORD CMDiskManager::CreateDisk(DWORD vDiskNo, WORD vPartNum)

  265. {

  266. printf("准备CreateDisk, vDiskNo=%d, vPartNum=%d \n", vDiskNo, vPartNum);

  267.  
  268. //第0块磁盘是系统盘,不能格式化掉!!!但不排除某些情况下新插入的移动硬盘会是第0块磁盘

  269. if (0 == vDiskNo){

  270. printf("第0块磁盘是系统盘,不能格式化掉\n");

  271. return 0;

  272. }

  273.  
  274. HANDLE hDevice; //硬盘句柄 handle to the drive to be examined

  275. BOOL result; //结果标志 results flag

  276. DWORD readed; // discard results

  277. DWORD ret;

  278. WORD i;

  279. char diskPath[256]; //磁盘内部路径

  280. DISK_GEOMETRY pdg;

  281. DWORD sectorSize; //扇区大小

  282. DWORD signature; //签名

  283. LARGE_INTEGER diskSize; //磁盘大小

  284. LARGE_INTEGER partSize; //分区大小

  285. BYTE actualPartNum; //实际上的分区数

  286.  
  287. DWORD layoutStructSize; //

  288. DRIVE_LAYOUT_INFORMATION_EX *dl; //磁盘分区信息

  289. CREATE_DISK newDisk; //创建磁盘(初始化?)

  290.  
  291. //生成磁盘内部路径

  292. sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);

  293.  
  294. actualPartNum = 4;

  295. if (vPartNum > actualPartNum)

  296. {

  297. printf("vPartNum > 4\n");

  298. return (WORD)-1;

  299. }

  300.  
  301. hDevice = CreateFile(

  302. diskPath,

  303. GENERIC_READ | GENERIC_WRITE,

  304. FILE_SHARE_READ | FILE_SHARE_WRITE,

  305. NULL, //default security attributes

  306. OPEN_EXISTING, // disposition

  307. 0, // file attributes

  308. NULL

  309. );

  310. if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

  311. {

  312. fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());

  313. return DWORD(-1);

  314. }

  315.  
  316. // Create primary partition MBR

  317. //创建主分区的MBR

  318. printf("创建主分区的MBR\n");

  319.  
  320. newDisk.PartitionStyle = PARTITION_STYLE_MBR;

  321. signature = (DWORD)time(0); // 原为time(NULL), get signature from current time

  322. newDisk.Mbr.Signature = signature;

  323.  
  324. result = DeviceIoControl(

  325. hDevice,

  326. IOCTL_DISK_CREATE_DISK,

  327. &newDisk,

  328. sizeof(CREATE_DISK),

  329. NULL,

  330. 0,

  331. &readed,

  332. NULL

  333. );

  334. if (!result)

  335. {

  336. fprintf(stderr, "IOCTL_DISK_CREATE_DISK Error: %ld\n", GetLastError());

  337. (void)CloseHandle(hDevice);

  338. return DWORD(-1);

  339. }

  340.  
  341. //fresh the partition table

  342. //刷新分区表

  343. printf("刷新分区表\n");

  344. result = DeviceIoControl(

  345. hDevice,

  346. IOCTL_DISK_UPDATE_PROPERTIES,

  347. NULL,

  348. 0,

  349. NULL,

  350. 0,

  351. &readed,

  352. NULL

  353. );

  354. if (!result)

  355. {

  356. fprintf(stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: %ld\n", GetLastError());

  357. (void)CloseHandle(hDevice);

  358. return DWORD(-1);

  359. }

  360.  
  361. //Now create the partitions

  362. //现在创建分区

  363. ret = GetDriveGeometry(vDiskNo, &pdg);

  364. if ((DWORD)-1 == ret)

  365. {

  366. return ret;

  367. }

  368.  
  369. //扇区大小

  370. sectorSize = pdg.BytesPerSector;

  371. diskSize.QuadPart = pdg.Cylinders.QuadPart * pdg.TracksPerCylinder *

  372. pdg.SectorsPerTrack * pdg.BytesPerSector; //calculate the disk size;

  373. partSize.QuadPart = diskSize.QuadPart / vPartNum;

  374.  
  375. //分区结构大小

  376. layoutStructSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + (actualPartNum - 1) * sizeof(PARTITION_INFORMATION_EX);

  377. dl = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(layoutStructSize);

  378. if (NULL == dl)

  379. {

  380. (void)CloseHandle(hDevice);

  381. return (WORD)-1;

  382. }

  383.  
  384. dl->PartitionStyle = (DWORD)PARTITION_STYLE_MBR;

  385. dl->PartitionCount = actualPartNum;

  386. dl->Mbr.Signature = signature;

  387.  
  388. //clear the unused partitions

  389. //清除未用的分区

  390. printf("清除未用的分区\n");

  391. for (i = 0; i < actualPartNum; i++){

  392. dl->PartitionEntry[i].RewritePartition = 1;

  393. dl->PartitionEntry[i].Mbr.PartitionType = PARTITION_ENTRY_UNUSED;

  394. }

  395.  
  396. //set the profile of the partitions

  397. for (i = 0; i < vPartNum; i++){

  398. dl->PartitionEntry[i].PartitionStyle = PARTITION_STYLE_MBR;

  399. dl->PartitionEntry[i].StartingOffset.QuadPart =

  400. (partSize.QuadPart * i) + ((LONGLONG)(pdg.SectorsPerTrack) * (LONGLONG)(pdg.BytesPerSector)); //32256

  401. dl->PartitionEntry[i].PartitionLength.QuadPart = partSize.QuadPart;

  402. dl->PartitionEntry[i].PartitionNumber = i + 1;

  403. dl->PartitionEntry[i].RewritePartition = TRUE;

  404. dl->PartitionEntry[i].Mbr.PartitionType = PARTITION_IFS;

  405. dl->PartitionEntry[i].Mbr.BootIndicator = FALSE;

  406. dl->PartitionEntry[i].Mbr.RecognizedPartition = TRUE;

  407. dl->PartitionEntry[i].Mbr.HiddenSectors =

  408. pdg.SectorsPerTrack + (DWORD)((partSize.QuadPart / sectorSize) * i);

  409. }

  410. //execute the layout

  411. result = DeviceIoControl(

  412. hDevice,

  413. IOCTL_DISK_SET_DRIVE_LAYOUT_EX,

  414. dl,

  415. layoutStructSize,

  416. NULL,

  417. 0,

  418. &readed,

  419. NULL

  420. );

  421. if (!result)

  422. {

  423. fprintf(stderr, "IOCTL_DISK_SET_DRIVE_LAYOUT_EX Error: %ld\n", GetLastError());

  424. free(dl);

  425. (void)CloseHandle(hDevice);

  426. return DWORD(-1);

  427. }

  428.  
  429. //fresh the partition table

  430. printf("刷新分区表\n");

  431. result = DeviceIoControl(

  432. hDevice,

  433. IOCTL_DISK_UPDATE_PROPERTIES,

  434. NULL,

  435. 0,

  436. NULL,

  437. 0,

  438. &readed,

  439. NULL

  440. );

  441. if (!result)

  442. {

  443. fprintf(stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: %ld\n", GetLastError());

  444. free(dl);

  445. (void)CloseHandle(hDevice);

  446. return DWORD(-1);

  447. }

  448.  
  449. free(dl);

  450. (void)CloseHandle(hDevice);

  451. printf("CreateDisk完成\n");

  452. Sleep(3000); //wait the operations take effect

  453. return 0;

  454. }

  455.  
  456.  
  457. //获取磁盘几何信息

  458. BOOL CMDiskManager::GetDriveGeometry(DWORD vDiskNo, DISK_GEOMETRY *pdg)

  459. {

  460. HANDLE hDevice; // handle to the drive to be examined

  461. BOOL bResult; // results flag

  462. DWORD junk; // discard results

  463.  
  464. char diskPath[256]; //磁盘内部路径

  465. sprintf_s(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);

  466.  
  467. hDevice = CreateFile(TEXT(diskPath), // drive

  468. 0, // no access to the drive

  469. FILE_SHARE_READ | // share mode

  470. FILE_SHARE_WRITE,

  471. NULL, // default security attributes

  472. OPEN_EXISTING, // disposition

  473. 0, // file attributes

  474. NULL); // do not copy file attributes

  475.  
  476. if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

  477. {

  478. return (FALSE);

  479. }

  480.  
  481. bResult = DeviceIoControl(hDevice, // device to be queried

  482. IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to perform

  483. NULL, 0, // no input buffer

  484. pdg, sizeof(*pdg), // output buffer

  485. &junk, // # bytes returned

  486. (LPOVERLAPPED)NULL); // synchronous I/O

  487.  
  488. CloseHandle(hDevice);

  489.  
  490. return (bResult);

  491. }

  492.  
  493.  
  494. /******************************************************************************

  495. * Function: delete the partition layout of the disk

  496. 删除磁盘分区信息(恢复出厂设置)

  497. * input: disk, disk name

  498. * output: N/A

  499. * return: Succeed, 0

  500. * Fail, -1

  501. ******************************************************************************/

  502. DWORD CMDiskManager::DestroyDisk(DWORD vDiskNo)

  503. {

  504. if (0 == vDiskNo){

  505. //系统盘是0号盘,为了安全,不能删除

  506. return 0;

  507. }

  508.  
  509. HANDLE hDevice; // handle to the drive to be examined

  510. BOOL result; // results flag

  511. DWORD readed; // discard results

  512. CHAR diskPath[256];

  513.  
  514. sprintf(diskPath, "\\\\.\\PhysicalDrive%d", vDiskNo);

  515.  
  516. hDevice = CreateFile(

  517. diskPath, // drive to open

  518. GENERIC_READ | GENERIC_WRITE, // access to the drive

  519. FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode

  520. NULL, // default security attributes

  521. OPEN_EXISTING, // disposition

  522. 0, // file attributes

  523. NULL // do not copy file attribute

  524. );

  525. if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

  526. {

  527. fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());

  528. return DWORD(-1);

  529. }

  530.  
  531. result = DeviceIoControl(

  532. hDevice, // handle to device

  533. IOCTL_DISK_DELETE_DRIVE_LAYOUT, // dwIoControlCode

  534. NULL, // lpInBuffer

  535. 0, // nInBufferSize

  536. NULL, // lpOutBuffer

  537. 0, // nOutBufferSize

  538. &readed, // number of bytes returned

  539. NULL // OVERLAPPED structure

  540. );

  541. if (!result)

  542. {

  543. //fprintf(stderr, "IOCTL_DISK_DELETE_DRIVE_LAYOUT Error: %ld\n", GetLastError());

  544. (void)CloseHandle(hDevice);

  545. return DWORD(-1);

  546. }

  547.  
  548. //fresh the partition table

  549. result = DeviceIoControl(

  550. hDevice,

  551. IOCTL_DISK_UPDATE_PROPERTIES,

  552. NULL,

  553. 0,

  554. NULL,

  555. 0,

  556. &readed,

  557. NULL

  558. );

  559. if (!result)

  560. {

  561. fprintf(stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: %ld\n", GetLastError());

  562. (void)CloseHandle(hDevice);

  563. return DWORD(-1);

  564. }

  565.  
  566. (void)CloseHandle(hDevice);

  567. return 0;

  568. }

  569.  
  570. /******************************************************************************

  571. * Function:快速格式化某个磁盘,文件系统NTFS,

  572. 如果在CreateDisk()创建磁盘后,磁盘的文件系统是RAW的话,才需要调用该函数

  573. * input: disk, disk name

  574. * output: N/A

  575. * return: Succeed, 0

  576. * Fail, 1

  577. ******************************************************************************/

  578. DWORD CMDiskManager::FormatVolume(CHAR letter)

  579. {

  580. DWORD ret;

  581. CHAR cmd[64];

  582. sprintf(cmd, "format %c: /FS:NTFS /Q /Y", letter);

  583. ret = (DWORD)system(cmd);

  584. return ret;

  585. }

  586.  
  587. //获取第dwNum个磁盘的信息

  588. void CMDiskManager::GetDiskInfo(DWORD &dwNum, CString chDriveInfo[])

  589. {

  590. DWORD DiskCount = 0;

  591.  
  592. //利用GetLogicalDrives()函数可以获取系统中逻辑驱动器的数量,函数返回的是一个32位无符号整型数据。

  593. DWORD DiskInfo = GetLogicalDrives();

  594.  
  595. //通过循环操作查看每一位数据是否为1,如果为1则磁盘为真,如果为0则磁盘不存在。

  596. while (DiskInfo)

  597. {

  598. //通过位运算的逻辑与操作,判断是否为1

  599. Sleep(10);

  600. if (DiskInfo & 1)

  601. {

  602. DiskCount++;

  603. }

  604. DiskInfo = DiskInfo >> 1;//通过位运算的右移操作保证每循环一次所检查的位置向右移动一位。*/

  605. }

  606.  
  607. if (dwNum < DiskCount)

  608. {

  609. return;//实际的磁盘数目大于dwNum

  610. }

  611. dwNum = DiskCount;//将磁盘分区数量保存

  612.  
  613.  
  614. //-------------------------------------------------------------------//

  615. //通过GetLogicalDriveStrings()函数获取所有驱动器字符串信息长度

  616. int DSLength = GetLogicalDriveStrings(0, NULL);

  617.  
  618. CHAR* DStr = new CHAR[DSLength];

  619. memset(DStr, 0, DSLength);

  620.  
  621. //通过GetLogicalDriveStrings将字符串信息复制到堆区数组中,其中保存了所有驱动器的信息。

  622. GetLogicalDriveStrings(DSLength, DStr);

  623.  
  624. int DType;

  625. int si = 0;

  626. BOOL fResult;

  627. unsigned _int64 i64FreeBytesToCaller;

  628. unsigned _int64 i64TotalBytes;

  629. unsigned _int64 i64FreeBytes;

  630.  
  631. //读取各驱动器信息,由于DStr内部数据格式是A:\NULLB:\NULLC:\NULL,所以DSLength/4可以获得具体大循环范围

  632. for (int i = 0; i<DSLength / 4; ++i)

  633. {

  634. Sleep(10);

  635. CString strdriver = DStr + i * 4;

  636. CString strTmp, strTotalBytes, strFreeBytes;

  637. DType = GetDriveType(strdriver);//GetDriveType函数,可以获取驱动器类型,参数为驱动器的根目录

  638. switch (DType)

  639. {

  640. case DRIVE_FIXED:

  641. {

  642. strTmp.Format(_T("本地磁盘"));

  643. }

  644. break;

  645. case DRIVE_CDROM:

  646. {

  647. strTmp.Format(_T("DVD驱动器"));

  648. }

  649. break;

  650. case DRIVE_REMOVABLE:

  651. {

  652. strTmp.Format(_T("可移动磁盘"));

  653. }

  654. break;

  655. case DRIVE_REMOTE:

  656. {

  657. strTmp.Format(_T("网络磁盘"));

  658. }

  659. break;

  660. case DRIVE_RAMDISK:

  661. {

  662. strTmp.Format(_T("虚拟RAM磁盘"));

  663. }

  664. break;

  665. case DRIVE_UNKNOWN:

  666. {

  667. strTmp.Format(_T("虚拟RAM未知设备"));

  668. }

  669. break;

  670. default:

  671. strTmp.Format(_T("未知设备"));

  672. break;

  673. }

  674.  
  675. //GetDiskFreeSpaceEx函数,可以获取驱动器磁盘的空间状态,函数返回的是个BOOL类型数据

  676. fResult = GetDiskFreeSpaceEx(strdriver,

  677. (PULARGE_INTEGER)&i64FreeBytesToCaller,

  678. (PULARGE_INTEGER)&i64TotalBytes,

  679. (PULARGE_INTEGER)&i64FreeBytes);

  680.  
  681. if (fResult)

  682. {

  683. strTotalBytes.Format(_T("磁盘总容量%.2fMB"), (float)i64TotalBytes / 1024 / 1024);

  684. strFreeBytes.Format(_T("磁盘剩余空间%.2fMB"), (float)i64FreeBytesToCaller / 1024 / 1024);

  685. }

  686. else

  687. {

  688. strTotalBytes.Format(_T(""));

  689. strFreeBytes.Format(_T(""));

  690. }

  691. chDriveInfo[i] = strTmp + _T("(") + strdriver + _T("):") + strTotalBytes + ", " +strFreeBytes;

  692. si += 4;

  693. }

  694. }

  695.  
  696.  
  697. /******************************************************************************

  698.  
  699. * Function: get disk's physical number from its drive letter

  700. 根据逻辑盘符找到物理硬盘号

  701.  
  702. * e.g. C-->0 (C: is on disk0)

  703.  
  704. * input: letter, drive letter

  705.  
  706. * output: N/A

  707.  
  708. * return: Succeed, disk number

  709.  
  710. * Fail, -1

  711.  
  712. ******************************************************************************/

  713.  
  714. //根据逻辑盘符找到物理硬盘号

  715. DWORD CMDiskManager::GetPhysicalDriveFromPartitionLetter(CHAR letter)

  716. {

  717. HANDLE hDevice; // handle to the drive to be examined

  718.  
  719. BOOL result; // results flag

  720.  
  721. DWORD readed; // discard results

  722.  
  723. STORAGE_DEVICE_NUMBER number; //use this to get disk numbers

  724.  
  725. CHAR path[256];

  726.  
  727. sprintf(path, "\\\\.\\%c:", letter);

  728.  
  729. hDevice = CreateFile(path, // drive to open

  730.  
  731. GENERIC_READ | GENERIC_WRITE, // access to the drive

  732.  
  733. FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode

  734.  
  735. NULL, // default security attributes

  736.  
  737. OPEN_EXISTING, // disposition

  738.  
  739. 0, // file attributes

  740.  
  741. NULL); // do not copy file attribute

  742.  
  743. if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

  744.  
  745. {

  746.  
  747. fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());

  748.  
  749. return DWORD(-1);

  750. }

  751.  
  752. result = DeviceIoControl(

  753.  
  754. hDevice, // handle to device

  755.  
  756. IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode

  757.  
  758. NULL, // lpInBuffer

  759.  
  760. 0, // nInBufferSize

  761.  
  762. &number, // output buffer

  763.  
  764. sizeof(number), // size of output buffer

  765.  
  766. &readed, // number of bytes returned

  767.  
  768. NULL // OVERLAPPED structure

  769.  
  770. );

  771.  
  772. if (!result) // fail

  773. {

  774.  
  775. fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: %ld\n", GetLastError());

  776.  
  777. (void)CloseHandle(hDevice);

  778.  
  779. return (DWORD)-1;

  780. }

  781.  
  782. //printf("%d %d %d\n\n", number.DeviceType, number.DeviceNumber, number.PartitionNumber);

  783.  
  784. (void)CloseHandle(hDevice);

  785.  
  786. return number.DeviceNumber;

  787.  
  788. }

  789.  
  790. /******************************************************************************

  791.  
  792. * Function: get disk's drive letters from physical number

  793. 获取一个物理硬盘上的所有盘符

  794. * e.g. 0-->{C, D, E} (disk0 has 3 drives, C:, D: and E:)

  795.  
  796. * input: vDiskNo, disk's physical number

  797.  
  798. * output: letters, letters array

  799.  
  800. * return: Succeed, the amount of letters

  801.  
  802. * Fail, -1

  803.  
  804. ******************************************************************************/

  805.  
  806. CString CMDiskManager::GetPartitionLetterFromPhysicalDrive(DWORD vDiskNo)

  807. {

  808. DWORD mask;

  809. DWORD driveType;

  810. DWORD bmLetters;

  811. DWORD diskNumber;

  812. CHAR path[256];

  813. CHAR letter;

  814. DWORD letterNum;

  815. WORD i;

  816. CHAR *p;

  817. CString tRet = "";

  818.  
  819. bmLetters = GetLogicalDrives();

  820.  
  821. if (0 == bmLetters)

  822. {

  823. return "";

  824. }

  825.  
  826. letterNum = 0;

  827.  
  828. for (i = 0; i < sizeof(DWORD) * 8; i++)

  829. {

  830. mask = 0x1u << i;

  831.  
  832. if ((mask & bmLetters) == 0) //get one letter

  833. {

  834. continue;

  835. }

  836.  
  837. letter = (CHAR)(0x41 + i); //ASCII change

  838.  
  839. sprintf(path, "%c:\\", letter);

  840.  
  841. driveType = GetDriveType(path);

  842.  
  843. if (driveType != DRIVE_FIXED)

  844. {

  845. bmLetters &= ~mask; //clear this bit

  846. continue;

  847. }

  848.  
  849. diskNumber = GetPhysicalDriveFromPartitionLetter(letter);

  850.  
  851. if (diskNumber != vDiskNo)

  852. {

  853. bmLetters &= ~mask; //clear this bit

  854.  
  855. continue;

  856. }

  857.  
  858. letterNum++;

  859. }

  860.  
  861. //build the result

  862.  
  863. /*letters = (CHAR *)malloc(letterNum);

  864.  
  865. if (NULL == *letters)

  866. {

  867. return (DWORD)-1;

  868. }

  869.  
  870. p = *letters;

  871. */

  872. CString s;

  873. for (i = 0; i < sizeof(DWORD) * 8; i++)

  874. {

  875. mask = 0x1u << i;

  876.  
  877. if ((mask & bmLetters) == 0)

  878. {

  879. continue;

  880. }

  881.  
  882. letter = (CHAR)(0x41 + i); //ASCII change

  883. s.Format("%c", letter);

  884. if (!tRet.IsEmpty()){

  885. tRet += ",";

  886. }

  887. tRet += s + ":";

  888.  
  889. }

  890.  
  891. return tRet;

  892. }


 

头文件:CMDiskManager.h

 
  1. #include <windows.h>

  2. #include <winioctl.h>

  3. #include <stdio.h>

  4. #include "time.h"

  5.  
  6. #include <stdlib.h>

  7. #include <tchar.h>

  8.  
  9. #pragma pack(1)

  10.  
  11. #define MAX_MBR_PARTITIONS 4

  12. #define MBR_DISK_SIGNATURE_OFFSET 440

  13. #define MBR_DISK_PPT_OFFSET 446

  14. #define MBR_SIGNATURE_OFFSET 510

  15.  
  16. //

  17. // MBR Partition Entry

  18. //

  19. typedef struct {

  20. UINT8 BootIndicator;

  21. UINT8 StartHead;

  22. UINT8 StartSector;

  23. UINT8 StartTrack;

  24. UINT8 OSType;

  25. UINT8 EndHead;

  26. UINT8 EndSector;

  27. UINT8 EndTrack;

  28. UINT32 StartingLBA;

  29. UINT32 SizeInLBA;

  30. } MBR_PARTITION_RECORD;

  31.  
  32. //

  33. // MBR Partition table

  34. //

  35. typedef struct {

  36. UINT8 BootCode[440];

  37. UINT32 UniqueMbrSignature;

  38. UINT16 Unknown;

  39. MBR_PARTITION_RECORD PartitionRecord[MAX_MBR_PARTITIONS];

  40. UINT16 Signature;

  41. } MASTER_BOOT_RECORD;

  42.  
  43. #pragma pack()

  44.  
  45. #define MBR_SIGNATURE 0xAA55

  46. #define EXTENDED_DOS_PARTITION 0x05

  47. #define EXTENDED_WINDOWS_PARTITION 0x0F

  48.  
  49.  
  50. class CMDiskManager {

  51.  
  52. public:

  53.  
  54. CMDiskManager();

  55.  
  56. //获取磁盘几何

  57. BOOL GetDriveGeometry(DWORD vDiskNo, DISK_GEOMETRY *pdg);

  58.  
  59. //获取磁盘大小,单位是MB

  60. int GetDiskSize(DWORD vDiskNo);

  61.  
  62. /*

  63. 获取磁盘分区信息

  64. vDiskNo:磁盘序号

  65. */

  66. DWORD GetLayoutInfo(DWORD vDiskNo);

  67.  
  68. //读MBR信息

  69. BOOL ReadMBR(int vDiskNo, LPVOID *pBuffer);

  70.  
  71. /*

  72. 获取磁盘分区个数

  73. vDiskNo:磁盘序号

  74. */

  75. int GetPartNum(DWORD vDiskNo);

  76.  
  77. /*

  78. 初始化磁盘,创建分区

  79. vDiskNo:磁盘序号,千万要避开系统盘,系统盘一般是0

  80. vPartNum:分区数,只要1个分区就可以了

  81. */

  82. DWORD CreateDisk(DWORD vDiskNo, WORD vPartNum);

  83.  
  84. /*

  85. 回复磁盘到空白状态,删除MBR分区信息

  86. */

  87. DWORD DestroyDisk(DWORD vDiskNo);

  88.  
  89. };


如果CreateDisk之后文件系统格式还是RAW的,那么可以用这个:

 
  1. /******************************************************************************

  2. * Function:快速格式化某个磁盘,文件系统NTFS

  3. * input: disk, disk name

  4. * output: N/A

  5. * return: Succeed, 0

  6. * Fail, 1

  7. ******************************************************************************/

  8. DWORD CMDiskManager::FormatVolume(CHAR letter)

  9. {

  10. DWORD ret;

  11. CHAR cmd[64];

  12. sprintf(cmd, "format %c: /FS:NTFS /Q /Y", letter);

  13. ret = (DWORD)system(cmd);

  14. return ret;

  15. }

猜你喜欢

转载自blog.csdn.net/ayang1986/article/details/81319508