php 查看linux硬盘序列号,LINUX获取硬盘序列号

介绍:Linux系统获取磁盘序列号的命令和工具比较多,但每一种工具都有一定局限性,本文的c++工具集合

多种获取磁盘序列号的方法,除了虚拟机外,一般都可以获取磁盘的序列号。

disknum.cpp源码如下:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static bool get_disk_name(std::string & disk_name)

{

disk_name.c_str();

std::ifstream ifs("/etc/mtab", std::ios::binary);

if (!ifs.is_open())

{

return(false);

}

char line[4096] = { 0 };

while (!ifs.eof())

{

ifs.getline(line, sizeof(line));

if (!ifs.good())

{

break;

}

const char * disk = line;

while (isspace(disk[0]))

{

++disk;

}

const char * space = strchr(disk, ' ');

if (NULL == space)

{

continue;

}

const char * mount = space + 1;

while (isspace(mount[0]))

{

++mount;

}

if ('/' != mount[0] || ' ' != mount[1])

{

continue;

}

while (space > disk && isdigit(space[-1]))

{

--space;

}

if (space > disk)

{

std::string(disk, space).swap(disk_name);

break;

}

}

ifs.close();

return(!disk_name.empty());

}

static void trim_serial(const void * serial, size_t serial_len, std::string & serial_no)

{

const char * serial_s = static_cast(serial);

const char * serial_e = serial_s + serial_len;

while (serial_s < serial_e)

{

if (isspace(serial_s[0]))

{

++serial_s;

}

else if ('\0' == serial_e[-1] || isspace(serial_e[-1]))

{

--serial_e;

}

else

{

break;

}

}

if (serial_s < serial_e)

{

std::string(serial_s, serial_e).swap(serial_no);

}

}

static bool get_disk_serial_by_way_1(const std::string & disk_name, std::string & serial_no)

{

serial_no.clear();

int fd = open(disk_name.c_str(), O_RDONLY);

if (-1 == fd)

{

return(false);

}

struct hd_driveid drive = { 0 };

if (0 == ioctl(fd, HDIO_GET_IDENTITY, &drive))

{

trim_serial(drive.serial_no, sizeof(drive.serial_no), serial_no);

}

close(fd);

return(!serial_no.empty());

}

static bool 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 = { 0 };

io_hdr.interface_id = 'S';

/* CDB */

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;

/*

*        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 = 5000;

if (ioctl(fd, SG_IO, &io_hdr) < 0)

{

return(false);

}

/* now for the error processing */

if (SG_INFO_OK != (io_hdr.info & SG_INFO_OK_MASK) && io_hdr.sb_len_wr > 0)

{

return(false);

}

if (io_hdr.masked_status || io_hdr.host_status || io_hdr.driver_status)

{

return(false);

}

return(true);

}

static bool get_disk_serial_by_way_2(const std::string & disk_name, std::string & serial_no)

{

serial_no.clear();

int fd = open(disk_name.c_str(), O_RDONLY);

if (-1 == fd)

{

return(false);

}

int version = 0;

if (ioctl(fd, SG_GET_VERSION_NUM, &version) < 0 || version < 30000)

{

close(fd);

return(false);

}

const unsigned int data_size = 0x00ff;

unsigned char data[data_size] = { 0 };

const unsigned int sense_len = 32;

unsigned char sense[sense_len] = { 0 };

unsigned char cdb[] = { 0x12, 0x01, 0x80, 0x00, 0x00, 0x00 };

cdb[3] = (data_size >> 8) & 0xff;

cdb[4] = (data_size & 0xff);

if (scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, data_size, sense, sense_len))

{

/* Page Length */

int page_len = data[3];

/* Unit Serial Number */

trim_serial(data + 4, page_len, serial_no);

}

close(fd);

return(!serial_no.empty());

}

static bool parse_serial(const char * line, int line_size, const char * match_words, std::string & serial_no)

