////////// 获得硬盘内部SN以下是lu0的主页上的(http://best.163.com/~lulin)直接从RING3获取硬盘序列号 
作者:陆麟 
转载请征得作者同意. 
2000.11.3 
PATCHED 11.19 
--------------------------------------------------------------------------------通常情况下,我们通过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."; 
  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; 


   ///////////// 获得网卡卡号
在VC工程中加入Netapi32.lib
#include "Nb30.h"
typedef struct _ASTAT_
{
    ADAPTER_STATUS adapt;
    NAME_BUFFER NameBuff [30];
}ASTAT, * PASTAT;
void GetMacCode (int lana_num, char* pArray)
{
    NCB ncb;
    UCHAR uRetCode;
    ASTAT Adapter;
    memset( &ncb, 0, sizeof(ncb) );
    ncb.ncb_command = NCBRESET;
    ncb.ncb_lana_num = lana_num; 
    
    uRetCode = Netbios( &ncb );
    
    memset( &ncb, 0, sizeof(ncb) );
    ncb.ncb_command = NCBASTAT;
    ncb.ncb_lana_num = lana_num; 
    strcpy((char *)ncb.ncb_callname,"*" );        
        ncb.ncb_buffer = (unsigned char *) &Adapter; 
    ncb.ncb_length = sizeof(Adapter);
    
    uRetCode = Netbios( &ncb );
    if ( uRetCode == 0 )
    {
        // Transform the MAC Address to the form like 0010-A4E4-5802
        sprintf(pArray,"%02X-%02X-%02X-%02X-%02X-%02X",
            Adapter.adapt.adapter_address[0],
            Adapter.adapt.adapter_address[1],
            Adapter.adapt.adapter_address[2],
            Adapter.adapt.adapter_address[3],
            Adapter.adapt.adapter_address[4],
            Adapter.adapt.adapter_address[5] );
    }
    else
        strcpy(pArray,"");
}    
BOOL CGetmacDlg::OnInitDialog()
{
    CDialog::OnInitDialog();    // Add "About..." menu item to system menu.    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    
    // TODO: Add extra initialization here
    char buf[20];
    NCB ncb;
    UCHAR uRetCode;
    LANA_ENUM lana_enum;
    memset( &ncb, 0, sizeof(ncb) );
    ncb.ncb_command = NCBENUM;
    ncb.ncb_buffer = (unsigned char *) &lana_enum;
    ncb.ncb_length = sizeof(lana_enum);
    uRetCode = Netbios( &ncb );
    if (lana_enum.length==0)    // No NetAdapter
        return -2;
    
    if ( uRetCode == 0 )
    {
        for ( int i=0; i<lana_enum.length; ++i)
        {
            GetMacCode( lana_enum.lana[i],buf);
            if (i==0)
                m_sMac=buf;//CString m_sMac
        }
    }    
    UpdateData(FALSE);
    return TRUE;  // return TRUE  unless you set the focus to a control
}