2011-03-04 25 views
8

Necesito obtener las especificaciones del disco duro en las máquinas Win y * nix. Solía ​​<hdreg.h> en Linux así:Cómo obtener información de hardware en Linux usando 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; 
    } 

necesito hd_driveid decirme algo más de información sobre el disco. Quiero saber:

  • número de particiones
  • Especificaciones de cada partición (formato, etiquetas, banderas, tamaño, punto de inicio, número de pistas, etc.)
  • Número de pistas por cilindro
  • Número de pistas totales
  • tamaño de bloque máximo
  • bloque mínimo tamaño
  • tamaño de bloque predeterminado
  • Tamaño total del dispositivo

Mis preguntas son:

  1. ¿Hay una forma común (independiente de la plataforma) para de hardware de conexión? Me gustaría usar el mismo código para win y * nix. (incluso si no había otra manera que incrustando código de ensamblado en cpp)
  2. Si no hay, ¿cómo obtengo la información anterior en * nix?
+1

Algunos sistemas no tienen particiones ... Algunos (normalmente en los * BSD) usan "sectores" en su lugar, y otros podrían estar simplemente usando el disco duro completo. (es decir, sin particionar). – Arafangion

Respuesta

9

Casi todo en su lista no tiene nada que ver con "especificaciones de disco duro":

  • El número de particiones depende de la lectura de la tabla de particiones, y si usted tiene cualquier partición extendida, las tablas de particiones de esas particiones. El SO generalmente hará este bit por usted cuando se cargue el controlador del dispositivo.
  • La información de partición (es decir, la etiqueta de volumen) normalmente no está disponible en la tabla de particiones. Necesita adivinar el tipo de sistema de archivos y analizar el encabezado del sistema de archivos. Lo único en la tabla de particiones es el byte "tipo", que no te dice mucho, y el inicio/tamaño.
  • Los discos duros no le darán información "real" de CHS. Además, la información de CHS que proporciona el disco es "incorrecta" desde el punto de vista del BIOS (el BIOS hace su propio borrado).
  • Los discos duros tienen un tamaño de sector fijo, que puede obtener con hd_driveid.sector_bytes (generalmente 512, pero algunos discos modernos usan 4096). No conozco un "tamaño de bloque" máximo, que es una propiedad del sistema de archivos.Tampoco estoy seguro de por qué esto es útil.
  • El tamaño total en sectores está en hd_driveid.lba_capacity_2. Además, el tamaño en bytes, probablemente, se puede obtener con algo como

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

    Nótese que en ambos casos, es probable que va a ser unos pocos megabytes más grandes que los tamaños calculados por C H × × S.

podría ayudar si usted nos dijo por qué quería esta información ...

+1

Gracias tc. Lo supero con 'T = t × S' donde S es' sectores' y t es el número de pistas. No sé qué es el 'tamaño de bloque' y no puedo encontrarlo en ningún otro lugar que no sea el ejemplo de mis maestros C#. en este ejemplo hay una instancia de 'ManagementObject' y dicha información se extrae de ella mediante un indizador de cadenas ... (Olvidé decir que estoy escribiendo una tarea :-) –

+1

Parámetros como hd.model, hd.serial_no son real. ¿Puede alguien darme un consejo por qué estoy recibiendo un hd_driveid.sector_bytes igual a cero? Solo necesito este parámetro y es igual a cero ... – Tebe

+1

@shbk: Puede ser mejor comenzar una nueva pregunta que indique exactamente qué hardware está usando, el código completo que ejecutó y qué produce. También es mucho más fácil ayudar si explicas lo que intentas lograr en última instancia. –

3

No, no hay una manera independiente de la plataforma. Ni siquiera hay forma de * nix. Solo hay una forma de Linux.

En Linux, toda la información relevante está disponible en varios archivos en el sistema de archivos /proc. El /proc/devices le dirá qué dispositivos hay (los archivos en /dev/ pueden existir incluso cuando los dispositivos no están disponibles, aunque abrirlos fallará en ese caso), /proc/partitions le dirá qué particiones están disponibles en cada disco y que usted tiene que buscar en los diversos subdirectorios para la información. Solo mira a tu alrededor en algún sistema Linux donde es lo que necesitas.

+1

Gracias por su respuesta, pero no puedo encontrar lo que necesito allí ... Me pregunto cómo se crean los archivos en '/ proc' Quiero obtener información de hardware en mi programa :-) (de la misma manera que se generan en '/ proc') –

+3

@Sorush los 'archivos' en proc son realmente un sistema de archivos especial (llamado procfs) que lee y/o escribe directamente en el kernel. Tendrás que profundizar en el kernel de Linux para descubrir CÓMO procfs obtiene sus datos. El objetivo de procfs era exponer los datos sin necesidad de ser un hacker del kernel. – KitsuneYMG

+1

@Sorush: tendrás que cavar un poco para recolectar todo lo que necesites. Desafortunadamente no estoy en un sistema Linux ahora y no recuerdo los archivos precisos, pero hay algo como '/ proc/bus/ide' y'/proc/bus/scsi' y algunos otros y hay muchos archivos con varios bits de información que deberá recopilar. –

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; 
//--- 
Cuestiones relacionadas