有什么方法能获得当前机器的硬盘序列号呢?
各位大虾帮帮忙啊!!!谢谢啦。
各位大虾帮帮忙啊!!!谢谢啦。
解决方案 »
- 咨询一个OLE灾难性故障的问题
- 关于软件狗的问题
- 我问两个重要问题。有人用delphi2010开发项目没?正式版?还有D它爸爸anders hejlsberg真的要回来否?
- indy服务端和客户端的数据传输的问题.非常着急,高分相送!谢谢.(因为不能超过100,肯定会另外送分100!谢谢)
- 分时间段计费问题
- 谁有不用安装adobe reader即可看pdf文件的插件给我一用,马上结贴。
- 迷茫中请高手指点在哪寻MSCOMM控件?
- 怎样向memo控件的当前位置加字符串
- 问一个关于cxGrid控件的问题
- 项目后天验收,还有几个问题困扰,高手中手低手看进来
- DelphiX for Delphi6 的安装
- 星期一的提问:这个SQL语句怎么写?困扰许久,在线等待!
unit Unit_Main;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTSrbIoControl = packed recordHeaderLength: ULONG;Signature: array[0..7] of Char;Timeout: ULONG;ControlCode: ULONG;ReturnCode: ULONG;Length: ULONG;end;SRB_IO_CONTROL = TSrbIoControl;PSrbIoControl = ^TSrbIoControl;TIDERegs = packed recordbFeaturesReg: Byte; // Used for specifying SMART "commands".bSectorCountReg: Byte; // IDE sector count registerbSectorNumberReg: Byte; // IDE sector number registerbCylLowReg: Byte; // IDE low order cylinder valuebCylHighReg: Byte; // IDE high order cylinder valuebDriveHeadReg: Byte; // IDE drive/head registerbCommandReg: Byte; // Actual IDE command.bReserved: Byte; // reserved. Must be zero.end;IDEREGS = TIDERegs;PIDERegs = ^TIDERegs;TSendCmdInParams = packed recordcBufferSize: DWORD;irDriveRegs: TIDERegs;bDriveNumber: Byte;bReserved: array[0..2] of Byte;dwReserved: array[0..3] of DWORD;bBuffer: array[0..0] of Byte;end;SENDCMDINPARAMS = TSendCmdInParams;PSendCmdInParams = ^TSendCmdInParams;TIdSector = packed recordwGenConfig: Word;wNumCyls: Word;wReserved: Word;wNumHeads: Word;wBytesPerTrack: Word;wBytesPerSector: Word;wSectorsPerTrack: Word;wVendorUnique: array[0..2] of Word;sSerialNumber: array[0..19] of Char;wBufferType: Word;wBufferSize: Word;wECCSize: Word;sFirmwareRev: array[0..7] of Char;sModelNumber: array[0..39] of Char;wMoreVendorUnique: Word;wDoubleWordIO: Word;wCapabilities: Word;wReserved1: Word;wPIOTiming: Word;wDMATiming: Word;wBS: Word;wNumCurrentCyls: Word;wNumCurrentHeads: Word;wNumCurrentSectorsPerTrack: Word;ulCurrentSectorCapacity: ULONG;wMultSectorStuff: Word;ulTotalAddressableSectors: ULONG;wSingleWordDMA: Word;wMultiWordDMA: Word;bReserved: array[0..127] of Byte;end;PIdSector = ^TIdSector;constIDE_ID_FUNCTION = $EC;IDENTIFY_BUFFER_SIZE = 512;DFP_RECEIVE_DRIVE_DATA = $0007C088;IOCTL_SCSI_MINIPORT = $0004D008;IOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501;DataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE;BufferSize = SizeOf(SRB_IO_CONTROL) + DataSize;W9xBufferSize = IDENTIFY_BUFFER_SIZE + 16;typeTForm_Main = class(TForm)Edit_HardDiskNumber: TEdit;Label1: TLabel;Button_Get: TButton;procedure Button_GetClick(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm_Main: TForm_Main;implementation{$R *.dfm}function GetIdeDiskSerialNumber: string;typeTSrbIoControl = packed recordHeaderLength: ULONG;Signature: array[0..7] of Char;Timeout: ULONG;ControlCode: ULONG;ReturnCode: ULONG;Length: ULONG;end;SRB_IO_CONTROL = TSrbIoControl;PSrbIoControl = ^TSrbIoControl;TIDERegs = packed recordbFeaturesReg: Byte; // Used for specifying SMART "commands".bSectorCountReg: Byte; // IDE sector count registerbSectorNumberReg: Byte; // IDE sector number registerbCylLowReg: Byte; // IDE low order cylinder valuebCylHighReg: Byte; // IDE high order cylinder valuebDriveHeadReg: Byte; // IDE drive/head registerbCommandReg: Byte; // Actual IDE command.bReserved: Byte; // reserved for future use. Must be zero.end;IDEREGS = TIDERegs;PIDERegs = ^TIDERegs;TSendCmdInParams = packed recordcBufferSize: DWORD; // Buffer size in bytesirDriveRegs: TIDERegs; // Structure with drive register values.bDriveNumber: Byte; // Physical drive number to send command to (0,1,2,3).bReserved: array[0..2] of Byte; // Reserved for future expansion.dwReserved: array[0..3] of DWORD; // For future use.bBuffer: array[0..0] of Byte; // Input buffer.end;SENDCMDINPARAMS = TSendCmdInParams;PSendCmdInParams = ^TSendCmdInParams;
请问高人以上的代码是从哪里弄来的啊,怎么这么复杂哦?哈哈
const
IDENTIFY_BUFFER_SIZE = 512;
type
TIDERegs = packed record
bFeaturesReg : BYTE; // Used for specifying SMART "commands".
bSectorCountReg : BYTE; // IDE sector count register
bSectorNumberReg : BYTE; // IDE sector number register
bCylLowReg : BYTE; // IDE low order cylinder value
bCylHighReg : BYTE; // IDE high order cylinder value
bDriveHeadReg : BYTE; // IDE drive/head register
bCommandReg : BYTE; // Actual IDE command.
bReserved : BYTE; // reserved for future use. Must be zero.
end;
TSendCmdInParams = packed record
// Buffer size in bytes
cBufferSize : DWORD;
// Structure with drive register values.
irDriveRegs : TIDERegs;
// Physical drive number to send command to (0,1,2,3).
bDriveNumber : BYTE;
bReserved : Array[0..2] of Byte;
dwReserved : Array[0..3] of DWORD;
bBuffer : Array[0..0] of Byte; // Input buffer.
end;
TIdSector = packed record
wGenConfig : Word;
wNumCyls : Word;
wReserved : Word;
wNumHeads : Word;
wBytesPerTrack : Word;
wBytesPerSector : Word;
wSectorsPerTrack : Word;
wVendorUnique : Array[0..2] of Word;
sSerialNumber : Array[0..19] of Char;
wBufferType : Word;
wBufferSize : Word;
wECCSize : Word;
sFirmwareRev : Array[0..7] of Char;
sModelNumber : Array[0..39] of Char;
wMoreVendorUnique : Word;
wDoubleWordIO : Word;
wCapabilities : Word;
wReserved1 : Word;
wPIOTiming : Word;
wDMATiming : Word;
wBS : Word;
wNumCurrentCyls : Word;
wNumCurrentHeads : Word;
wNumCurrentSectorsPerTrack : Word;
ulCurrentSectorCapacity : DWORD;
wMultSectorStuff : Word;
ulTotalAddressableSectors : DWORD;
wSingleWordDMA : Word;
wMultiWordDMA : Word;
bReserved : Array[0..127] of BYTE;
end;
PIdSector = ^TIdSector;
TDriverStatus = packed record
// 0
bDriverError : Byte;
// IDEbDriverError SMART_IDE_ERROR
bIDEStatus : Byte;
bReserved : Array[0..1] of Byte;
dwReserved : Array[0..1] of DWORD;
end;
TSendCmdOutParams = packed record
// bBuffer
cBufferSize : DWORD;
//
DriverStatus : TDriverStatus;
// cBufferSize
bBuffer : Array[0..0] of BYTE;
end;
var
hDevice : THandle;
cbBytesReturned : DWORD;
//ptr : PVarChar;
SCIP : TSendCmdInParams;
aIdOutCmd : Array [0..(SizeOf(TSendCmdOutParams)+IDENTIFY_BUFFER_SIZE-1)-1] of Byte;
IdOutCmd : TSendCmdOutParams absolute aIdOutCmd;
procedure ChangeByteOrder( var Data; Size : Integer );
var
ptr : PChar;
i : Integer;
c : Char;
begin
ptr := @Data;
for i := 0 to (Size shr 1)-1 do begin
c := ptr^;
ptr^ := (ptr+1)^;
(ptr+1)^ := c;
Inc(ptr,2);
end;
end; //end of ChangeByteOrder
begin
Result := ''; //
if SysUtils.Win32Platform=VER_PLATFORM_WIN32_NT then begin// Windows NT, Windows 2000
// ! '\\.\PhysicalDrive1\'
hDevice := CreateFile( '\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );
end else // Version Windows 95 OSR2, Windows 98
hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 );
if hDevice=INVALID_HANDLE_VALUE then Exit;
try
FillChar(SCIP,SizeOf(TSendCmdInParams)-1,#0);
FillChar(aIdOutCmd,SizeOf(aIdOutCmd),#0);
cbBytesReturned := 0;
// Set up data structures for IDENTIFY command.
with SCIP do begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
// bDriveNumber := 0;
with irDriveRegs do begin
bSectorCountReg := 1;
bSectorNumberReg := 1;
// if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0
// else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);
bDriveHeadReg := $A0;
bCommandReg := $EC;
end;
end;
if not DeviceIoControl( hDevice, $0007c088, @SCIP, SizeOf(TSendCmdInParams)-1,
@aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil ) then Exit;
finally
CloseHandle(hDevice);
end;
with PIdSector(@IdOutCmd.bBuffer)^ do begin
ChangeByteOrder( sSerialNumber, SizeOf(sSerialNumber) );
(PChar(@sSerialNumber)+SizeOf(sSerialNumber))^ := #0;
Result := PChar(@sSerialNumber);
end;
end;//End of GetIdeSerialNumber
function tform1.GetHDSerialNumber: LongInt; {$IFDEF WIN32} var pdw : pDWord; mc, fl : dword; {$ENDIF} begin {$IfDef WIN32} New(pdw); GetVolumeInformation('c:\',nil,0,pdw,mc,fl,nil,0); Result := pdw^; dispose(pdw); {$ELSE} Result := GetWinFlags; {$ENDIF} end;
Windows,SysUtils;function getIDEHardDiskSN: string;
type
{*******Use in Win2k ****************}
TSrbIoControl = packed record
HeaderLength: ULONG;
Signature: array[0..7] of Char;
Timeout: ULONG;
ControlCode: ULONG;
ReturnCode: ULONG;
Length: ULONG;
end;
SRB_IO_CONTROL = TSrbIoControl;
PSrbIoControl = ^TSrbIoControl;TIDERegs = packed record
bFeaturesReg: Byte; // Used for specifying SMART "commands".
bSectorCountReg: Byte; // IDE sector count register
bSectorNumberReg: Byte; // IDE sector number register
bCylLowReg: Byte; // IDE low order cylinder value
bCylHighReg: Byte; // IDE high order cylinder value
bDriveHeadReg: Byte; // IDE drive/head register
bCommandReg: Byte; // Actual IDE command.
bReserved: Byte; // reserved. Must be zero.
end;
IDEREGS = TIDERegs;
PIDERegs = ^TIDERegs;TSendCmdInParams = packed record
cBufferSize: DWORD;
irDriveRegs: TIDERegs;
bDriveNumber: Byte;
bReserved: array[0..2] of Byte;
dwReserved: array[0..3] of DWORD;
bBuffer: array[0..0] of Byte;
end;
SENDCMDINPARAMS = TSendCmdInParams;
PSendCmdInParams = ^TSendCmdInParams;TIdSector = packed record
wGenConfig: Word;
wNumCyls: Word;
wReserved: Word;
wNumHeads: Word;
wBytesPerTrack: Word;
wBytesPerSector: Word;
wSectorsPerTrack: Word;
wVendorUnique: array[0..2] of Word;
sSerialNumber: array[0..19] of Char;
wBufferType: Word;
wBufferSize: Word;
wECCSize: Word;
sFirmwareRev: array[0..7] of Char;
sModelNumber: array[0..39] of Char;
wMoreVendorUnique: Word;
wDoubleWordIO: Word;
wCapabilities: Word;
wReserved1: Word;
wPIOTiming: Word;
wDMATiming: Word;
wBS: Word;
wNumCurrentCyls: Word;
wNumCurrentHeads: Word;
wNumCurrentSectorsPerTrack: Word;
ulCurrentSectorCapacity: ULONG;
wMultSectorStuff: Word;
ulTotalAddressableSectors: ULONG;
wSingleWordDMA: Word;
wMultiWordDMA: Word;
bReserved: array[0..127] of Byte;
end;
PIdSector = ^TIdSector;{************end Win2k*****************}const
{********** Use in Win2k **********}
IDE_ID_FUNCTION = $EC;
IDENTIFY_BUFFER_SIZE = 512;
DFP_RECEIVE_DRIVE_DATA = $0007C088;
IOCTL_SCSI_MINIPORT = $0004D008;
IOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501;
DataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE;
BufferSize = SizeOf(SRB_IO_CONTROL) + DataSize;
W9xBufferSize = IDENTIFY_BUFFER_SIZE + 16;
{********* End Win2k***************}{********* Use in Win9x ***********}
hookexceptionno = 5;
{********* End in Win9x************}var{********* Use in Win9x ***********}
pw: array[0..255] of Word; // pw[256];
idtr_1: array[0..5] of Byte; //保存中断描述符表寄存器
oldexceptionhook: DWord; //保存原先的中断入口地址
IdeBase: Word;
SelectDisk: Integer;
ErrNo: Integer = 0;
{********* End in Win9x************}implementation{********* Use in Win9x ***********}function inp(rdx: Word): Byte;
asm
mov dx, rdx
in al, dx
end;function inpw(rdx: Word): Word;
asm
mov dx, rdx
in ax, dx
end;procedure outp(ral: Byte; rdx: Word);
asm
mov dx, rdx
mov al, ral
out dx, al
end;function WaitIde: Byte;
var
al: Byte;
begin
repeat
al := inp(IdeBase + 7);
until (al < $80) or (al = $A0); //$a0可能就没有硬盘
WaitIde := al;
end;procedure ReadIDE;
var
al: Byte;
i: Integer;
begin
WaitIde;
outp(SelectDisk, IdeBase + 6);
al := WaitIde;
if ((al and $50) <> $50) then
begin
ErrNo := 1;
exit;
end;
outp(SelectDisk, IdeBase + 6);
outp($EC, IdeBase + 7);
al := WaitIde;
if ((al and $58) <> $58) then
begin
ErrNo := 2;
exit;
end;
for i := 0 to 255 do
begin
pw[i] := inpw(IdeBase);
end;
end;// 新的中断处理程序procedure ReadIt; assembler;
asm
push eax
push ebx
push ecx
push edx
push esi
push edi
// 在这里写读程序
call ReadIDE
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
end;procedure GetSerialNo; assembler;
asm
push eax
// 获取修改的中断的中断描述符(中断门)地址
sidt idtr_1
mov eax,dword ptr idtr_1+02h
add eax,hookexceptionno*08h+04h
// 保存原先的中断入口地址
cli
push ecx
mov ecx,dword ptr [eax]
mov cx,word ptr [eax-04h]
mov dword ptr oldexceptionhook,ecx
pop ecx
// 设置修改的中断入口地址为新的中断处理程序入口地址
push ebx
lea ebx,ReadIt
mov word ptr [eax-04h],bx
shr ebx,10h
mov word ptr [eax+02h],bx
pop ebx
// 执行中断,转到ring 0(与cih 病毒原理相似!)
push ebx
int hookexceptionno
pop ebx
// 恢复原先的中断入口地址
push ecx
mov ecx,dword ptr oldexceptionhook
mov word ptr [eax-04h],cx
shr ecx,10h
mov word ptr [eax+02h],cx
pop ecx
// 结束
sti
pop eax
ret
end;procedure GetIdeDiskSN9X(DriverNo: integer; var s: string);
var
i: Integer;
begin
{如果有多硬盘一般可能有4个硬盘,也可能多至8个硬盘}
ErrNo := 0;
fillchar(pw, sizeof(pw), 0);
s := '';{设置基址,
4,5:IdeBase := $1e8;
6,7:IdeBase := $168;}
case DriverNo of
0, 1: IdeBase := $1F0;
2, 3: IdeBase := $170;
end;{ 指定主从,Driver No 是奇数为$B0,偶数为$A0}
case DriverNo of
0, 2: SelectDisk := $A0;
1, 3: SelectDisk := $B0;
end; GetSerialNo;
if ErrNo <> 0 then
Exit; //读错误
if (pw[0] = 0) then
s := ''
else
for i := 10 to 20 do
begin
s := s + char(pw[i] shr 8) + char(pw[i] and $FF);
end;
end;
{********* End in Win9x************}{*******Use in Win2k ****************}procedure ChangeByteOrder(var Data; Size: Integer);
var
ptr: PChar;
i: Integer;
c: Char;
begin
ptr := @Data;
for i := 0 to (Size shr 1) - 1 do
begin
c := ptr^;
ptr^ := (ptr + 1)^;
(ptr + 1)^ := c;
Inc(ptr, 2);
end;
end;
{ Windows NT, Windows 2000
通过MS的S.M.A.R.T.接口,直接从RING3调用
API DeviceIoControl()来获取硬盘信息
Get SCSI port handle}function GetIdeDiskSNNT: string;
var
hDevice: THandle;
cbBytesReturned: DWORD;
pInData: PSendCmdInParams;
pOutData: Pointer; // PSendCmdOutParams
Buffer: array[0..BufferSize - 1] of Byte;
srbControl: TSrbIoControl absolute Buffer;
begin
Result := '';
FillChar(Buffer, BufferSize, #0); hDevice := CreateFile('\.Scsi0:', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
0, 0);
if hDevice = INVALID_HANDLE_VALUE then Exit;
try
srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
System.Move('SCSIDISK', srbControl.Signature, 8);
srbControl.Timeout := 2;
srbControl.Length := DataSize;
srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;
pInData := PSendCmdInParams(PChar(@Buffer) + SizeOf(SRB_IO_CONTROL));
pOutData := pInData;
with pInData^ do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
bDriveNumber := 0;
with irDriveRegs do
begin
bFeaturesReg := 0;
bSectorCountReg := 1;
bSectorNumberReg := 1;
bCylLowReg := 0;
bCylHighReg := 0;
bDriveHeadReg := $A0;
bCommandReg := IDE_ID_FUNCTION;
end;
end;
if not DeviceIoControl(hDevice, IOCTL_SCSI_MINIPORT, @Buffer, BufferSize,
@Buffer, BufferSize, cbBytesReturned, nil) then
Exit;
finally
CloseHandle(hDevice);
end; with PIdSector(PChar(pOutData) + 16)^ do
begin
ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
SetString(Result, sSerialNumber, SizeOf(sSerialNumber));
end;
Result := Trim(Result);
end;
{********* End in Win2k************}function getIDEHardDiskSN: string;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
Result := getIDEDiskSNNT
else if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
getIDEDiskSN9x(0, Result)
else
Result := '';
end;end.