原创
编程获取硬盘序列号
2008-4-7 13:19
6872
6
9
分类:
软件与OS
昨天查了查网上的文章,发现有人已经提出通过向磁盘驱动程序发送Ioctl请求来获取硬盘序列号的。参考别人的
代码,把那个获取硬盘序列号的程序写出来了,测试通过。
下面的API函数用于获取硬盘序列号:
SYSINFO_API BOOL GetHardDiskSerialNumber(char *buffer,int DiskNum)
{
DWORD dwDataBuf[256];
WORD wDataBuf[256];
char SerialNum[256];
int i,j;
if(!GetIdeDiskInformation(dwDataBuf,DiskNum)){
if(!GetScsiDiskInformation(dwDataBuf,DiskNum)){
SysInfoDebug("GetHardDiskSerialNumber--failed");
return FALSE;
}
}
for(i=0;i<256;i++)
wDataBuf=(WORD)dwDataBuf;
/* convert WORD data to char array(string)*/
i=ConvertToString(wDataBuf,27,46,SerialNum,0);
SerialNum='-';
j=ConvertToString(wDataBuf,10,19,SerialNum,i+1);
SerialNum[j]='-';
ConvertToString(wDataBuf,23,26,SerialNum,j+1);
strcpy(buffer,SerialNum);
return TRUE;
}
首先调用GetIdeDiskInformation来获取IDE硬盘的信息,如果系统没有IDE硬盘,那么再用GetScsiDiskInformation试图获取
Scsi硬盘的信息,两者都找不到就返回FALSE。找到信息后,调用ConvertToString把序列号相关的信息转换为string
存在buffer参数指定的内存中,返回给调用者。
GetIdeDiskInformation的代码如下:
/*get IDE disk infromation
Arguments:
* buffer--return the IDE disk first sector information
* DiskNum--IDE disk number, must between 0 and MAX_IDE_DISK
*return:
* FALSE---can't get infromation
* TRUE---successfully, the buffer contains all information we need
*/
BOOL GetIdeDiskInformation(DWORD *buffer, int DiskNum)
{
char szIdeDeviceName[32];
HANDLE hIdeDriver;
DWORD dwByteRet;
GETVERSIONOUTPARAMS VersionParam;
SENDCMDINPARAMS InParam;
BYTE bIdCmd;
BYTE OutBuf[sizeof(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE-1];
int i;
USHORT *pIdSector;
if((DiskNum>MAX_IDE_DISK-1)||(DiskNum<0)){
SysInfoDebug(" GetIdeDiskInformation--Invalid Disk Number");
return FALSE;
}
sprintf(szIdeDeviceName,"\\\\.\\PhysicalDrive%d",DiskNum);
hIdeDriver=CreateFile(szIdeDeviceName,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(hIdeDriver!=INVALID_HANDLE_VALUE){
SysInfoDebug("GetIdeDiskInformation--Open Disk success");
memset((void*)&VersionParam,0,sizeof(VersionParam));
if(DeviceIoControl(hIdeDriver,SMART_GET_VERSION,NULL,0,&VersionParam,
sizeof(VersionParam),&dwByteRet,NULL)){
if(VersionParam.bIDEDeviceMap > 0){
bIdCmd=(VersionParam.bIDEDeviceMap>>DiskNum&0x10)?IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
memset((void*)&InParam,0,sizeof(InParam));
memset((void*)OutBuf,0,sizeof(OutBuf));
if(DoIdentify(hIdeDriver,&InParam,(PSENDCMDOUTPARAMS)&OutBuf,bIdCmd,(BYTE)DiskNum,&dwByteRet)){
pIdSector=(USHORT *)((PSENDCMDOUTPARAMS)OutBuf)->bBuffer;
for(i=0;i<256;i++)
buffer=pIdSector;
SysInfoDebug("GetIdeDiskInformation--get disk information success");
return TRUE;
}
}
}
}
SysInfoDebug("GetIdeDiskInformation--cannot get disk information");
return FALSE;
}
其中调用了DoIdentify这个辅助函数,代码如下:
BOOL DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd, BYTE btDriveNum,
PDWORD pdwBytesReturned)
{
// Set up data structures for IDENTIFY command.
pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
pSCIP->irDriveRegs.bFeaturesReg = 0;
pSCIP->irDriveRegs.bSectorCountReg = 1;
pSCIP->irDriveRegs.bSectorNumberReg = 1;
pSCIP->irDriveRegs.bCylLowReg = 0;
pSCIP->irDriveRegs.bCylHighReg = 0;
// Compute the drive number.
pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0;
// The command can either be IDE identify or ATAPI identify.
pSCIP->irDriveRegs.bCommandReg = btIDCmd;
pSCIP->bDriveNumber = btDriveNum;
pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
return (DeviceIoControl(hPhysicalDriveIOCTL, SMART_RCV_DRIVE_DATA,
(LPVOID)pSCIP,
sizeof(SENDCMDINPARAMS) - 1,
(LPVOID)pSCOP,
sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
pdwBytesReturned, NULL));
}
而GetScsiDiskInformation的代码如下:
/* get scsi disk information ,if any
* we query scsi miniport driver to get these information
* Arguments:
* buffer--return the scsi disk first sector information
* DiskNum--scsi disk number, must between 0 and MAX_SCSI_DISK
*return:
* FALSE---can't get infromation
* TRUE---successfully, the buffer contains all information we need
*/
BOOL GetScsiDiskInformation(DWORD *buffer,int DiskNum)
{
HANDLE hScsiDriver;
int j;
DWORD dwByteRet;
char szScsiDeviceName[32];
char tmpbuf[sizeof(SRB_IO_CONTROL)+SENDIDLENGTH];
SRB_IO_CONTROL *pSrb=(SRB_IO_CONTROL *)tmpbuf;
SENDCMDINPARAMS *pin=(SENDCMDINPARAMS *)(tmpbuf+sizeof(SRB_IO_CONTROL));
SENDCMDOUTPARAMS *pout;
IDSECTOR *pid;
USHORT * pIdSector;
if((DiskNum>MAX_SCSI_DISK-1)||(DiskNum<0)){
SysInfoDebug("GetScsiDiskInformation--Invalid disk number");
return FALSE;
}
sprintf(szScsiDeviceName,"\\\\.\\SCSI%d:",DiskNum);
hScsiDriver=CreateFile(szScsiDeviceName,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(hScsiDriver!=INVALID_HANDLE_VALUE){
SysInfoDebug("GetScsiDiskInformation--Open disk success");
memset(tmpbuf,0,sizeof(tmpbuf));
pSrb->HeaderLength=sizeof(SRB_IO_CONTROL);
pSrb->Timeout=10000;
pSrb->Length=SENDIDLENGTH;
pSrb->ControlCode=IOCTL_SCSI_MINIPORT_IDENTIFY;
strncpy((char*)pSrb->Signature,"SCSIDISK",8);
pin->bDriveNumber=DiskNum;
pin->irDriveRegs.bCommandReg=IDE_ATA_IDENTIFY;
if(DeviceIoControl(hScsiDriver,IOCTL_SCSI_MINIPORT,tmpbuf,sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDINPARAMS)-1,
tmpbuf,sizeof(tmpbuf),&dwByteRet,NULL)){
pout=(SENDCMDOUTPARAMS *)(tmpbuf+sizeof(SRB_IO_CONTROL));
pid=(IDSECTOR *)(pout->bBuffer);
if(pid->sModelNumber[0]){
pIdSector=(USHORT *)pid;
for(j=0;j<256;j++)
buffer[j]=(char)pIdSector[j];
CloseHandle(hScsiDriver);
return TRUE;
}
}
CloseHandle(hScsiDriver);
}
SysInfoDebug("GetScsiDiskInformation--Can not Get Disk Information");
return FALSE;
}
关闭
站长推荐
/2
用户1361860 2009-3-9 13:42
用户180278 2009-3-3 21:38
用户180278 2009-3-3 21:34