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

时间:2011-03-04 12:21:38

标签: c++ linux hardware hard-drive

我需要在Win和* nix机器上获得硬盘规格。我在Linux上使用<hdreg.h>就像这样:

   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中的上述信息?

5 个答案:

答案 0 :(得分:9)

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

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

    的方式获得字节大小
    #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 ... }
    

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

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

答案 1 :(得分:3)

不,没有与平台无关的方式。甚至没有* nix的方式。只有Linux方式。

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

答案 2 :(得分:2)

对于GNU / Linux,请看一下:obtaining hard disk metadata

答案 3 :(得分:2)

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

答案 4 :(得分:1)

//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 );
//---