Как получить информацию об оборудовании в Linux с помощью C++

Мне нужно получить характеристики жесткого диска на машинах Win и * nix. Я использовал <hdreg.h> в 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?

person sorush-r    schedule 04.03.2011    source источник
comment
Некоторые системы не имеют разделов... Некоторые (обычно в *BSD) вместо этого используют слайсы, а другие могут просто использовать полный жесткий диск. (т.е. неразделенный).   -  person Arafangion    schedule 04.03.2011


Ответы (3)


Почти все в вашем списке не имеет ничего общего с «спецификациями жесткого диска»:

  • Количество разделов зависит от чтения таблицы разделов и, если у вас есть расширенные разделы, таблиц разделов этих разделов. ОС обычно делает это за вас при загрузке драйвера устройства.
  • Информация о разделе (а именно метка тома) обычно недоступна в таблице разделов. Вам нужно угадать тип файловой системы и проанализировать заголовок файловой системы. Единственное, что есть в таблице разделов, — это байт типа, который мало что вам говорит, и начало/размер.
  • Жесткие диски не дадут вам «настоящую» информацию о CHS. Кроме того, информация CHS, предоставляемая накопителем, является «неправильной» с точки зрения BIOS (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 ... }
    

    Обратите внимание, что в обоих случаях он, вероятно, будет на несколько мегабайт больше, чем размеры, рассчитанные CHS.

Было бы полезно, если бы вы сказали нам, зачем вам нужна эта информация...

person tc.    schedule 04.03.2011
comment
спасибо тк. Я преодолеваю T=t×S, где S - sectors, а t - количество дорожек. Я не знаю, что такое block size, и я не могу найти его нигде, кроме примера С# моего учителя. в этом примере есть экземпляр ManagementObject, и такая информация извлекается из него индексатором строк... (забыл сказать, что пишу домашнее задание :-) - person sorush-r; 04.03.2011
comment
Такие параметры, как hd.model, hd.serial_no, являются реальными. Может кто-нибудь дать мне совет, почему я получаю hd_driveid.sector_bytes равным нулю? Мне нужен только этот параметр и он равен нулю... - person Tebe; 12.04.2012
comment
@shbk: может быть лучше начать новый вопрос, указав, какое именно оборудование вы используете, полный код, который вы запустили, и что он выводит. Также намного легче помочь, если вы объясните, чего вы пытаетесь в конечном итоге достичь. - person tc.; 16.04.2012

Нет, не существует платформенно-независимого способа. Нет даже способа *nix. Есть только линуксовый способ.

В Linux вся необходимая информация доступна в различных файлах файловой системы /proc. /proc/devices сообщит вам, какие устройства существуют (файлы в /dev/ могут существовать, даже когда устройства недоступны, хотя в этом случае открыть их не удастся), /proc/partitions сообщит вам, какие разделы доступны на каждом диске, и чем вы будете нужно искать информацию в различных подкаталогах. Просто осмотритесь в какой-нибудь Linux-системе, где есть то, что вам нужно.

person Jan Hudec    schedule 04.03.2011
comment
Спасибо за ваш ответ, но я не могу найти там то, что мне нужно... Мне интересно, как создаются файлы в /proc? Я хочу сам получить информацию об оборудовании в своей программе :-) (так же, как они генерируются в /proc) - person sorush-r; 04.03.2011
comment
@Sorush «файлы» в proc на самом деле представляют собой специальную файловую систему (называемую procfs), которая считывает и / или записывает непосредственно в ядро. Вам нужно покопаться в ядре Linux, чтобы узнать, КАК procfs получает свои данные. Весь смысл procfs заключался в том, чтобы раскрывать данные без необходимости быть хакером ядра. - person KitsuneYMG; 04.03.2011
comment
@Sorush: Вам придется немного покопаться, чтобы собрать все, что вам нужно. К сожалению, сейчас я не в системе Linux и не помню точных файлов, но есть что-то вроде /proc/bus/ide и /proc/bus/scsi и еще несколько, и есть много файлов с различной информацией, которую вам нужно будет собрать. - person Jan Hudec; 07.03.2011

Для GNU/Linux взгляните на это: получение метаданных жесткого диска

person fpmurphy    schedule 04.03.2011