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,我会更有动力更新文章嚯!)