IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> QT(C++)DeviceIoControl()函数的相关使用 -> 正文阅读

[C++知识库]QT(C++)DeviceIoControl()函数的相关使用

Microsoft官网中有这个函数的介绍,对,仅仅就是介绍,有时候官网的查询结果也就只能看看……

在我写过的一个软件中,我曾经多次使用该函数获取相关结果,现将我的使用经验分享给大家!


DeviceIoControl()函数将控制代码直接发送到指定的设备驱动,使相应的设备执行指定的操作。函数原型如下:

BOOL DeviceIoControl(
    HANDLE hDevice,               //设备句柄
    DWORD dwIoControlCode,        //欲执行操作类型
    LPVOID lpInBuffer,            //操作输入的数据缓冲区,不需要输入数据时可为NULL
    DWORD nInBufferSize,          //输入缓冲区的大小,不需要输入数据时可为0
    LPVOID lpOutBuffer,           //接收操作返回数据的缓冲区,没有数据输出时可为NULL
    DWORD nOutBufferSize,         //接收缓冲区的大小,没有数据输出时可为0
    LPDWORD lpBytesReturned,      //实际返回数据的大小,没有数据输出时可为NULL
    LPOVERLAPPER lpOverlapped     //忽略此项,直接设置成NULL
);

返回值非0表示函数使用成功;0表示失败,失败信息可以通过GetLastError()函数获得。


(1)对非系统盘加锁、解锁

DeviceIoControl(file, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, NULL, NULL);

DeviceIoControl(file, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, NULL, NULL);

//这里的非系统盘指的是U盘,系统盘加锁是不会成功的,因为操作系统本身时刻都对系统盘有操作。

//file如果是驱动器句柄,那么就是将整个驱动器锁起来;如果是驱动器的某个分盘句柄,则将这个分盘锁起来。

(2)获取磁盘所在的物理驱动器号

string PhysicalDrive = "\\\\.\\PhysicalDrive";        

STORAGE_DEVICE_NUMBER Number;

DeviceIoControl(file, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &Number, sizeof(Number), NULL, (LPOVERLAPPED)NULL);

PhysicalDrive += to_string(Number.DeviceNumber);  

//这里使用PhysicalDrive是为了后续方便直接获取驱动器句柄,获取驱动器句柄的CreateFile()函数中的第一个参数便是类似 \\.\PhysicalDrive0 的参数
//详情可以查阅Microsoft官网CreateFile关于物理驱动器句柄的获取

//file为磁盘句柄

//Number的DeviceNumber返回的便是当前磁盘所在的驱动器号

(3)获取磁盘总字节数

GET_LENGTH_INFORMATION available;

DeviceIoControl(file, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &available, sizeof(available), 0, NULL);

UINT64 DiskSize = available.Length.QuadPart;

//file为磁盘(驱动器)句柄,获取对应类别的总字节数

//DiskSize则为磁盘总字节数

//为什么会使用这种方法获取磁盘总字节数呢?
//使用过DiskGenius的朋友会发现 柱面数 × 磁道数 × 扇区数 × 每扇区字节数 != 磁盘总字节数
//这是因为有多余的字节数并不能凑够一个柱面,所以通过正常的获取磁头数等信息并不能正确获取总字节数

//获取了总字节数后,便可以通过(4)的函数获取每个扇区的字节数,从而计算整个磁盘的扇区总数

(4)获取磁盘的磁头数、柱面数、扇区数、每扇区字节数

DISK_GEOMETRY pdg;

DeviceIoControl(DiskHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &pdg, sizeof(pdg), NULL, (LPOVERLAPPED)NULL);


//DiskHandle可以为磁盘句柄、驱动器句柄,则此函数获取对应的数据

//pdg.Cylinders.QuadPart为柱面数
//pdg.TracksPerCylinder为每个柱面磁道数
//pdg.SectorsPerTrack为每个磁道扇区数
//pdg.BytesPerSector为每个扇区的字节数

//用此方法得出的 柱面数 × 磁道数 × 扇区数 × 每扇区字节数 = 总字节数,一般研究这种情况下的数据
//特殊情况区别对待
//此时的总字节数会比实际字节数少,实际字节数可以用(3)的方法获取
//此方法主要是获取磁盘(驱动器)的标准数据

//实际总扇区数 = (3)获取的总字节数 / 每扇区字节数

在我写过的软件中,这四种方法都使用过,读者可以根据需要复制代码,请仔细理解每个方法中的注释内容!

最后,有帮助的话可以给我一丢丢赞赏嚯!(记得备注CSDN,我会更有动力更新文章嚯!)

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章           查看所有文章
加:2022-05-21 18:44:48  更:2022-05-21 18:47:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年3日历 -2024/3/28 19:54:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码