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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/153601.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git reset hard,mixed,soft

首先&#xff0c;我们得了解git reset命令的形式之一&#xff1a; git reset [<mode>] [<commit>] 此命令的作用是恢复HEAD分支到<commit>位置&#xff0c;并根据<mode>决定是否恢复index file和working tree。恢复是指将staging area和working tree…

c语言遇到的常见问题及解决方案

在C语言编程中&#xff0c;可能会遇到一些问题&#xff0c;以下是一些常见问题和解决方案&#xff1a; 问题1&#xff1a;变量数据类型交换后未得到预期结果 原因&#xff1a;在scanf("%c",&name);中的%c前面缺少一个空格。 解决方案&#xff1a;在%c前面加上…

数据处理生产环境_spark获取df列当前日期的前一天日期

需求描述&#xff1a; 我现在有一个dataframe,名为dfin,样例数据如下 a1_id_lxha2_PHtime比亚迪_汉1232023-11-15 12:12:23比亚迪_汉1252023-11-15 13:14:51比亚迪_汉1232023-11-15 12:13:23比亚迪_汉1262023-11-16 14:12:34比亚迪_秦2312023-11-15 14:12:28比亚迪_秦2342023…

在线客服系统源码 聊天记录实时保存 附带完整的搭建教程

在线客服系统是一个企业网站进行网络营销的最重要的工具。企业进行网络宣传后&#xff0c;会有很多访客进入到网站&#xff0c;这时候网站就需要有在线客服人员进行接待&#xff0c;及时的与访客进行沟通&#xff0c;才能留住访客&#xff0c;变流量为销量。 在线客服系统可以…

Windows本地搭建rtmp推流服务

前言 开发时偶尔需要使用rtmp直播流做视频流测试&#xff0c;苦于网上开源的rtmp视频流都已经失效&#xff0c;无奈只好尝试在本地自己搭建一个rtmp的推流服务&#xff0c;方便测试使用。 一、工具准备 Nginx&#xff1a;使用nginx-rtmp-win64推流工具FFmpeg&#xff1a;官方…

网络安全涉及哪些方面?

1.系统安全&#xff1a;运行系统安全即保证信息处理和传输系统的安全。它侧重于保证系统正常运行&#xff0c;避免因为系统的损坏而对系统存储、处理和传输的消息造成破坏和损失&#xff0c;避免由于电磁泄露&#xff0c;产生信息泄露&#xff0c;干扰他人或受他人干扰。 2. 网…

[汇编实操]DOSBox工具: unable to open input file: 文件名.asm问题解决

出错原因1 &#xff1a;将文件放在debug文件下&#xff0c;mount后发现并没有该文件 解决方案 &#xff1a;重启DOSBox&#xff0c;重新mount&#xff0c;直到dir后可以看到该asm文件 出错原因2&#xff1a;DOS系统不支持8位以上的文件名 解决方案 &#xff1a;将文件名改为8…

【Linux】 线程

pthread_join: 获取线程返回值 #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <string.h>/*** 测试 pthread_join* 阻塞等待一个子线程的退出&#xff0c;可以接收到某一个子线程调用pthread_ex…

ISP概念入门

这里写自定义目录标题 引言ISP的处理流程1、Sensor有暗电流2、通过镜头到达Sensor中间的光多于到达Sensor的边缘的光&#xff0c;即光学系统中的渐晕3、Senor上有的像素点的输出有坏点4、Cmos的Sensor采用了Bayer色彩滤波阵列(Bayer Color Filter Array&#xff0c;CFA)5、Seno…

西米支付”:在游戏SDK中,提供了哪些支付渠道?SDK的用处?

在游戏SDK中&#xff0c;提供了哪些支付渠道&#xff1f; 常见的支付方式包括支付宝、微信支付、银联支付等。游戏SDK的支付功能可以方便玩家选择不同的支付渠道&#xff0c;以满足他们个性化的支付需求。 流行的支付应用&#xff1a;该应用集成了流行的支付应用支付接口&#…

