Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Howto get hardware information in Linux using C++

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?
like image 589
sorush-r Avatar asked Mar 04 '11 12:03

sorush-r


People also ask

How do I find system information in Ubuntu terminal?

uname -a: The uname command with the -a option prints all system information, including machine name, kernel name, version, and a few other details. This command is most useful for checking which kernel you're using. ifconfig: This reports on your system's network interfaces.


1 Answers

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...

like image 156
tc. Avatar answered Oct 23 '22 15:10

tc.