在linux下读取硬盘序列号相比在windows下简单一些,主要还是打开系统文件并获取相对应的序列号即可。
以下代码为linux读取硬盘序列号的c++代码:
int get_hd_sn(const char* szDevName, char* szSN, int limit) {
struct hd_driveid id;
int fd = open(szDevName, O_RDONLY);
if (fd < 0) {
perror("打开失败:");
return -1;
}
//这句话是关键
if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
strncpy(szSN, (const char*) id.serial_no, limit);
return 0;
}
return -1;
}
有了以上代码,那么我们的jni方法就很好写了,只要定义一下相对应的方法,并返回代码值即可。如下所示的定义:
public native int readSn(String s, char[] cs);
其中 s表示传递的硬盘标识,一般为/dev/sda,cs为填充的硬盘序列号,在传递时只需要new一个传递过去即可。而返回值,表示了读取是否成功,当为0时,读取成功。否则失败。
以下为该本要方法的jni实现:
JNIEXPORT jint JNICALL Java_XXXX(JNIEnv *env, jclass, jstring s,
jcharArray cs) {
char a[100];
jsize size = env->GetStringUTFLength(s);
char devs[size + 1];
env->GetStringUTFRegion(s, 0, size, devs);
int re = get_hd_sn(devs, a, 100);
if (re != 0)
return re;
jchar css[strlen(a)];
for (int i = 0; a[i] != '\0'; i++) {
css[i] = a[i];
}
env->SetCharArrayRegion(cs, 0, strlen(a), (const jchar*) css);
return re;
}
整个实现过程很简单,在jni方法返回之后,要对读取的数据转化为字符串,并去除其中的空格,最后得到的结果就是我们所需要的硬盘序列号了。如下所示:
String s = new String(cs);//cs即传递过去的字符数组
s = s.trim();
System.out.println("硬盘序列号为:" + s);
至此,整个实现即OK。但要运行时,却有一个权限的问题。非root用户不能访问/dev/sda文件,所以在运行以上的jni程序时,需要使用root用户来运行,否则在jni方法内部,会报一个没有权限的错误信息。这是惟一一个不好的地方。
转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201109140001.html
.net程序员路过