How to get hardware information on Linux using C ++

I need to get the hard drive specifications on Win and * nix machines. I used <hdreg.h> for Linux as follows:

  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 tell me more disk information. I want to know:

  • Number of sections
  • The characteristics of each section (format, label, flags, size, starting point, number of tracks, etc.).
  • Number of tracks per cylinder
  • Number of shared tracks
  • Max block size
  • Minimum block size
  • Default block size
  • Total device size

My questions:

  • Is there a general (platform independent) way to connect the equipment? I would like to use the same code for win and * nix. (even if there was no other way than embedding assembly code in cpp)
  • If this does not happen, how do I get information in * nix?
+8
c ++ linux hardware hard-drive
source share
5 answers

Almost everything on your list has nothing to do with the “hard drive specifications”:

  • The number of partitions depends on the reading of the partition table and, if you have any extended partitions, the partition tables of these partitions. Usually, the OS will do this bit for you when loading the device driver.
  • Partition information (namely, volume label) is usually not available in the partition table. You need to guess the file system type and analyze the file system header. The only thing in the partition table is the "type" byte, which does not tell you all this, and the start / size.
  • Hard drives will not give you "real" CHS information. In addition, the CHS information that the drive provides is “incorrect” in terms of the BIOS (the BIOS does its own fake).
  • 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 do not know about the maximum "block size", which is a property of the file system. I am also not sure why this is useful.
  • The total size in sectors is in hd_driveid.lba_capacity_2 . Also, the size in bytes can probably be obtained using 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 ... } 

    Please note that in both cases this is likely to be several megabytes larger than the sizes calculated by C & times; H x S.

This may help if you told us why you wanted this information ...

+9
source share

No, there is no platform independent method. There is even no * nix path. There is only a Linux way.

On Linux, all relevant information is available in various files in the /proc file system. /proc/devices will tell you which devices exist (files in /dev/ may exist even if the devices are inaccessible, although opening them will fail), /proc/partitions will tell you which partitions are available for each drive, and You will have to search in different subdirectories for information. Just look around any Linux system where you need it.

+3
source share

On GNU / Linux, see: getting hard disk metadata

+2
source share
 //------------------------------------------------- // 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; //--- 
+2
source share
 //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 ); //--- 
+1
source share

All Articles