第一节中我们谈到了磁盘设备名称的两种形式:

对于物理驱动器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。

windows的磁盘操作之四——根据逻辑分区号获得物理磁盘号(转)的更多相关文章

  1. c++windows内核编程笔记day12 硬盘逻辑分区管理、文件管理、内存管理

    windows系统磁盘文件存储: 分区格式:NTFS / FAT32 GetSystemDirectory();//获取系统路径 GetWindowsDirectory();//获取windows路径 ...

  2. [CentOS7] [VMWARE] 增加磁盘空间后扩大逻辑分区

    Learn to rescan disk in Linux VM when its backed vdisk in vmware is extended. This method does not r ...

  3. win7下将主分区转换成逻辑分区

    在了解怎么转换之前,先搞清楚主分区,扩展分区,逻辑分区的基本概念. 主分区,也称为主磁盘分区,和扩展分区.逻辑分区一样,是一种分区类型.主分区中不能再划分其他类型的分区,因此每个主分区都相当于一个逻辑 ...

  4. Linux主分区,扩展分区,逻辑分区的联系和区别

    主分区,也称为主磁盘分区,和扩展分区.逻辑分区一样,是一种分区类型.主分区中不能再划分其他类型的分区,因此每个主分区都相当于一个逻辑磁盘(在这一点上主分区和逻辑分区很相似,但主分区是直接在硬盘上划分的 ...

  5. linu逻辑分区动态调整大小

    注意: 这个动态调整的方法是有丢数据风险的,要确保调整的源分区没有使用或者使用率很低.源分区中如果有重要的文件最好先备份 在centos 6.5上操作过 lvdisplay 查看已有的分区的大小 lv ...

  6. win7/win10 未分配磁盘怎样创建扩展分区 也就是逻辑分区(转截)

    我们有时候用windows7的磁盘管理工具对windows7系统分区管理的时候,我们可能会不小心把我们的电脑硬盘扩展分区都删除了,扩展分区变为了未分配的空间,这时候如果我们新建分区的话,建立的都是主分 ...

  7. windows的磁盘操作之七——获取当前所有的物理磁盘号 加备注

     windows的磁盘操作之七--获取当前所有的物理磁盘号 2011-07-28 17:47:56 标签:windows API DeviceIoControl 物理磁盘 驱动器号 原创作品,允许转载 ...

  8. 管理员技术(六): 硬盘分区及格式化、 新建一个逻辑卷、调整现有磁盘的分区、扩展逻辑卷的大小、添加一个swap分区

    一.硬盘分区及格式化 问题: 本例要求熟悉硬盘分区结构,使用fdisk分区工具在磁盘 /dev/vdb 上按以下要求建立分区: 1> 采用默认的 msdos 分区模式        2> ...

  9. linux 系统磁盘管理(主分区和逻辑分区)

    摘要:linux系统磁盘管理主分区和逻辑分区 1.linux系统分区应了解的常识 硬盘分区实质上是对硬盘的一种格式化,然后才能使用硬盘保存各种信息,在创建分区时,就已经设置好了硬盘的各项物理参数,指定 ...

随机推荐

  1. 设计模式-装饰者模式(Decorator Pattern)

    本文由@呆代待殆原创,转载请注明出处. 此设计模式遵循的设计原则之一:类应该支持扩展,而拒绝修改(Open-Closed Principle) 装饰者模式简述 装饰者模式通过组合的方式扩展对象的特性, ...

  2. Android View事件分发-从源码分析

    View事件分发-从源码分析 学习自 <Android开发艺术探索> https://blog.csdn.net/qian520ao/article/details/78555397?lo ...

  3. Tecnomatix Process Designer & Process Simulate用法

    1. 删除项目 在AdminConsole->Project Action中,点击Delete project即可.

  4. Good Bye 2016 F.New Year and Finding Roots(交互)

    题目链接 \(Description\) 有一棵高度为\(h\)的满二叉树,点从\(1\)到\(2^h-1\)编号(无序).每次你可以询问一个点的编号,交互库会返回其所有邻接点的编号.你需要在\(16 ...

  5. C语言sscanf和sprintf输入输出使用及Strlen、Memset解释

    sscanf() - 从一个字符串中读进与指定格式相符的数据.   swscanf()- 用于处理宽字符字符串,和sscanf功能相同    通过学习和使用个人认为,在字符串格式不是很复杂,但是也并不 ...

  6. bzoj 2809 可并堆维护子树信息

    对于每个节点,要在其子树中选尽量多的节点,并且节点的权值和小于一个定值. 建立大根堆,每个节点从儿子节点合并,并弹出最大值直到和满足要求. /***************************** ...

  7. Android WebView加载Html右边空白问题的解决方案

    用WebView显示Html时,右边会出现一条空白区,如下图所示: 最开始的时候,认为是网页本身的空白. 后来发现网页本身无问题,且这个空白区是跟Scroll Bar 的位置和粗细比较相符,于是去控制 ...

  8. Programming 2D Games 读书笔记(第四章)

      示例一:Game Engine Part 1 更加完善游戏的基本流程 Graphics添加了以下几个方法,beginScene和endScene提高绘图,showBackbuffer去掉了clea ...

  9. oracle dba

    http://www.oracleblog.org/category/study-note/ https://jonathanlewis.wordpress.com/ http://www.julia ...

  10. C++ 实践总结

     对于一个应用程序而言,静态链接库可能被载入多次,而动态链接库仅仅会被载入一次. Gameloft面试之错误一 Event: 面试官说例如以下程序是能够链接通过的. class Base { Pu ...