在windows x64系统下读取sata硬盘序列号

上一篇文章中我们提到如何使用jni在windows环境中读取硬盘序列号。然而,原有的代码,并不能有效地读取sata硬盘信息,并且在x64环境下也不能工作。所以,我们需要一种新的读取硬盘序列号的方法。

最终,经过笔者寻找,发现终于有一个有效地同时能够读取sata硬盘的c++代码,该代码的源地址为:

http://www.winsim.com/diskid32/diskid32.cpp

此代码能够在x86以及x64位平台下很好地工作。当然,仅是一段读取硬盘信息的代码,此处有详细的使用代码。可以下载以使用。

那么,在java中, 我们可以使用这段代码,分别编译出两个版本的dll文件,一个定义为acx86.dll,另一个定义为acx64.dll。这样在项目启动时,我们就可以根据当前jvm的版本(为什么不是windows版本,而是jvm版本,自己想),来选择加载不同的dll。那么,如何判断当前jvm版本呢,以下代码可以达到:

	public static boolean isJvm32() {
		return System.getProperty("sun.arch.data.model").contains("32");
	}

属性值sun.arch.data.model,当在32位jvm时,将返回32; 而在64位jvm时,返回64。这样就可以分别加载不同的dll了。

以上代码(包括c++和java)均已在本机测试通过(windows xp x64版本,jdk32位和64位)。

在linux下使用java(jni)读取硬盘序列号

    在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时,读取成功。否则失败。

继续阅读“在linux下使用java(jni)读取硬盘序列号”

使用jni在windows下读取硬盘序列号

    通常做java程序的开发人员都想过想要通过某种手段来保护自己的程序。一般的方式是通过授权,采取软件授权的方式。这个时间就需要读取客户机器上的一些关键信息,比如硬盘序列号,网卡,cpu信息或者bios信息等。其中,java本身可以读取网卡信息,对于其它的机器信息读取出来则有点困难了。然而,通过其它语言,比如c++,这些信息都可以通过一定的函数将其读取出来。
    本文描述了通过网上的一个读取硬盘序列号的小程序(使用c++实现),采用jni来再次引用实现,以达到首要的目的。

    首先是需要下载相应的通过c++读取硬盘信息的相应代码,相应的源代码可以到此地址下载。
    http://download.csdn.net/download/Fly_m/3581179
    待下载完全之后,通过以下简单的方式即可以读取硬盘序列号,并返回相应的java 字符串信息。如定义的读取硬盘序列号的java本地方法为:

static native String r();

    则相对应的jni的实现即为:

JNIEXPORT jstring JNICALL XXX_r
(JNIEnv *env, jclass cls) {
	DiskInfo d = DiskInfo();
	int i = d.GetDiskInfo();
	if(i != 0) {
		return env->NewStringUTF("");
	}
	return env->NewStringUTF(d.szSerialNumber);
}

    以上即为完整的通过jni读取硬盘序列号的例子,完全可以在生产环境中使用。