下文转载自http://blog.51cto.com/cutebunny/624567
本节讨论与上一节相反的操作,根据物理驱动器号获取该磁盘上的所有分区号。DeviceIoControl函数并没有提供操作码来直接完成此操作,所以需要稍微绕个圈子来实现这项功能。
大体思路为,先通过
GetLogicalDrives
函数获得系统中所有分区号,然后过滤掉非硬盘分区(例如软驱、光驱),再过滤掉不属于指定物理磁盘的分区,最后剩下的就是我们所需要的分区号了。
代码如下
/******************************************************************************* Function: get disk's drive letters from physical number* e.g. 0-->{C, D, E} (disk0 has 3 drives, C:, D: and E:)* input: phyDriveNumber, disk's physical number* output: letters, letters array* return: Succeed, the amount of letters* Fail, -1******************************************************************************/DWORD GetPartitionLetterFromPhysicalDrive(DWORD phyDriveNumber, CHAR **letters){DWORD mask;DWORD driveType;DWORD bmLetters;DWORD diskNumber;CHAR path[DISK_PATH_LEN];CHAR letter;DWORD letterNum;WORD i;CHAR *p;bmLetters = GetLogicalDrives();if (0 == bmLetters){return (DWORD)-1;}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 != phyDriveNumber){bmLetters &= ~mask; //clear this bitcontinue;}letterNum++;}//build the result*letters = (CHAR *)malloc(letterNum);if (NULL == *letters){return (DWORD)-1;}p = *letters;for (i = 0; i < sizeof(DWORD) * 8; i++){mask = 0x1u << i;if ((mask & bmLetters) == 0){continue;}letter = (CHAR)(0x41 + i); //ASCII change*p = letter;p++;}return letterNum;}
代码分析
函数输入参数
DWORD phyDriveNumber
为物理磁盘号,例如0
,1
,2
……。
函数输出参数
CHAR **letters
为获得的逻辑分区号数组指针。由于一块物理盘上可能有多个分区,所以用数组存放求得的多个分区号。
函数返回值为分区数量。
1.
调用函数
GetLogicalDrives
获得所有分区号。注意函数
GetLogicalDrives
返回值为位图形时,例如第0
位代表A:
,第2
位代表C:
等等。
2.
对获得的逻辑分区逐个检测。
调用函数
GetDriveType
获得分区类型,如果类型不为硬盘(driveType != DRIVE_FIXED)
,将此位清0
。
调用函数
GetPhysicalDriveFromPartitionLetter
(详见第四节http://cutebunny.blog.51cto.com/301216/624379)查询该逻辑分区所属的物理分区号,如果不为
phyDriveNumber
,将此位清0
。
经过上两项条件过滤后的位图存储了我们所需的逻辑分区号。
3.
为*letters
分配空间,并将位图转换为盘符字母存储在数组中。