导读:
如题,在网上找也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