$ hdparm -i /dev/sda
今回はどうやってシリアルNoを取得しているか調べたかったのでソースを見てみた
ちなみにソースのダウンロードはyumdownloaderを使う
# yum install yum-utils
$ yumdownloader --source hdparm
取得したRPMの展開はこうする
$ rpm2cpio hdparm-9.16-3.fc12.src.rpm | cpio -idv
で、tarが出てくるので展開してhdparm.cを覗いてみた
SerialNo=~を表示している関数は402行目のdump_identityで
その関数を呼び出しているのは1906行目だけ
すぐ上の1900行目でで呼び出されているioctl(fd, HDIO_GET_IDENTITY, id2)で取得してるらしい
__u16 *fdはopen(devname, open_flags) (1297行目)、__u16 id2[256]は空 (1898行目)
int open_flagsは多分O_RDONLY|O_NONBLOCK (141行目)
シリアルNoはid2[10]から20文字分の領域に格納されてる (408行目)
なんかif文だらけで疲れた、、
てことで、ここまでわかれば自分でも作れるかな
ちなみにWindowsではGetVolumeInformationを使うと取得できるみたい
と言う訳で作ってみた
調べてみたらhd_driveidっていう構造体が
ちゃんと用意されていたのでそっちを使う方がいいですね
gcc foo.cでコンパイルして./a.out /dev/sdaでシリアルNoを表示します
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/hdreg.h>
int main(int argc, char* argv[])
{
int fd, err = 0;
struct hd_driveid id;
if(argc != 2)
{
return 1;
}
fd = open(argv[1], O_RDONLY | O_NONBLOCK);
if(fd != -1)
{
if(ioctl(fd, HDIO_GET_IDENTITY, &id) != -1)
{
printf("%s\n", id.serial_no);
}
else
{
err = errno;
perror("ioctl");
}
if(close(fd) == -1)
{
err = errno;
perror("close");
}
}
else
{
err = errno;
perror(argv[1]);
}
return err;
}
0 件のコメント:
コメントを投稿