大数据平台红蓝对抗 - 磨利刃,淬精兵! | 京东云技术团队

一、背景 目前大促备战常见备战工作&#xff1a;专项压测&#xff08;全链路压测、内部压测&#xff09;、灾备演练、降级演练、限流、巡检&#xff08;监控、应用健康度&#xff09;、混沌演练&#xff08;红蓝对抗&#xff09;&#xff0c;如下图所示。随着平台业务越来越复…

数据预处理方法

数据预处理是为了保证数据质量。数据预处理包括&#xff1a;数据清理&#xff0c;数据集成&#xff0c;数据转换&#xff0c;数据归约&#xff08;最大限度精简数据量&#xff09;。比如&#xff1a;缺失数据处理是去掉&#xff0c;还是填充默认值或最近的值。 数据的预处理也…

AirPods跳转下一首歌的操作方法,“代”数不同,方法也不同

在这么小的包装中&#xff0c;科技含量如此之高&#xff0c;真是令人惊讶。AirPods的神奇之处在于苹果获得专利的H1芯片。除了光学传感器和运动加速度计&#xff0c;它还允许你使用触摸控制来启动、停止或跳过歌曲。继续阅读&#xff0c;了解如何跳转AirPods、AirPods 2、AirPo…

如何将力控与PLC之间有线以太网通讯改无线?

在实际系统中&#xff0c;车间里分布多台PLC&#xff0c;需要用上位机软件集中控制。通常所有设备距离在几十米到上百米不等。用户会选择以太网方式是因为传输速度有保障&#xff0c;而选择无线以太网方案是因为不想开挖电缆沟&#xff0c;或者布线不方便&#xff0c;不但施工麻…

Python 和 Ruby 谁是最好的Web开发语言?

Python 和 Ruby 都是目前用来开发 websites、web-based apps 和 web services 的流行编程语言之一。 【这个时候又人要说PHP是世界上最好的语言了】 我就不说PHP 最好的方法 VS 以人为本的语言 社区: 稳定与创新 尽管特性和编程哲学是选择一个语言的首要驱动因素&#xff0c…

印刷企业实施MES管理系统需要哪些硬件设施

随着科技的飞速发展&#xff0c;印刷行业正面临着前所未有的挑战和机遇。为了提高生产效率&#xff0c;降低成本&#xff0c;并增强市场竞争力&#xff0c;越来越多的印刷企业开始实施制造执行系统&#xff08;MES&#xff09;管理系统。本文将重点讨论印刷企业在实施MES管理系…

【点云上采样】基于移动最小二乘(MLS)的上采样

文章目录 声明简介代码参考 声明 示例结果比较奇怪&#xff0c;可能是参数没调好&#xff0c;如有问题&#xff0c;望指正&#xff01; 简介 基于MLS&#xff08;Moving Least Squares&#xff09;的上采样是一种常用的点云处理方法&#xff0c;用于增加稀疏点云数据的密度和…

在SpringBoot中使用RocketMQ

Spring Boot因为方便易用&#xff0c;在Java中广泛使用&#xff0c;本章将说明如何在Spring项目中快速使用RocketMQ。 1.直接使用 在Spring Boot项目中&#xff0c;使用某个新的组件第一步通常是加入这个组件的依赖。下面以Maven为例&#xff0c;说明如何在pom.xml中加入Rock…

Spark---介绍及安装

一、Spark介绍 1、什么是Spark Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室)所开源的类Hadoop MapReduce的通用并行计算框架&#xff0c;Spark拥有Hadoop MapReduce所具有的优点&#xff1b;但…

[ruby on rails]rack-cors, rack-attack

gem rack-attack gem rack-cors1. rack-attack 可以根据ip、域名等设置黑名单、设置访问频率 设置黑名单 # 新增 config/initializers/rack_attack.rb # 请求referer如果匹配不上设置的allowed_origins&#xff0c;返回403 forbidden Rack::Attack.blocklist(block bad domai…