如何在 Linux 中使用 C++ 获取硬件信息

发布于 2024-10-20 04:34:27 字数 857 浏览 10 评论 0原文

我需要获取 Win 和 *nix 机器上的硬盘规格。我在 Linux 上使用了 ,如下所示:

   static struct hd_driveid hd;
   int device;
   if ((device = open("/dev/sda", O_RDONLY | O_NONBLOCK)) < 0)
   {
      cerr << "ERROR: Cannot open device /dev/sda \n";
      exit(1);
   }

   if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
   {
      cout << hd.model << endl;
      cout << hd.serial_no << endl;
      cout << hd.heads << endl;
   }

我需要 hd_driveid 来告诉我有关磁盘的更多信息。我想知道:

  • 分区数
  • 每个分区的规格(格式、标签、标志、大小、起始点、磁道数等)
  • 每个柱面的磁道数
  • 总磁道数
  • 最大块大小
  • 最小块大小
  • 默认块大小
  • 总大小 我的问题

是:

  1. 有一个共同的 (与平台无关)方式 连接硬件?我想使用 win 和 *nix 的代码相同。 (即使 没有别的办法了 将汇编代码嵌入到cpp中)
  2. 如果没有,我如何在*nix中获取上述信息?

I need to get specifications of hard disk on both Win and *nix machines. I used <hdreg.h> on Linux like this:

   static struct hd_driveid hd;
   int device;
   if ((device = open("/dev/sda", O_RDONLY | O_NONBLOCK)) < 0)
   {
      cerr << "ERROR: Cannot open device /dev/sda \n";
      exit(1);
   }

   if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
   {
      cout << hd.model << endl;
      cout << hd.serial_no << endl;
      cout << hd.heads << endl;
   }

I need hd_driveid to tell me some more information about disk. I want to know:

  • Number of partitions
  • Specifications of each partition (format, label, flags, size, start point, number of tracks etc.)
  • Number of tracks per cylinder
  • Number of total tracks
  • Maximum block size
  • Minimum Block size
  • Default block size
  • Total size of device

My questions are:

  1. Is there a common
    (platform-independent) way to
    connect hardware? I would like use
    same code for win and *nix. (even if
    there was no way other than
    embedding assembly code into cpp)
  2. If there isn't, how do I get above information in *nix?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

挽梦忆笙歌 2024-10-27 04:34:27

列表中的几乎所有内容都与“硬盘规格”无关:

  • 分区的数量取决于读取分区表,如果有任何扩展分区,则取决于这些分区的分区表。当设备驱动程序加载时,操作系统通常会为您执行此操作。
  • 分区信息(即卷标)通常在分区表中不可用。您需要猜测文件系统类型并解析文件系统头。分区表中唯一的内容是“类型”字节(它不会告诉您太多信息)以及开始/大小。
  • 硬盘驱动器不会为您提供“真实的”CHS 信息。此外,从 BIOS 的角度来看,驱动器提供的 CHS 信息是“错误的”(BIOS 自己捏造的)。
  • 硬盘驱动器具有固定的扇区大小,您可以通过 hd_driveid.sector_bytes 获得该大小(通常为 512,但某些现代驱动器使用 4096)。我不知道最大“块大小”,这是文件系统的属性。我也不确定为什么这有用。
  • 扇区总大小位于 hd_driveid.lba_capacity_2 中。此外,以字节为单位的大小可能可以通过类似的方法获得

    <前><代码>#define _FILE_OFFSET_BITS 64
    #include;
    #include;

    ...
    off_t size_in_bytes = lseek(设备, 0, SEEK_END);
    if (size_in_bytes == (off_t)-1) { ... 错误,错误代码为 ERRNO ... }

    请注意,在这两种情况下,它可能比 C×H×S 计算的大小大几兆字节。

如果您告诉我们您想要此信息的原因可能会有所帮助......

Nearly everything in your list has nothing to do with "specifications of hard disk":

  • The number of partitions depends on reading the partition table, and if you have any extended partitions, the partition tables of those partitions. The OS will usually do this bit for you when the device driver loads.
  • Partition information (namely the volume label) typically isn't available in the partition table. You need to guess the file system type and parse the file system header. The only thing in the partition table is the "type" byte, which doesn't tell you all that much, and the start/size.
  • Hard drives won't give you "real" CHS information. Additionally, the CHS information that the drive provides is "wrong" from the point of view of the BIOS (the BIOS does its own fudging).
  • Hard drives have a fixed sector size, which you can get with hd_driveid.sector_bytes (usually 512, but some modern drives use 4096). I'm not aware of a maximum "block size", which is a property of the filesystem. I'm also not sure why this is useful.
  • The total size in sectors is in hd_driveid.lba_capacity_2. Additionally, the size in bytes can probably be obtained with something like

    #define _FILE_OFFSET_BITS 64
    #include <sys/types.h>
    #include <unistd.h>
    
    ...
    off_t size_in_bytes = lseek(device, 0, SEEK_END);
    if (size_in_bytes == (off_t)-1) { ... error, error code in ERRNO ... }
    

    Note that in both cases, it'll probably be a few megabytes bigger than sizes calculated by C×H×S.

It might help if you told us why you wanted this information...

