windows c语言 sata 序列号,【Delphi】获取IDE/SATA硬盘序列号

网上有这种代码了,只是因为写的较早,有些地方写的不那么言简意赅,而且在XE后的版本中有问题(因为Unicode字符的关系)

下面是精简修改过的代码,只取第一块硬盘的序列号,Win7 + XE 测试通过。需要先安装JwApi函数库,因为有些结构体在库中有声明了

unit uGetHDSN;

interface

uses

Windows, JwaWinIoctl;

function GetIdeSerialNumber: AnsiString;

implementation

type

TIdSector = packed record

wGenConfig: USHORT;

wNumCyls: USHORT;

wReserved: USHORT;

wNumHeads: USHORT;

wBytesPerTrack: USHORT;

wBytesPerSector: USHORT;

wSectorsPerTrack: USHORT;

wVendorUnique: array [0 .. 2] of USHORT;

sSerialNumber: array [0 .. 19] of AnsiChar;

wBufferType: USHORT;

wBufferSize: USHORT;

wECCSize: USHORT;

sFirmwareRev: array [0 .. 7] of AnsiChar;

sModelNumber: array [0 .. 39] of AnsiChar;

wMoreVendorUnique: USHORT;

wDoubleWordIO: USHORT;

wCapabilities: USHORT;

wReserved1: USHORT;

wPIOTiming: USHORT;

wDMATiming: USHORT;

wBS: USHORT;

wNumCurrentCyls: USHORT;

wNumCurrentHeads: USHORT;

wNumCurrentSectorsPerTrack: USHORT;

ulCurrentSectorCapacity: ULONG;

wMultSectorStuff: USHORT;

ulTotalAddressableSectors: ULONG;

wSingleWordDMA: USHORT;

wMultiWordDMA: USHORT;

bReserved: array [0 .. 127] of Byte;

end;

PIdSector = ^TIdSector;

const

IDE_ATA_IDENTIFY = $EC;

function LittleToBig(Data: Word): Word;

asm

xchg ah, al

end;

function GetIdeSerialNumber: AnsiString;

var

hDevice: THandle;

Size, cbBytesReturned: DWORD;

SCIP: TSendCmdInParams;

SCOP: PSendCmdOutParams;

P: PWORD;

I: Integer;

begin

Result := '';

hDevice := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or

FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

if hDevice = INVALID_HANDLE_VALUE then

Exit;

Size := SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE - 1;

SCOP := AllocMem(Size);

SCIP.irDriveRegs.bCommandReg := IDE_ATA_IDENTIFY;

if DeviceIoControl(hDevice, SMART_RCV_DRIVE_DATA, @SCIP, SizeOf(TSendCmdInParams) - 1, SCOP, Size,

cbBytesReturned, nil) = False then

begin

FreeMem(SCOP);

CloseHandle(hDevice);

Exit;

end;

// 处理一下序列号在内存中的顺序

with PIdSector(@SCOP^.bBuffer[0])^ do

begin

SetLength(Result, Length(sSerialNumber));

P := @Result[1];

CopyMemory(P, @sSerialNumber[0], Length(sSerialNumber));

for I := 1 to Length(sSerialNumber) div 2 do

begin

P^ := LittleToBig(P^);

Inc(P);

end;

end;

FreeMem(SCOP);

end;

end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值