您的位置:首页 > 其它

windows的磁盘操作之四——根据逻辑分区号获得物理磁盘号(转)

2013-10-25 11:45 471 查看
第一节中我们谈到了磁盘设备名称的两种形式:

对于物理驱动器x,形式为\\.\PhysicalDriveX,编号从0开始,例如

名称

含义

\\.\PhysicalDrive0

打开第一个物理驱动器

\\.\PhysicalDrive2

打开第三个物理驱动器

对于逻辑分区(卷),形式为\\.\X: ,例如

名称

含义

\\.\A:

打开A盘(软驱)

\\.\C:

打开C盘(磁盘逻辑分区)

那么如何找出物理驱动器号0,1,2…… 和逻辑分区号C, D, E……之间的关系呢?本节讨论通过逻辑分区号获取所在物理驱动器号的方法,下一节讨论通过物理驱动器号找出其所包含的逻辑分区号的方法。当然,必定会存在其他思路实现同样的功能,欢迎大家补充。

首先我们要明确,物理驱动器号和逻辑分区号应该是一对多的关系。例如disk0可能包含C, D, E三个分区。所以下面讨论的函数GetPhysicalDriveFromPartitionLetter返回一个单独的整型数。DeviceIoControl提供操作码IOCTL_STORAGE_GET_DEVICE_NUMBER,可以非常方便的获得打开设备的设备类型和设备号。

代码如下

/******************************************************************************

* 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 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[DISK_PATH_LEN];

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;

}

代码分析:

1. 根据分区号生成设备名称。

2. 调用CreateFile打开设备并获得设备句柄。

3. 调用操作码为IOCTL_STORAGE_GET_DEVICE_NUMBER的DeviceIoControl函数,输出为结构体变量STORAGE_DEVICE_NUMBER number。

结构体STORAGE_DEVICE_NUMBER定义为

typedef struct _STORAGE_DEVICE_NUMBER {

DEVICE_TYPE DeviceType;

ULONG DeviceNumber;

ULONG PartitionNumber;

} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;

其中DeviceNumber就是我们需要的物理磁盘号。

4. 返回DeviceNumber。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: