之前写的一个用于获取磁盘序列号的一个类,封装的不太好,莫见笑...harddiskinfo.h
点击(此处)折叠或打开
-
#ifndef HARDDISK_H
-
#define HARDDISK_H
-
-
#include <string>
-
-
#define SCSI_TIMEOUT 5000 /* ms */
-
-
class HardDiskInfo
-
{
-
public:
-
HardDiskInfo(std::string name);
-
~HardDiskInfo();
-
std::string serial_number();
-
-
private:
-
void initialize();
-
int device_fd;
-
std::string device_name;
-
};
-
- #endif /*HARDDISK_H*/
点击(此处)折叠或打开
-
#include "harddiskinfo.h"
-
-
#include <string.h>
-
#include <cstdio>
-
#include <cstdlib>
-
#include <cerrno>
-
-
#include <fcntl.h>
-
#include <unistd.h>
-
#include <linux/types.h>
-
#include <linux/hdreg.h>
-
#include <sys/ioctl.h>
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <sys/ioctl.h>
-
#include <scsi/sg.h>
-
-
#include <iostream>
-
-
using std::cerr;
-
using std::endl;
-
using std::hex;
-
-
HardDiskInfo::HardDiskInfo(std::string name) :
-
device_name(name)
-
{
-
initialize();
-
}
-
-
HardDiskInfo::~HardDiskInfo()
-
{
-
close(device_fd);
-
}
-
static int scsi_io(int fd, unsigned char *cdb, unsigned char cdb_size, int xfer_dir,
-
unsigned char *data, unsigned int *data_size,
-
unsigned char *sense, unsigned int *sense_len)
-
{
-
sg_io_hdr_t io_hdr;
-
-
memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
-
io_hdr.interface_id = 'S';
-
-
io_hdr.cmdp = cdb;
-
io_hdr.cmd_len = cdb_size;
-
-
/* Where to store the sense_data, if there was an error */
-
io_hdr.sbp = sense;
-
io_hdr.mx_sb_len = *sense_len;
-
*sense_len=0;
-
-
/*
-
* Transfer direction, either in or out. Linux does not yet
-
* support bidirectional SCSI transfers ?
-
*/
-
io_hdr.dxfer_direction = xfer_dir;
-
-
/*
-
* Where to store the DATA IN/OUT from the device and how big the
-
* buffer is
-
*/
-
io_hdr.dxferp = data;
-
io_hdr.dxfer_len = *data_size;
-
-
/* SCSI timeout in ms */
-
io_hdr.timeout = SCSI_TIMEOUT;
-
-
if(ioctl(fd, SG_IO, &io_hdr) < 0)
-
{
-
perror("SG_IO ioctl error");
-
return -1;
-
}
-
-
/* now for the error processing */
-
if((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK)
-
{
-
if(io_hdr.sb_len_wr > 0)
-
{
-
*sense_len=io_hdr.sb_len_wr;
-
return 0;
-
}
-
}
-
if(io_hdr.masked_status)
-
{
-
cerr << "status: 0x" << hex << io_hdr.status << endl;
-
cerr << "masked_status: 0x" << hex << io_hdr.masked_status << endl;
-
return -2;
-
}
-
if(io_hdr.host_status)
-
{
-
cerr << "host_status: 0x" << hex << io_hdr.host_status << endl;
-
return -3;
-
}
-
if(io_hdr.driver_status)
-
{
-
cerr << "driver_status: 0x" << hex << io_hdr.driver_status << endl;
-
return -4;
-
}
-
return 0;
-
}
-
-
static void device_serial_num(int device_fd, std::string *serial_number)
-
{
-
unsigned char cdb[] = {0x12,0x01,0x80,0,0,0};
-
unsigned int data_size = 0x00ff;
-
unsigned char data[data_size];
-
unsigned int sense_len = 32;
-
unsigned char sense[sense_len];
-
char result[32] = {0};
-
int res, pl, i;
-
-
cdb[3] = (data_size >>8) & 0xff;
-
cdb[4] = data_size & 0xff;
-
-
res=scsi_io(device_fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, &data_size, sense, &sense_len);
-
if(res)
-
{
-
perror("ioctl(SG_DXFER_FROM_DEV) error");
-
}
-
if(sense_len)
-
{
-
;
-
}
-
-
/* Page Length */
-
pl=data[3];
-
int m = 0;
-
for(i = 4;i < (pl + 4); i++)
-
result[m++] = data[i] & 0xff;
-
serial_number->assign(result);
-
}
-
-
std::string HardDiskInfo::serial_number()
-
{
-
std::string hd_serno;
-
device_serial_num(device_fd, &hd_serno);
-
-
return hd_serno;
-
}
-
-
void HardDiskInfo::initialize()
-
{
-
int vers;
-
device_fd = open(device_name.c_str(), O_RDONLY);
-
if (device_fd == -1)
-
{
-
perror("Can not open the specified device");
-
exit(EXIT_FAILURE);
-
}
-
if ((ioctl(device_fd, SG_GET_VERSION_NUM, &vers) < 0) || (vers < 30000))
-
{
-
perror("The specified device is not a sg device, or old sg device");
-
close(device_fd);
-
exit(EXIT_FAILURE);
-
}
- }