2011-03-04 6 views
8

Мне нужно получить спецификации жесткого диска на компьютерах Win и * nix. Я использовал <hdreg.h> на Linux, как это:Как получить информацию об оборудовании в 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. Есть ли общая (независимый от платформы) способ подключения оборудования? Я бы хотел использовать тот же код для win и * nix. (даже если не было никакого способа, кроме , встраивание ассемблерного кода в cpp)
  2. Если нет, то как мне получить информацию в * nix?
+1

Некоторые системы не имеют разделов ... Некоторые (как правило, в * BSD) используют вместо этого «срезы», а другие вполне могут просто использовать полный жесткий диск. (т. е. безразделения). – Arafangion

ответ

9

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

  • Количество разделов зависит от чтения таблицы разделов, и если у вас есть какие-либо дополнительные разделы, раздел Таблицы эти разделы. Обычно ОС будет делать этот бит для вас при загрузке драйвера устройства.
  • Информация о разделе (а именно метка тома) обычно не доступна в таблице разделов. Вам нужно угадать тип файловой системы и проанализировать заголовок файловой системы. Единственное, что в таблице разделов - это байт типа, который не говорит вам всего этого, и начало/размер.
  • Жесткие диски не выдадут вам «настоящую» информацию CHS. Кроме того, информация CHS, которую предоставляет привод, является «неправильной» с точки зрения BIOS (BIOS делает свое собственное fudging).
  • Жесткие диски имеют фиксированный размер сектора, который вы можете получить с помощью 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 - числом дорожек. Я не знаю, что такое 'block size', и я не могу найти его нигде, кроме примера C# преподавателей. в этом примере есть экземпляр «ManagementObject», и такая информация извлекается из него строковым индексом ... (я забыл сказать, что пишу домашнее задание :-) –

+1

Параметры, такие как hd.model, hd.serial_no, реальный. Может кто-нибудь дать мне совет, почему я получаю hd_driveid.sector_bytes равным нулю? Мне нужен только этот параметр, и он равен нулю ... – Tebe

+1

@shbk: Может быть, лучше начать новый вопрос с указанием того, какое оборудование вы используете, полный код, который вы запускали, и то, что он выводит. Это также намного легче помочь, если вы объясните, чего вы пытаетесь достичь в конечном итоге. –

3

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

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

+1

Спасибо за ваш ответ, но я не могу найти то, что мне там нужно ... Я задавался вопросом, как создаются файлы в '/ proc'? Я хочу получить информацию об оборудовании самостоятельно в своей программе :-) (так же, как они создаются в '/ proc') –

+3

@ Сопровождать« файлы »в proc - это действительно специальная файловая система (называемая procfs), которая читает и/или писать непосредственно в ядро. Вам нужно будет выкопать ядро ​​Linux, чтобы узнать, КАК procfs получает свои данные. Весь смысл procfs заключался в том, чтобы предоставить данные без необходимости быть хакером ядра. – KitsuneYMG

+1

@Sorush: Вам нужно будет копать совсем немного, чтобы собрать все, что вам нужно. К сожалению, я сейчас не в системе Linux, и я не помню точные файлы, но есть что-то вроде '/ proc/bus/ide' и'/proc/bus/scsi' и некоторые другие, и есть много файлов с различные биты информации, которые вам нужно собрать. –

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; 
//--- 
Смежные вопросы