11.9 实现磁盘相关操作

2023-11-21 07:15
文章标签 实现 操作 相关 磁盘 11.9

本文主要是介绍11.9 实现磁盘相关操作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

11.9.1 遍历磁盘容量

如下代码实现了在Windows系统中获取所有磁盘驱动器的信息。具体包括两个函数,一个用于获取驱动器类型,另一个用于获取驱动器空间信息。主函数则调用这两个函数来遍历所有逻辑驱动器并输出相应的信息。在输出驱动器空间信息时,会输出该驱动器的总大小、已用空间以及可用空间。

#include <stdio.h>
#include <Windows.h>void GetDrivesType(const char* lpRootPathName)
{UINT uDriverType = GetDriveType(lpRootPathName);switch (uDriverType){case DRIVE_UNKNOWN:puts("未知磁盘"); break;case DRIVE_NO_ROOT_DIR: puts("路径无效"); break;case DRIVE_REMOVABLE: puts("可移动磁盘"); break;case DRIVE_FIXED: puts("固定磁盘"); break;case DRIVE_REMOTE: puts("网络磁盘"); break;case DRIVE_CDROM: puts("光驱"); break;case DRIVE_RAMDISK: puts("内存映射盘"); break;default: break;}
}void GetDrivesFreeSpace(const char* lpRootPathName)
{unsigned long long available, total, free;if (GetDiskFreeSpaceEx(lpRootPathName, (ULARGE_INTEGER*)&available, (ULARGE_INTEGER*)&total, (ULARGE_INTEGER*)&free)){printf("磁盘: %s | 总计: %lld MB 已用: %lld MB 剩余: %lld MB \n",lpRootPathName, total >> 20, available >> 20, free >> 20);}
}int main(int argc,char *argv[])
{DWORD dwSize = MAX_PATH;char szLogicalDrives[MAX_PATH] = {0};// 获取逻辑驱动器号字符串DWORD dwResult = GetLogicalDriveStringsA(dwSize, szLogicalDrives);if (dwResult > 0 && dwResult <= MAX_PATH){// 从缓冲区起始地址开始char* szSingleDrive = szLogicalDrives;while (*szSingleDrive) {//printf("Drive: %s\n", szSingleDrive);      // 输出单个驱动器的驱动器号// GetDrivesType(szSingleDrive);GetDrivesFreeSpace(szSingleDrive);// 获取下一个驱动器地址szSingleDrive += strlen(szSingleDrive) + 1;}}system("pause");return 0;
}

11.9.2 遍历盘符并存储

循环遍历盘符分区,并将所有盘符结构存储到std::vector<MyDriver>定义的容器中.

#include <windows.h>
#include <iostream>
#include <vector>
#include <string>// 将字节转换为GB单位显示的宏定义
#define ToGB(x) (x.HighPart << 2) + (x.LowPart >> 20) / 1024.0// 定义基础结构
typedef struct
{double available_space;double free_space;double total_space;
}DriverInfo;// 定义完整结构
typedef struct
{char driver_name[128];char driver_type[128];double available_space;double free_space;double total_space;
}MyDriver;using namespace std;// 获取驱动器数量
int GutDrivesCount()
{DWORD drivers;int count = 0;//获取驱动器数drivers = GetLogicalDrives();while (drivers != 0){if (drivers & 1 != 0){count++;}drivers >>= 1;}return count;
}// 获取驱动器类型
std::string GetDrivesType(const char* lpRootPathName)
{UINT uDriverType = GetDriveType(lpRootPathName);switch (uDriverType){case DRIVE_UNKNOWN:return "未知类型"; break;case DRIVE_NO_ROOT_DIR:return "路径无效"; break;case DRIVE_REMOVABLE:return "可移动磁盘"; break;case DRIVE_FIXED:return "固定磁盘"; break;case DRIVE_REMOTE:return "网络磁盘"; break;case DRIVE_CDROM:return "光驱设备"; break;case DRIVE_RAMDISK:return "内存映射盘"; break;default:break;}return "错误参数";
}// 获取盘符容量
DriverInfo GetDrivesFreeSpace(const char* lpRootPathName)
{// ULARGE_INTEGER 64位无符号整型值ULARGE_INTEGER available, total, free;DriverInfo ref;// 获取分区数据并返回DriversInfo结构体if (GetDiskFreeSpaceEx(lpRootPathName, (ULARGE_INTEGER*)&available, (ULARGE_INTEGER*)&total, (ULARGE_INTEGER*)&free)){ref.total_space = ToGB(total);ref.free_space = ToGB(available);ref.available_space = ref.total_space - ref.free_space;}return ref;
}std::vector<MyDriver> GetDriveForVector()
{DWORD count = GutDrivesCount();std::cout << "驱动器个数: " << count << std::endl;DWORD dwSize = MAX_PATH;char szLogicalDrives[MAX_PATH] = { 0 };// 获取逻辑驱动器号字符串DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives);// 处理获取到的结果if (dwResult > 0 && dwResult <= MAX_PATH){// 定义两个结构, MyDriver 临时存储单个结构,ref存储所有磁盘的容器MyDriver my_driver_ptr;std::vector<MyDriver> ref;// 从缓冲区起始地址开始char* szSingleDrive = szLogicalDrives;while (*szSingleDrive){// 逻辑驱动器类型std::string type = GetDrivesType(szSingleDrive);// 获取磁盘空间信息并存入 DriverInfo 结构DriverInfo ptr;ptr = GetDrivesFreeSpace(szSingleDrive);// 填充结构数据strcpy(my_driver_ptr.driver_name, szSingleDrive);strcpy(my_driver_ptr.driver_type, type.c_str());my_driver_ptr.total_space = ptr.total_space;my_driver_ptr.free_space = ptr.free_space;my_driver_ptr.available_space = ptr.available_space;// 加入到容器中ref.push_back(my_driver_ptr);/*std::cout<< "盘符: " << szSingleDrive<< " 类型: " << type<< " 总容量: " << ptr.total_space<< " 可用空间: " << ptr.free_space<< " 已使用: " << ptr.available_space<< std::endl;*/// 获取下一个驱动器号起始地址szSingleDrive += strlen(szSingleDrive) + 1;}return ref;}
}int main(int argc,char *argv[])
{std::vector<MyDriver> ptr = GetDriveForVector();// 循环输出vector容器for (int x = 0; x < ptr.size(); x++){std::cout<< "盘符: " << ptr[x].driver_name<< " 类型: " << ptr[x].driver_type<< " 总容量: " << ptr[x].total_space<< " 可用空间: " << ptr[x].free_space<< " 已使用: " << ptr[x].available_space<< std::endl;}std::system("pause");return 0;
}

