文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档> linux下读取sata硬盘序列号

linux下读取sata硬盘序列号

时间:2009-05-29  来源:coolias

   今天一直在找sata硬盘序列号的C读取方法, 找了良久, 终于找到一份可行的代码, 遂改之, 下面这段代码在as4测试通过, (此篇文章修改自: http://samba.org/~tridge/ctdb/utils/scsi_io/scsi_io.c)

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <scsi/sg.h>

#define SCSI_TIMEOUT 5000 /* ms */

static char *device = "/dev/sda";

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';

    /* 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;
    *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 failed");
        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){
        printf("status=0x%x\n", io_hdr.status);
        printf("masked_status=0x%x\n", io_hdr.masked_status);
        return -2;
    }
    if(io_hdr.host_status){
        printf("host_status=0x%x\n", io_hdr.host_status);
        return -3;
    }
    if(io_hdr.driver_status){
        printf("driver_status=0x%x\n", io_hdr.driver_status);
        return -4;
    }
    return 0;
}

int scsi_inquiry_unit_serial_number(int fd)
{
    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];

    int res, pl, i;

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

    printf("INQUIRY Unit Serial Number:\n");

    res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, &data_size, sense, &sense_len);
    if(res){
        printf("SCSI_IO failed\n");
        return -1;
    }
    if(sense_len){
        return -1;
    }

    /* Page Length */
    pl=data[3];

    /* Unit Serial Number */
    printf("Unit Serial Number:");
    for(i=4;i<(pl+4);i++)printf("%c",data[i]&0xff);printf("\n");
    return 0;
}

int open_scsi_device(const char *dev)
{
    int fd, vers;

    if((fd=open(dev, O_RDWR))<0){
        printf("ERROR could not open device %s\n", dev);
        return -1;
    }
    if ((ioctl(fd, SG_GET_VERSION_NUM, &vers) < 0) || (vers < 30000)) {
        printf("/dev is not an sg device, or old sg driver\n");
        close(fd);
        return -1;
    }

    return fd;
}

int main(int argc, const char *argv[])
{
    int fd;

    fd=open_scsi_device(device);
    if(fd<0){
        printf("Could not open SCSI device %s\n",device);
        _exit(10);
    }

    scsi_inquiry_unit_serial_number(fd);

    return 0;
}

相关阅读 更多 +
排行榜 更多 +
龙珠格斗火柴人

龙珠格斗火柴人

飞行射击 下载
荒野恐龙猎手安卓版

荒野恐龙猎手安卓版

飞行射击 下载
超凡坦克英雄

超凡坦克英雄

飞行射击 下载