原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://cutebunny.blog.51cto.com/301216/624379
第一节中http://cutebunny.blog.51cto.com/301216/624027我们谈到了磁盘设备名称的两种形式:
对于物理驱动器
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
。
本文出自 “bunny技术坊” 博客,请务必保留此出处http://cutebunny.blog.51cto.com/301216/624379