11.9.3 实现磁盘格式化

如下代码定义了一个函数FormatDisk,用于格式化由指定为字符串的驱动器号标识的磁盘。该函数使用Shell2.dll模块中的SHFormatDrive()这个未导出函数实现对特定磁盘的格式化。

FormatDisk函数采用std::string参数strDisk,该参数指定要格式化的磁盘的驱动器号。该函数首先使用LoadLibraryA加载Shell32.dll库,然后使用GetProcAddress检索SHFormatDrive函数的地址。使用控制台应用程序的窗口句柄、要格式化的磁盘的驱动器ID(根据驱动器号计算)以及指定格式选项的标志来调用SHFormatDrive函数。

#include <iostream>
#include <string>
#include <Windows.h>
#include <ShlObj.h>#pragma comment(lib, "Shell32.lib")// 格式化磁盘
void FormatDisk(std::string strDisk)
{HINSTANCE hInstance = ::LoadLibraryA("Shell32.dll");if (NULL == hInstance){return;}typedef DWORD(*PSHFORMATDRIVE)(HWND, UINT, UINT, UINT);PSHFORMATDRIVE SHFormatDrive = (PSHFORMATDRIVE)::GetProcAddress(hInstance, "SHFormatDrive");if (NULL == SHFormatDrive){return;}UINT uiID = strDisk[0] - 'A';// 获取控制台程序窗口句柄HWND hWnd = ::GetConsoleWindow();SHFormatDrive((HWND)hWnd, uiID, 0xFFFF, 0x0001);::FreeLibrary(hInstance);
}int main(int argc, char* argv[])
{// 传入磁盘FormatDisk("D");return 0;
}

11.9.4 移除指定磁盘

如下代码演示了如何通过 Windows API 移除指定的磁盘驱动器,包括移除盘符和卸载卷加载点。代码首先定义了一个 DeleteVolume 函数,接收一个指向字符串的指针,表示要删除的磁盘驱动器的盘符。然后,函数将盘符转换为设备名称,使用 DefineDosDeviceA 函数将其从系统中移除。接着,函数使用 DeleteVolumeMountPointA 函数删除卷加载点。最后,main 函数调用 DeleteVolume 函数四次,移除了 C:、D:、E:、F: 四个磁盘驱动器。

#include <iostream>
#include <Windows.h>// 移除指定盘符
BOOL DeleteVolume(char* lpszDriver)
{// 将盘符和Dos设备路径移除char szDeviceName[MAX_PATH] = { 0 };strcpy(szDeviceName, lpszDriver);szDeviceName[2] = '\0';if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION, szDeviceName, NULL)){return FALSE;}// 卸载卷加载点if (!DeleteVolumeMountPointA(lpszDriver)){return FALSE;}return TRUE;
}int main(int argc, char *argv[])
{DeleteVolume((char*)"C:");DeleteVolume((char *)"D:");DeleteVolume((char*)"E:");DeleteVolume((char*)"F:");return 0;
}

11.9.5 输出磁盘分区表