我喜欢麦丽素 2024-10-27 04:34:27
//-------------------------------------------------
// Without Boost LIB usage
//-------------------------------------------------
#include <sys/statvfs.h>
#include <sys/sysinfo.h>
//-------------------------------------------------
stringstream   strStream;
unsigned long  hdd_size;
unsigned long  hdd_free;
ostringstream  strConvert;
//---
struct sysinfo info;
sysinfo( &info );   
//---
struct statvfs fsinfo;
statvfs("/", &fsinfo);
//---
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
strStream << cpu_freq.rdbuf();
std::string  cpufrequency = strStream.str();
//---
strStream.str("");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
strStream << cpu_temp.rdbuf();
strConvert<< fixed << setprecision(2) << std::stof(strStream.str());
std::string cputemp = strConvert.str();
//---
std::string   mem_size = to_string( (size_t)info.totalram *     (size_t)info.mem_unit );
//---
hdd_size = fsinfo.f_frsize * fsinfo.f_blocks;
hdd_free = fsinfo.f_bsize * fsinfo.f_bfree;  
//---                                                
std::cout << "CPU core number           ==" << num_cpu       << endl;
std::cout << "CPU core speed            ==" << cpufrequency  << endl;
std::cout << "CPU temperature (C)       ==" << cputemp       << endl;
//---
std::cout << "Memory size               ==" << mem_size      << endl;
//---
std::cout << "Disk, filesystem size     ==" << hdd_size      << endl;
std::cout << "Disk free space           ==" << hdd_free      << endl;
//---
//-------------------------------------------------
// Without Boost LIB usage
//-------------------------------------------------
#include <sys/statvfs.h>
#include <sys/sysinfo.h>
//-------------------------------------------------
stringstream   strStream;
unsigned long  hdd_size;
unsigned long  hdd_free;
ostringstream  strConvert;
//---
struct sysinfo info;
sysinfo( &info );   
//---
struct statvfs fsinfo;
statvfs("/", &fsinfo);
//---
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
strStream << cpu_freq.rdbuf();
std::string  cpufrequency = strStream.str();
//---
strStream.str("");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
strStream << cpu_temp.rdbuf();
strConvert<< fixed << setprecision(2) << std::stof(strStream.str());
std::string cputemp = strConvert.str();
//---
std::string   mem_size = to_string( (size_t)info.totalram *     (size_t)info.mem_unit );
//---
hdd_size = fsinfo.f_frsize * fsinfo.f_blocks;
hdd_free = fsinfo.f_bsize * fsinfo.f_bfree;  
//---                                                
std::cout << "CPU core number           ==" << num_cpu       << endl;
std::cout << "CPU core speed            ==" << cpufrequency  << endl;
std::cout << "CPU temperature (C)       ==" << cputemp       << endl;
//---
std::cout << "Memory size               ==" << mem_size      << endl;
//---
std::cout << "Disk, filesystem size     ==" << hdd_size      << endl;
std::cout << "Disk free space           ==" << hdd_free      << endl;
//---
萌吟 2024-10-27 04:34:27

不,不存在独立于平台的方式。甚至没有 *nix 方式。只有 Linux 的方式。

在 Linux 中,所有相关信息都可以在 /proc 文件系统中的各个文件中找到。 /proc/devices 会告诉你有哪些设备(即使设备不可用,/dev/ 中的文件也可能存在,但打开它们会失败)情况),/proc/partitions 将告诉您每个磁盘上有哪些可用分区,并且您必须在各个子目录中查找信息。只要在某个 Linux 系统上看看哪里有你需要的。

No, there is no platform-independent way. There is even no *nix way. There is just Linux way.

In Linux, all relevant information is available in various files in the /proc filesystem. The /proc/devices will tell you what devices there are (the files in /dev/ may exist even when the devices are not available, though opening them will fail in that case), /proc/partitions will tell you what partitions are available on each disk and than you'll have to look in the various subdirectories for the information. Just look around on some linux system where is what you need.

北渚 2024-10-27 04:34:27

对于 GNU/Linux,请查看以下内容:获取硬盘元数据

For GNU/Linux have a look at this: obtaining hard disk metadata

枯寂 2024-10-27 04:34:27
//Piece of code working for me with Boost LIB usage
//-----------------------------------------------------
#include <sys/sysinfo.h>
#include <boost/filesystem.hpp>
//---    
using namespace boost::filesystem;
//---
struct sysinfo info;
sysinfo( &info );
//---
space_info si = space(".");
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream  cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
//---
std::string cpunumber = to_string(num_cpu);
std::string cpufrequency = cpu_freq.str();
std::string cputemp = cpu_temp.str();
std::string mem_size = to_string( (size_t)info.totalram *     (size_t)info.mem_unit );
std::string disk_available = to_string(si.available);
std::string fslevel = to_string( (si.available/si.capacity)*100 );
//---
//Piece of code working for me with Boost LIB usage
//-----------------------------------------------------
#include <sys/sysinfo.h>
#include <boost/filesystem.hpp>
//---    
using namespace boost::filesystem;
//---
struct sysinfo info;
sysinfo( &info );
//---
space_info si = space(".");
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream  cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
//---
std::string cpunumber = to_string(num_cpu);
std::string cpufrequency = cpu_freq.str();
std::string cputemp = cpu_temp.str();
std::string mem_size = to_string( (size_t)info.totalram *     (size_t)info.mem_unit );
std::string disk_available = to_string(si.available);
std::string fslevel = to_string( (si.available/si.capacity)*100 );
//---
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文