2011-03-04 65 views
8

我需要在Win和* nix机器上获取硬盘的规格。我在Linux上使用<hdreg.h>这样的:如何在Linux中使用C++获取硬件信息

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. 是否有一个共同的 (独立平台)的方式来 连接硬件?我想使用 相同的代码为赢和* nix。 (即使 没有办法将 嵌入到cpp的汇编代码中)
  2. 如果没有,我如何在* nix中获得上述信息?
+1

某些系统没有分区......有些(通常在* BSD中)使用“分片”,而其他分区可能只是使用完整的硬盘。 (即未分区)。 – Arafangion 2011-03-04 13:36:59

回答

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

谢谢tc。我用'T = t×S'来克服,其中S是'扇区',t是轨道数。我不知道'块大小'是什么,除了我的老师C#示例以外,我找不到它。在这个例子中有一个'ManagementObject'的实例,这些信息是通过一个字符串索引器提取出来的......(我忘了说我在写作业:-) – 2011-03-04 13:48:40

+1

像hd.model,hd.serial_no这样的参数是真实。可能有人给我一个提示,为什么我得到一个hd_driveid.sector_bytes等于零?我只需要这个参数,它等于零... – Tebe 2012-04-11 22:48:12

+1

@shbk:开始一个新的问题可能会更好,它说明你正在使用的硬件,你运行的完整代码以及它输出的内容。如果你解释你试图最终实现什么,它也更容易帮助。 – 2012-04-16 15:37:46

3

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

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

+1

感谢您的回答,但我找不到我需要的答案......我想知道如何创建'/ proc'中的文件?我想在我的程序中自己获得硬件信息:-)(与它们在'/ proc'中生成的方式相同) – 2011-03-04 12:38:22

+3

@将proc中的'文件'刷新是真正的特殊文件系统(称为procfs),它读取和/或直接写入内核。您将需要深入Linux内核以找出procfs如何获取其数据。 procfs的重点在于公开无需成为内核黑客的数据。 – KitsuneYMG 2011-03-04 12:54:19

+1

@Sorush:你将不得不挖掘一下,收集你所需要的一切。不幸的是,我现在不在Linux系统上,我不记得确切的文件,但有'/ proc/bus/ide'和'/ proc/bus/scsi'之类的东西,还有一些文件您需要收集的各种信息。 – 2011-03-07 13:54:32

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