直接从RING3获取硬盘序列号 
--------------------------------------------------------------------------------
通常情况下,我们通过0XEC命令对IDE端口进行监测.获取硬盘信息. 
一般情况下,我们就写个VXD或者DRIVER来完成.但是现在,通过MS的S.M.A.R.T.接口,我们可以直接从RING3调用API DeviceIoControl()来获取硬盘信息 
*注:在WIN98SE,WINDOWS ME中,S.M.A.R.T并不缺省安装.请将SMARTVSD.VXD拷贝到%SYSTEM%\IOSUBSYS目录下. 
在WINDOWS2000下,由于非ADMINISTRATORS组的用户对硬盘连GENERIC_READ的权限也没有,所以请以ADMINISTRATOR登录后使用. /*+++ 
HDID.CPP 
Written by Lu Lin 
http://lu0.126.com 
2000.11.3 
---*/ 
#include <windows.h> 
#include <iostream.h> 
#include <stdio.h> #define DFP_GET_VERSION 0x00074080 
#define DFP_SEND_DRIVE_COMMAND 0x0007c084 
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088 #pragma pack(1) 
typedef struct _GETVERSIONOUTPARAMS { 
 BYTE bVersion;  // Binary driver version. 
 BYTE bRevision;  // Binary driver revision. 
 BYTE bReserved;  // Not used. 
 BYTE bIDEDeviceMap; // Bit map of IDE devices. 
 DWORD fCapabilities; // Bit mask of driver capabilities. 
 DWORD dwReserved[4]; // For future use. 
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS; typedef struct _IDEREGS { 
 BYTE bFeaturesReg;  // Used for specifying SMART "commands". 
 BYTE bSectorCountReg; // IDE sector count register 
 BYTE bSectorNumberReg; // IDE sector number register 
 BYTE bCylLowReg;   // IDE low order cylinder value 
 BYTE bCylHighReg;  // IDE high order cylinder value 
 BYTE bDriveHeadReg;  // IDE drive/head register 
 BYTE bCommandReg;  // Actual IDE command. 
 BYTE bReserved;   // reserved for future use.  Must be zero. 
} IDEREGS, *PIDEREGS, *LPIDEREGS; typedef struct _SENDCMDINPARAMS { 
 DWORD cBufferSize;  // Buffer size in bytes 
 IDEREGS irDriveRegs;  // Structure with drive register values. 
 BYTE bDriveNumber;  // Physical drive number to send 
        // command to (0,1,2,3). 
 BYTE bReserved[3];  // Reserved for future expansion. 
 DWORD dwReserved[4];  // For future use. 
 //BYTE  bBuffer[1];   // Input buffer. 
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS; typedef struct _DRIVERSTATUS { 
 BYTE bDriverError;  // Error code from driver, 
        // or 0 if no error. 
 BYTE bIDEStatus;   // Contents of IDE Error register. 
        // Only valid when bDriverError 
        // is SMART_IDE_ERROR. 
 BYTE bReserved[2];  // Reserved for future expansion. 
 DWORD dwReserved[2];  // Reserved for future expansion. 
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS; typedef struct _SENDCMDOUTPARAMS { 
 DWORD    cBufferSize;  // Size of bBuffer in bytes 
 DRIVERSTATUS DriverStatus;  // Driver status structure. 
 BYTE   bBuffer[512];   // Buffer of arbitrary length 
          // in which to store the data read from the drive. 
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS; typedef struct _IDSECTOR { 
 USHORT wGenConfig; 
 USHORT wNumCyls; 
 USHORT wReserved; 
 USHORT wNumHeads; 
 USHORT wBytesPerTrack; 
 USHORT wBytesPerSector; 
 USHORT wSectorsPerTrack; 
 USHORT wVendorUnique[3]; 
 CHAR sSerialNumber[20]; 
 USHORT wBufferType; 
 USHORT wBufferSize; 
 USHORT wECCSize; 
 CHAR sFirmwareRev[8]; 
 CHAR sModelNumber[40]; 
 USHORT wMoreVendorUnique; 
 USHORT wDoubleWordIO; 
 USHORT wCapabilities; 
 USHORT wReserved1; 
 USHORT wPIOTiming; 
 USHORT wDMATiming; 
 USHORT wBS; 
 USHORT wNumCurrentCyls; 
 USHORT wNumCurrentHeads; 
 USHORT wNumCurrentSectorsPerTrack; 
 ULONG ulCurrentSectorCapacity; 
 USHORT wMultSectorStuff; 
 ULONG ulTotalAddressableSectors; 
 USHORT wSingleWordDMA; 
 USHORT wMultiWordDMA; 
 BYTE bReserved[128]; 
} IDSECTOR, *PIDSECTOR; /*+++ 
Global vars 
---*/ 
GETVERSIONOUTPARAMS vers; 
SENDCMDINPARAMS in; 
SENDCMDOUTPARAMS out; 
HANDLE h; 
DWORD i; 
BYTE j; void CopyRight(){ 
 cerr<<endl<<"HDD identifier v1.0 for WIN95/98/Me/NT/2000. written by Lu Lin"<<endl; 
 cerr<<"For more information, please visit Inside Programming: http://lu0.126.com"<<endl; 
 cerr<<"2000.11.3"<<endl<<endl; 

VOID ChangeByteOrder(PCHAR szString, USHORT uscStrSize) 
{ USHORT i; 
CHAR temp;  for (i = 0; i < uscStrSize; i+=2) 
 { 
  temp = szString[i]; 
  szString[i] = szString[i+1]; 
  szString[i+1] = temp; 
 } 
} void DetectIDE(BYTE bIDEDeviceMap){ 
 if (bIDEDeviceMap&1){ 
  if (bIDEDeviceMap&16){ 
   cout<<"ATAPI device is attached to primary controller, drive 0."<<endl; 
  }else{ 
   cout<<"IDE device is attached to primary controller, drive 0."<<endl; 
  } 
 } 
 if (bIDEDeviceMap&2){ 
  if (bIDEDeviceMap&32){ 
   cout<<"ATAPI device is attached to primary controller, drive 1."<<endl; 
  }else{ 
   cout<<"IDE device is attached to primary controller, drive 1."<<endl; 
  } 
 } 
 if (bIDEDeviceMap&4){ 
  if (bIDEDeviceMap&64){ 
   cout<<"ATAPI device is attached to secondary controller, drive 0."<<endl; 
  }else{ 
   cout<<"IDE device is attached to secondary controller, drive 0."<<endl; 
  } 
 } 
 if (bIDEDeviceMap&8){ 
  if (bIDEDeviceMap&128){ 
   cout<<"ATAPI device is attached to secondary controller, drive 1."<<endl; 
  }else{ 
   cout<<"IDE device is attached to secondary controller, drive 1."<<endl; 
  } 
 } 
} void hdid9x(){ 
 ZeroMemory(&vers,sizeof(vers)); 
 //We start in 95/98/Me 
 h=CreateFile("\\\\.\\Smartvsd",0,0,0,CREATE_NEW,0,0); 
 if (!h){ 
  cout<<"open smartvsd.vxd failed"<<endl; 
  exit(0); 
 }  if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0)){ 
  cout<<"DeviceIoControl failed:DFP_GET_VERSION"<<endl; 
  CloseHandle(h); 
  return; 
 } 
 //If IDE identify command not supported, fails 
 if (!(vers.fCapabilities&1)){ 
  cout<<"Error: IDE identify command not supported."; 
  CloseHandle(h); 
  return; 
 } 
 //Display IDE drive number detected 
 DetectIDE(vers.bIDEDeviceMap); 
 //Identify the IDE drives 
 for (j=0;j<4;j++){ 
  PIDSECTOR phdinfo; 
  char s[41];   ZeroMemory(&in,sizeof(in)); 
  ZeroMemory(&out,sizeof(out)); 
  if (j&1){ 
   in.irDriveRegs.bDriveHeadReg=0xb0; 
  }else{ 
   in.irDriveRegs.bDriveHeadReg=0xa0; 
  } 
  if (vers.fCapabilities&(16>>j)){ 
   //We don't detect a ATAPI device. 
   cout<<"Drive "<<(int)(j+1)<<" is a ATAPI device, we don't detect it"<<endl; 
   continue; 
  }else{ 
   in.irDriveRegs.bCommandReg=0xec; 
  } 
  in.bDriveNumber=j; 
  in.irDriveRegs.bSectorCountReg=1; 
  in.irDriveRegs.bSectorNumberReg=1; 
  in.cBufferSize=512; 
  if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0)){ 
   cout<<"DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA"<<endl; 
   CloseHandle(h); 
   return; 
  } 
  phdinfo=(PIDSECTOR)out.bBuffer; 
  memcpy(s,phdinfo->sModelNumber,40); 
  s[40]=0; 
  ChangeByteOrder(s,40); 
  cout<<endl<<"Module Number:"<<s<<endl; 
  memcpy(s,phdinfo->sFirmwareRev,8); 
  s[8]=0; 
  ChangeByteOrder(s,8); 
  cout<<"\tFirmware rev:"<<s<<endl; 
  memcpy(s,phdinfo->sSerialNumber,20); 
  s[20]=0; 
  ChangeByteOrder(s,20); 
  cout<<"\tSerial Number:"<<s<<endl; 
  cout<<"\tCapacity:"<<phdinfo->ulTotalAddressableSectors/2/1024<<"M"<<endl<<endl; 
 }  //Close handle before quit 
 CloseHandle(h); 
 CopyRight(); } void hdidnt(){ 
 char hd[80]; 
 PIDSECTOR phdinfo; 
 char s[41];  ZeroMemory(&vers,sizeof(vers)); 
 //We start in NT/Win2000 
 for (j=0;j<4;j++){ 
  sprintf(hd,"\\\\.\\PhysicalDrive%d",j); 
  h=CreateFile(hd,GENERIC_READ|GENERIC_WRITE, 
   FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0); 
  if (!h){ 
   continue; 
  } 
  if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0)){ 
   CloseHandle(h); 
   continue; 
  } 
  //If IDE identify command not supported, fails 
  if (!(vers.fCapabilities&1)){ 
   cout<<"Error: IDE identify command not supported."; 

解决方案 »

  1.   

    CloseHandle(h); 
       return; 
      } 
      //Identify the IDE drives 
      ZeroMemory(&in,sizeof(in)); 
      ZeroMemory(&out,sizeof(out)); 
      if (j&1){ 
       in.irDriveRegs.bDriveHeadReg=0xb0; 
      }else{ 
       in.irDriveRegs.bDriveHeadReg=0xa0; 
      } 
      if (vers.fCapabilities&(16>>j)){ 
       //We don't detect a ATAPI device. 
       cout<<"Drive "<<(int)(j+1)<<" is a ATAPI device, we don't detect it"<<endl; 
       continue; 
      }else{ 
       in.irDriveRegs.bCommandReg=0xec; 
      } 
      in.bDriveNumber=j; 
      in.irDriveRegs.bSectorCountReg=1; 
      in.irDriveRegs.bSectorNumberReg=1; 
      in.cBufferSize=512; 
      if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0)){ 
       cout<<"DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA"<<endl; 
       CloseHandle(h); 
       return; 
      } 
      phdinfo=(PIDSECTOR)out.bBuffer; 
      memcpy(s,phdinfo->sModelNumber,40); 
      s[40]=0; 
      ChangeByteOrder(s,40); 
      cout<<endl<<"Module Number:"<<s<<endl; 
      memcpy(s,phdinfo->sFirmwareRev,8); 
      s[8]=0; 
      ChangeByteOrder(s,8); 
      cout<<"\tFirmware rev:"<<s<<endl; 
      memcpy(s,phdinfo->sSerialNumber,20); 
      s[20]=0; 
      ChangeByteOrder(s,20); 
      cout<<"\tSerial Number:"<<s<<endl; 
      cout<<"\tCapacity:"<<phdinfo->ulTotalAddressableSectors/2/1024<<"M"<<endl<<endl; 
      CloseHandle(h); 
     } 
     CopyRight(); 
    } void main(){ 
     OSVERSIONINFO VersionInfo;  ZeroMemory(&VersionInfo,sizeof(VersionInfo)); 
     VersionInfo.dwOSVersionInfoSize=sizeof(VersionInfo); 
     GetVersionEx(&VersionInfo);  switch (VersionInfo.dwPlatformId){ 
     case VER_PLATFORM_WIN32s: 
      cout<<"Win32s is not supported by this programm."<<endl; 
      return; 
     case VER_PLATFORM_WIN32_WINDOWS: 
      hdid9x(); 
      return; 
     case VER_PLATFORM_WIN32_NT: 
      hdidnt(); 
      return; 
     } 

      
      

  2.   

    用java调用dll文件应该可以实现吧。这有个调用dll文件的例子。这个小例子用JNI调用了VC++做的DLL动态库。1、总体说明:
    实现一个函数,传入整形数i,返回值i*i,这个函数做在DLL中,java将通过JNI调用这个函数,传入一个参数,得到返回值。
    确定DLL的名称为calldll.dll,函数shanfei(int i)。2、编写java程序javacall.java,如下:
    public class javacall
    {
    static
    {
    System.loadLibrary("calldll");
    }public native static int shanfei(int i);public static void main(String[] args)
    {
    javacall jc = new javacall();
    int j;
    j = jc.shanfei(4);
    System.out.println(j);
    }
    }3、编译
    javac javacall.java4、生成头文件
    javah javacall
    生成javacall.h文件5、制作VC++动态库
    建立新DLL工程,程序中添加:#include "javacall.h"JNIEXPORT jint JNICALL Java_javacall_shanfei (JNIEnv *, jclass, jint p)
    {
    int j = p*p;
    return j;

    别忘了将javacall.h复制到VC工程目录中,然后编译,如果编译说找不到jni.h文件,可以将jni.h复制到工程目录中,还可将javacall.h文件中的#include <jni.h>改为#include "jni.h",再编译。6、java调用
    将生成的calldll.dll文件复制到javacall.java所在的目录中,运行
    java javacall,应该可以看到运行结果。
      

  3.   

    用一个开源的项目来解决吧jconfig
    http://blog.csdn.net/flylyke/
      

  4.   

    看很多例子都是调用本地的dll来实现的。所以想到了,用java调用dll,说实话俺不会。问问那位手拿鸡刀的兄弟吧。
      

  5.   

    cm4ever(小P) 
    你有没有现成的东西呀
      

  6.   

    我的要求就是用java实现取到硬盘的序列号,
    我再vc板块看到有这方面的程序,但是用jni不知该如何实现,好像有一些数据类型不太对