益友软件工作室

加密金刚锁相关技术 → C语言类技术文章 → 直接从RING3获取硬盘序列号

直接从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.";

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;

}

}

特别申明

本栏目的文章都是本人从网上搜集而来,仅供大家学习研究之用,请不要用于商业目的!其中署名“佚名”的,意思是作者不详。如果某些文章未署你的名字,请来信告知,我会补上的。如果你认为某些文章侵犯了你的正当权宜,也请来信,我会将它删除。