操原作业(四)之获取U盘信息

这里写图片描述

方法一:

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

int scsi_get_serial(int fd, void *buf, size_t buf_len)
{
    //数组中是将要执行的SCSI命令
    unsigned char inq_cmd[] = {INQUIRY, 1, 0x80, 0, buf_len, 0};
    unsigned char sense[32];
    struct sg_io_hdr io_hdr;
    int result;

    memset(&io_hdr, 0, sizeof(io_hdr));
    io_hdr.interface_id = 'S';
    io_hdr.cmdp = inq_cmd;
    io_hdr.cmd_len = sizeof(inq_cmd);
    io_hdr.dxferp = buf;
    io_hdr.dxfer_len = buf_len;
    io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
    io_hdr.sbp = sense;
    io_hdr.mx_sb_len = sizeof(sense);
    io_hdr.timeout = 5000;

    result = ioctl(fd, SG_IO, &io_hdr);
    if (result < 0)
        return result;

    if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK)
        return 1;

    return 0;
}

int main(int argc, char **argv)
{
    char *dev = "/dev/sdb4";
    //序列号,ID,供应商ID
    char scsi_serial[255];
    char line[101];

    int rc;
    int fd;

    fd = open(dev, O_RDONLY | O_NONBLOCK);
    if (fd < 0)
    {
        perror(dev);
    }
    memset(scsi_serial, 0, sizeof(scsi_serial));
    rc = scsi_get_serial(fd, scsi_serial, 255);
    if (rc < 0)
    {
        printf("FAIL, rc=%d, errno=%d\n", rc, errno);
    }
    else if (rc == 1)
    {
        printf("FAIL, rc=%d, drive doesn't report serial number\n", rc);
    }
    else
    {
        printf("product id:");
        for (int i = 15; i < 32; ++i)
        {
            putchar(scsi_serial[i]);
        }
        putchar('\n');

        printf("producer id:");
        for (int i = 8; i < 15; ++i)
        {
            putchar(scsi_serial[i]);
        }
        putchar('\n');

        printf("serial number:");
        for (int i = 8; i < 32; ++i)
        {
            putchar(scsi_serial[i]);
        }
        putchar('\n');
    }
    close(fd);
    //获得U盘路径
    FILE *fp = fopen("/proc/mounts", "r");
    if (!fp)
    {
        perror(dev);
    }
    char *result = NULL;
    char delims[] = " ";
    while (fgets(line, sizeof(line), fp))
        if (strstr(line, "/dev/sdb4"))
        {
            result = strtok(line, delims);
            printf("%s", result); //打印该行。
            result = strtok(NULL, delims);
            printf("%s\n", result); //打印该行。
        }
    return (EXIT_SUCCESS);
}

方法二: (该方法只能获取本地磁盘信息,对于 U 盘无效)

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

int main(){
    struct hd_driveid *id;
    char *dev = "/dev/hda";
    int fd;

    fd = open(dev, O_RDONLY|O_NONBLOCK);
    if(fd < 0) {
        perror("cannot open");
    }
    if (ioctl(fd, HDIO_GET_IDENTITY, id) < 0) {
        close(fd);
        perror("ioctl error");
    } else {
        // if we want to retrieve only for removable drives use this branching
        if ((id->config & (1 << 7)) || (id->command_set_1 & 4)) {
            close(fd);
            printf("Serial Number: %s\n", id->serial_no);
        } else {
            perror("support not removable");
        }
        close(fd);
    }
}

执行结果:

这里写图片描述

参考: USB-drive serial number under linux C++

猜你喜欢

转载自blog.csdn.net/yin__ren/article/details/80304546