如下代码,用于读取和分析Windows系统上第一个物理硬盘的主引导记录MBR。代码中定义了几个数据结构来表示MBR及其组件,包括引导记录、磁盘分区表和磁盘签名,ShowMbr使用ReadFile函数从硬盘读取MBR数据,然后以十六进制格式逐字节打印MBR数据。AnalysMbr函数提取并分析MBR数据,打印出引导记录、磁盘签名和分区表信息。

主函数中使用CreateFileA打开第一个物理硬盘,使用ShowMbr函数读取MBR数据,使用AnalystMbr函数分析MBR数据,然后使用CloseHandle函数关闭文件句柄,此段代码读者在编译时需采用64位模式编译。

#include <iostream>
#include <Windows.h>// 定义数据结构体
#define BOOTRECORDSIZE 440
typedef struct _BOOTRECORD
{unsigned char BootRecore[BOOTRECORDSIZE];
}BOOTRECORD, * PBOOTRECORD;#define DPTSIZE 64
typedef struct _DPT
{unsigned char Dpt[DPTSIZE];
}DPT, * PDPT;#define DPTNUMBER 4
typedef struct _DP
{unsigned char BootSign;     // 引导标志unsigned char StartHsc[3];unsigned char PatitionType;   // 分区类型unsigned char EndHsc[3];ULONG SectorsPreceding;     // 本分去之前使用的扇区数ULONG SectorsInPatition;    // 分区的总扇区数
}DP, * PDP;typedef struct _MBR
{BOOTRECORD BootRecord;      // 引导程序unsigned char ulSigned[4];    // windows磁盘签名unsigned char sReserve[2];    // 保留位DPT Dpt;            // 分区表unsigned char EndSign[2];   // 结束标志
}MBR, * PMBR;void ShowMbr(HANDLE hFile, PMBR pMbr)
{DWORD dwTemp = 0;::ReadFile(hFile, (LPVOID)pMbr, sizeof(MBR), &dwTemp, NULL);for (int i = 0; i < 512; i++){printf("%2x ", ((BYTE*)pMbr)[i]);if (0 == ((i + 1) % 16)){printf("\r\n");}else if (0 == ((i + 1) % 8)){printf("   ");}}
}void AnalysMbr(MBR Mbr)
{printf("\r\n引导记录:\r\n");for (int i = 0; i < BOOTRECORDSIZE; i++){printf("%2x ", Mbr.BootRecord.BootRecore[i]);if (0 == ((i + 1) % 16)){printf("\r\n");}else if (0 == ((i + 1) % 8)){printf("   ");}}printf("\r\n磁盘签名:\r\n");for (int i = 0; i < 4; i++){printf("%02x ", Mbr.ulSigned[i]);}printf("\r\n解析分区表:\r\n");for (int i = 0; i < DPTSIZE; i++){printf("%02x ", Mbr.Dpt.Dpt[i]);if (0 == ((i + 1) % 16)){printf("\r\n");}else if (0 == ((i + 1) % 8)){printf("   ");}}printf("\r\n");PDP pDp = (PDP) & (Mbr.Dpt.Dpt);for (int i = 0; i < DPTNUMBER; i++){printf("引导标识:%02x ", pDp[i].BootSign);printf("分区类型:%02x ", pDp[i].PatitionType);printf("\r\n");printf("本分区之前扇区数:%d ", pDp[i].SectorsPreceding);printf("本分区的总扇区数:%d", pDp[i].SectorsInPatition);printf("\r\n");printf("该分区的大小:%f\r\n", (double)pDp[i].SectorsInPatition / 1024 / 1024 * 512 / 1024 / 1024);printf("\r\n");}printf("结束标志:\r\n");for (int i = 0; i < 2; i++){printf("%02x ", Mbr.EndSign[i]);}printf("\r\n");
}int main(int argc, char* argv[])
{// 打开物理硬盘设备HANDLE hFile = ::CreateFileA("\\\\.\\PhysicalDrive0",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL);if (INVALID_HANDLE_VALUE == hFile){return -1;}MBR Mbr = { 0 };ShowMbr(hFile, &Mbr);AnalysMbr(Mbr);CloseHandle(hFile);return 0;
}

这篇关于11.9 实现磁盘相关操作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/400715

相关文章

Flutter实现文字镂空效果的详细步骤

《Flutter实现文字镂空效果的详细步骤》:本文主要介绍如何使用Flutter实现文字镂空效果,包括创建基础应用结构、实现自定义绘制器、构建UI界面以及实现颜色选择按钮等步骤,并详细解析了混合模... 目录引言实现原理开始实现步骤1:创建基础应用结构步骤2:创建主屏幕步骤3:实现自定义绘制器步骤4:构建U

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

Git可视化管理工具(SourceTree)使用操作大全经典

《Git可视化管理工具(SourceTree)使用操作大全经典》本文详细介绍了SourceTree作为Git可视化管理工具的常用操作,包括连接远程仓库、添加SSH密钥、克隆仓库、设置默认项目目录、代码... 目录前言:连接Gitee or github,获取代码:在SourceTree中添加SSH密钥:Cl

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B