如何能读取串口硬盘序列号(出厂唯一的序列号)

导读:
  如题,在网上找也N个,在IDE 硬盘及SCSI,WIN98都没问题,唯独在串口硬盘上就不行了!
  现在串口硬盘普及了!看来读取硬盘序更号的程序也得更新下了!


C/C++ code
  
  
#define IDENTIFY_BUFFER_SIZE 512

#define IDE_ATAPI_IDENTIFY 0xA0
#define IDE_ATA_IDENTIFY 0xEC
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088

#pragma pack(1)
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;

typedef
struct _DRIVERSTATUS
{
BYTE bDriverError;
BYTE bIDEStatus;
BYTE bReserved[
2 ];
DWORD dwReserved[
2 ];
} DRIVERSTATUS,
* PDRIVERSTATUS, * LPDRIVERSTATUS;

typedef
struct _SENDCMDOUTPARAMS
{
DWORD cBufferSize;
DRIVERSTATUS DriverStatus;
BYTE bBuffer[
1 ];
} SENDCMDOUTPARAMS,
* PSENDCMDOUTPARAMS, * LPSENDCMDOUTPARAMS;

typedef
struct _IDEREGS
{
BYTE bFeaturesReg;
BYTE bSectorCountReg;
BYTE bSectorNumberReg;
BYTE bCylLowReg;
BYTE bCylHighReg;
BYTE bDriveHeadReg;
BYTE bCommandReg;
BYTE bReserved;
} IDEREGS,
* PIDEREGS, * LPIDEREGS;

typedef
struct _SENDCMDINPARAMS
{
DWORD cBufferSize;
IDEREGS irDriveRegs;
BYTE bDriveNumber;
BYTE bReserved[
3 ];
DWORD dwReserved[
4 ];
BYTE bBuffer[
1 ];
} SENDCMDINPARAMS,
* PSENDCMDINPARAMS, * LPSENDCMDINPARAMS;

#pragma pack()

void ChangeByteOrder(LPSTR lpString, int nLen)
{
USHORT i;
CHAR c;

// 63 63 72 75 6E 2E 63 6F 6D
for ( int i = 0 ; i < nLen; i += 2 )
{
c
= lpString[i];
lpString[i]
= lpString[i + 1 ];
lpString[i
+ 1 ] = c;
}
}

bool CrnGetHDSerialNumber(LPSTR lpBuf)
{
strcpy(lpBuf,
"" );

HANDLE hDevice;

if (Win32Platform == VER_PLATFORM_WIN32_NT)
// 获取第一个硬盘,如果有多个,更改PhysicalDrive?就可以了。
hDevice = CreateFile( " .//PhysicalDrive0 " ,
GENERIC_READ
| GENERIC_WRITE,
FILE_SHARE_READ
| FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0 ,
0 );
else
hDevice
= CreateFile( " .//SMARTVSD " , 0 , 0 , NULL, CREATE_NEW, 0 , 0 );

if (hDevice == INVALID_HANDLE_VALUE) return false ;

SENDCMDINPARAMS scip
= { 0 };
char szBuffer[ sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE] = { 0 };
DWORD dwBytesRet
= 0 ;
bool bSuccess = false ;
try
{
scip.cBufferSize
= IDENTIFY_BUFFER_SIZE;

scip.irDriveRegs.bSectorCountReg
= 1 ;
scip.irDriveRegs.bSectorNumberReg
= 1 ;
scip.irDriveRegs.bDriveHeadReg
= IDE_ATAPI_IDENTIFY;
scip.irDriveRegs.bCommandReg
= IDE_ATA_IDENTIFY;

if (DeviceIoControl(hDevice,
DFP_RECEIVE_DRIVE_DATA,
& scip,
sizeof (SENDCMDINPARAMS) - 1 ,
szBuffer,
sizeof (szBuffer),
& dwBytesRet,
NULL))
{
PSENDCMDOUTPARAMS pOut
= (PSENDCMDOUTPARAMS)szBuffer;
PIDSECTOR pIdSec
= (PIDSECTOR)(pOut -> bBuffer);
ChangeByteOrder(pIdSec
-> sSerialNumber, sizeof (pIdSec -> sSerialNumber));
strncpy(lpBuf, pIdSec
-> sSerialNumber, 20 );
bSuccess
= true ;
}
}
__finally
{
CloseHandle(hDevice);
}

return bSuccess;
}
// ---------------------------------------------------------------------------
// 测试一哈
void __fastcall TForm1::Button2Click(TObject * Sender)
{
char sz[ 255 ];
CrnGetHDSerialNumber(sz);
ShowMessage(String(sz).Trim());
}
---------------------------------------------------------

谢谢Aweay,2种方法都可以: 
1、直接
strncpy(lpBuf,       pIdSec->   sSerialNumber,       20);
改成
strncpy(lpBuf,       pIdSec->   sSerialNumber,       dwBytesRet);  
后面的“I”字母就没有了,
2、直接把
char       sz[255];
这句后面加入
ZeroMemory(sz,255);也没有“I”字母了
现在就想等妖哥简单介绍下原理,这个代码和妖哥网站上的有什么区别

本文转自
http://topic.csdn.net/u/20071120/01/ace8c302-4260-4be2-99d7-faba80c68e8e.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值