在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程序员路过