首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

linux 获取硬盘序列号解决思路

2013-11-25 
linux 获取硬盘序列号找了好久,找到下面代码:// a.cpp//在Linux下获取硬盘物理系列号的程序#include stdi

linux 获取硬盘序列号
找了好久,找到下面代码:


// a.cpp

//在Linux下获取硬盘物理系列号的程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>             /* ioperm() */
#include <sys/io.h>             /* outb(), inb() */
//#include <asm/io.h> //推荐不要使用这个asm/io.h

#define _DEBUG_ 1

/* get serial number */
int gethddsn(char *ide)
{
        unsigned int ide_info[257];
        unsigned int info_off;
        unsigned long loop2 = 0;
        int loop, loop1 = 0;
        
        if( ioperm(0x1F6, 1, 1) ) {
                perror("ioperm");
                //exit(-1);
                return 0;
        }
        
        outb(0xA0, 0x1F6);
        if( ioperm(0x1F7, 1, 1) ) {
                perror("ioperm");
                //exit(-1);
                return 0;
        }
        
        outb(0xEC, 0x1F7);
        do {
                if( ioperm(0x1F7, 1, 1) ) {
                        perror("ioperm");
                        //exit(-1);
                        return 0;
                }
        }while( inb(0x1F7) != 0x58 && loop2++ < 0xFFFF );
        
        for( info_off = 0; info_off != 256; info_off++) {
                if( ioperm(0x1F0, 2, 1) ) {
                        perror("ioperm");
                        //exit(-1);
                        return 0;
                }
                
                ide_info[info_off] = inw(0x1F0);
        }
        
        for(loop = 10, loop1 = 0; loop <= 19; loop++)
        {
                ide[loop1++] = (char)(ide_info[loop]/256);
                ide[loop1++] = (char)(ide_info[loop]%256);
        }
        
        ide[loop1] = 0x00; //字符串结束
        if( loop1 > 20 )
        {
                printf("*hdsn too len:[%d] error!*\n", loop1);
                return 0;
        }
        
        return 1;
}

#if _DEBUG_
int main(void)  //print hard disk number 


{
        static char serial[21];
        
        if (gethddsn(serial))
                printf("IDE hard disk s/n: %s\n", serial);
        for (int i = 0; i < 20; ++i)
            printf("%d ", serial[i]);
        printf("\n");
        return 0;
}
#endif



// b.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/hdreg.h>

int main(int argc,char *argv[])
{
        static int open_flags = O_RDONLY|O_NONBLOCK;
        static int errno = 1;
        static struct hd_driveid id;

        int fd;
        const char *devname = "/dev/hda"; // 改成 "/dev/sda"时ioctl会出错, errno == 22

        fd = open(devname,open_flags);
        if(fd < 0)
        {
                perror(devname);
                exit(errno);
        }

        ioctl(fd,HDIO_GET_IDENTITY,&id);
        printf("Model = %40s,FwRev = %8s,SerialNo = %20s\n",id.model,id.fw_rev,id.serial_no);
        close(fd);

        return 0;
}


// c.cpp
#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 const 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(0==sense_len){  // 注意:原代码是 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;
}


方便测试,写了个makefile
 还有的赚
------解决方案--------------------


嗯嗯 花的代价太大了 就没有必要了 可以和boss 好好沟通下,把中间的缘由好好讲讲,应该没什么问题了
[解决办法]
时间没有浪费的!至少你懂了些东西!写了代码!并测试了你的代码!
我下午也是什么也没搞成!版本不同,导致重头再来了!
[解决办法]

引用:
Quote: 引用:

试试这些命令:
http://www.linuxjournal.com/content/tech-tip-retrieve-disk-info-command-line
然后尝试找其源代码。或者直接解析其输出结果。

谢谢,回家用正常的机器试试

如果没代码,那就解析system的结果了


这个比较靠普
[解决办法]
磁盘序列号以前写过,也是加密用的,过于久远,忘记了就当我路过吧
[解决办法]
来看看,然后5分到手

热点排行