{

const char * serial_s = strstr(line, match_words);

if (NULL == serial_s)

{

return(false);

}

serial_s += strlen(match_words);

while (isspace(serial_s[0]))

{

++serial_s;

}

const char * serial_e = line + line_size;

const char * comma = strchr(serial_s, ',');

if (NULL != comma)

{

serial_e = comma;

}

while (serial_e > serial_s && isspace(serial_e[-1]))

{

--serial_e;

}

if (serial_e <= serial_s)

{

return(false);

}

std::string(serial_s, serial_e).swap(serial_no);

return(true);

}

static void get_serial(const char * file_name, const char * match_words, std::string & serial_no)

{

serial_no.c_str();

std::ifstream ifs(file_name, std::ios::binary);

if (!ifs.is_open())

{

return;

}

char line[4096] = { 0 };

while (!ifs.eof())

{

ifs.getline(line, sizeof(line));

if (!ifs.good())

{

break;

}

if (0 == ifs.gcount())

{

continue;

}

if (parse_serial(line, ifs.gcount() - 1, match_words, serial_no))

{

break;

}

}

ifs.close();

}

static bool get_disk_serial_by_way_3(const std::string & disk_name, std::string & serial_no)

{

serial_no.c_str();

const char * hdparm_result = ".hdparm_result.txt";

char command[512] = { 0 };

snprintf(command, sizeof(command), "sudo hdparm -i %s | grep SerialNo > %s", disk_name.c_str(), hdparm_result);

if (0 == system(command))

{

get_serial(hdparm_result, "SerialNo=", serial_no);

}

unlink(hdparm_result);

return(!serial_no.empty());

}

static bool get_disk_serial_by_way_4(std::string & serial_no)

{

serial_no.c_str();

const char * lshw_result = ".lshw_result.txt";

char command[512] = { 0 };

snprintf(command, sizeof(command), "sudo lshw -class disk | grep serial > %s", lshw_result);

if (0 == system(command))

{

get_serial(lshw_result, "serial:", serial_no);

}

unlink(lshw_result);

return(!serial_no.empty());

}

static bool get_disk_serial_number(std::string & serial_no)

{

if (0 != getuid())

{

return(false);

}

std::string disk_name;

if (get_disk_name(disk_name))

{

if (get_disk_serial_by_way_1(disk_name, serial_no))

{

return(true);

}

if (get_disk_serial_by_way_2(disk_name, serial_no))

{

return(true);

}

if (get_disk_serial_by_way_3(disk_name, serial_no))

{

return(true);

}

}

if (get_disk_serial_by_way_4(serial_no))

{

return(true);

}

return(false);

}

static void test_1()

{

std::string serial_no;

if (get_disk_serial_number(serial_no))

{

printf("serial_number: [%s]\n", serial_no.c_str());

}

else

{

printf("get serial number failed\n");

}

}

static void test_2()

{

std::string disk_name;

if (get_disk_name(disk_name))

{

printf("disk_name:[%s]\n", disk_name.c_str());

{

std::string serial_no;

get_disk_serial_by_way_1(disk_name, serial_no);

printf("get_serial_by_way_1:[%s]\n", serial_no.c_str());

}

{

std::string serial_no;

get_disk_serial_by_way_2(disk_name, serial_no);

printf("get_serial_by_way_2:[%s]\n", serial_no.c_str());

}

{

std::string serial_no;

get_disk_serial_by_way_3(disk_name, serial_no);

printf("get_serial_by_way_3:[%s]\n", serial_no.c_str());

}

}

{

std::string serial_no;

get_disk_serial_by_way_4(serial_no);

printf("get_serial_by_way_4:[%s]\n", serial_no.c_str());

}

}

int main(int argc, char * argv[])

{

printf("---------------\n");

test_1();

printf("---------------\n");

test_2();

printf("---------------\n");

return(0);

}

编译:

g++ disknum.cpp -o disknum

运行命令:

[root@mobile ~]# disknum

---------------

serial_number: [00f32f3a079809b31e006e64d860f681]

---------------

disk_name:[/dev/sda]

get_serial_by_way_1:[]

get_serial_by_way_2:[00f32f3a079809b31e006e64d860f681]

HDIO_DRIVE_CMD(identify) failed: Invalid exchange

HDIO_GET_IDENTITY failed: Invalid argument

get_serial_by_way_3:[]

sudo: lshw: command not found

get_serial_by_way_4:[]

(责任编辑:liangzh)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值