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

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值