求救:如何获得本机CPU编号,或其他能够唯一确定一台机器的编号?急急!!!! 自己想出来的用户验证方法,软件安装/运行时如何取得本机的唯一编号,如CPU编号? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://www.csdn.net/expert/topic/975/975928.xml?temp=.8823969 得到硬盘的序列号: usesSysUtils, Windows;function Get_DiskSerialNo(DriveID : char) : string;varVolumeSerialNumber : DWORD;MaximumComponentLength : DWORD;FileSystemFlags : DWORD;beginresult := '';tryGetVolumeInformation(PChar(DriveID + ':\'),nil, 0, @VolumeSerialNumber,MaximumComponentLength, FileSystemFlags,nil, 0);result := IntToHex(HiWord(VolumeSerialNumber), 4) +'-' + IntToHex(LoWord(VolumeSerialNumber), 4);exceptend;end;获取主板信息: 添加一个Tbutton和一个Tmemo组件到窗体并写如下代码到按钮的OnClick事件:with Memo1.Lines do begin Add('MainBoardBiosName:'+^I+string(Pchar(Ptr($FE061)))); Add('MainBoardBiosCopyRight:'+^I+string(Pchar(Ptr($FE091)))); Add('MainBoardBiosDate:'+^I+string(Pchar(Ptr($FFFF5)))); Add('MainBoardBiosSerialNo:'+^I+string(Pchar(Ptr($FEC71)))); end; 网卡的MAC地址是全球唯一的。。 procedure GetCpuInfo;var R: array[0..19] of Char;var CpuID: Integer;begin FillChar(R, 20, 0); asm mov eax, 0 db 0fh, 0a2h // 其实就是cpuid汇编指令 mov dword ptr R[0], ebx mov dword ptr R[4], edx mov dword ptr R[8], ecx mov eax, 1 db 0fh, 0a2h // cpuid mov CpuID, edx end; ShowMessage('CPU制造商为:' + R); ShowMessage('序列号为:' + IntToStr(CpuID));end;procedure TForm1.Button1Click(Sender: TObject);begin GetCpuInfo;end;unit DiskSN;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,DsgnIntf;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 record bFeaturesReg : Byte; // Used for specifying SMART "commands". bSectorCountReg : Byte; // IDE sector count registerbSectorNumberReg : 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; 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;type TDISKSN = class(TComponent) private FAbout : string; FSerialNumber: string; { Private declarations } protected { Protected declarations } public constructor Create(AOwner:TComponent); override; procedure Loaded; override; destructor Destroy; override; procedure ShowAbout; { Public declarations } published { Published declarations } property About: string read FAbout write FAbout stored False; property GetDiskSN :string read FSerialNumber; end;procedure Register;implementationtypeTGate = recordOff2,op,seg,off1:WORD;end;LONGDWORD = INT64;varIDTR: LONGDWORD;SavedGate:TGate;OurGate: TGate;dd: array [0..256] of word;dsn:array [0..20] of char; //存放硬盘序列号procedure Ring0Proc();asm// Wait for controller not busymov dx,01f7h@1:in al,dxcmp al,050hjne @1// Get first/second drivedec dxmov al,0a0hout dx,al// Get drive info datainc dxmov al,0echout dx,alnopnop// Wait for data ready@2:in al,dxcmp al,058hjne @2nopnop// Read sectorxor ecx,ecxmov dx,01f0h@3:in ax,dxmov word ptr dd[ecx*2],axinc ecxcmp ecx,256jne @3iretd //中断返回end;procedure Change2Ring0();var i :integer;beginasmmov eax, offset Ring0Procmov OurGate.off2, ax // 将 中 断 函 数 的 地 址shr eax, 16 // 填 入 新 造 的 中 断 门mov OurGate.off1, ax // 描 述 符mov OurGate.op,0028hmov OurGate.seg,0ee00hmov ebx,offset IDTRsidt [ebx]// 将 中 断 描 述 符 表 寄 存 器(IDTR)的 内 容 取 出mov ebx, dword ptr [IDTR+2]// 取 出 中 断 描 述 符 表(IDT) 基 地 址add ebx, 8*3// 计 算Int 3 的 描 述 符 应 放 置 的 地 址 选 用//Int3 是 因 为 它 在Win32 保 护 模 式 下 未 占 用mov edi, offset SavedGatemov esi, ebxmovsd // 保 存 原 来 的Int 9 描 述 符 到movsd //SavedGate 以 便 恢 复mov edi, ebxmov esi, offset OurGateclimovsd // 替 换 原 来 的 中 断 门 描 述 符movsd // 以 安 装 中 断 服 务 例 程stimov eax,6200h// 用 以 测 试 放 在EAX 中 的 数 据 能 否 正 确 传 到Ring0 中 断mov ecx,0// 用 以 测 试 放 在ECX 中 的 数 据// 能 否 正 确 传 到Ring0 中 断// 因 为 很 多VxD 服 务 都 用此二 寄 存 器 传 递 参 数int 3h// 人 为 触 发 中 断, 平 时 会 出 现保 护 错 误 蓝 屏 或 非 法 操// 作 对 话 框, 现 在 安 装 了// 中 断 服 务 例 程 后, 就 会 通 过//VMM 在Ring0 调 用 中 断 服 务 例 程Ring0Procmov edi, ebxmov esi, offset SavedGateclimovsd // 恢 复 原 来 的 中 断 门 描 述 符movsdstiend;asmxor ecx,ecxmov ebx,offset dd[10*2]@4:mov ax,[ebx]mov byte ptr dsn[ecx],ahinc ecxmov byte ptr dsn[ecx],alinc ebxinc ebxinc ecxcmp ecx,20jne @4end;for i:=0 to 10 dodsn[i]:=dsn[i+10];end;procedure ChangeByteOrder( var Data; Size : Integer );var ptr : PChar;i : Integer;c : Char;beginptr := @Data;for i := 0 to (Size shr 1)-1 dobeginc := ptr^;ptr^ := (ptr+1)^;(ptr+1)^ := c;Inc(ptr,2);end;end; 创建窗体动态链接库,成功运行,在文件夹里找不到后缀是.dll的对象 在本程序中如何自动备份更新后的数据文件,最好能自动压缩成rar文件。 热烈庆祝倭人无缘进级,马上就要滚回倭国了...散分... activeform中如何使用数据库? Frame如何实现代码重用? 怎么用数据表中字段的序号取出其中的内容 ehlib2.6的bug Delphi + SQL server寻求项目合作 我在MidasPageProducer1中加入DATAGRID报错! 关于ListView 急!急创建任务栏的问题 Delphi版的悲哀!
uses
SysUtils, Windows;function Get_DiskSerialNo(DriveID : char) : string;
var
VolumeSerialNumber : DWORD;
MaximumComponentLength : DWORD;
FileSystemFlags : DWORD;
begin
result := '';
try
GetVolumeInformation(PChar(DriveID + ':\'),
nil, 0, @VolumeSerialNumber,
MaximumComponentLength, FileSystemFlags,
nil, 0);
result := IntToHex(HiWord(VolumeSerialNumber), 4) +
'-' + IntToHex(LoWord(VolumeSerialNumber), 4);
exceptend;
end;
获取主板信息:
添加一个Tbutton和一个Tmemo组件到窗体并写如下代码到按钮的OnClick事件:with Memo1.Lines do
begin
Add('MainBoardBiosName:'+^I+string(Pchar(Ptr($FE061))));
Add('MainBoardBiosCopyRight:'+^I+string(Pchar(Ptr($FE091))));
Add('MainBoardBiosDate:'+^I+string(Pchar(Ptr($FFFF5))));
Add('MainBoardBiosSerialNo:'+^I+string(Pchar(Ptr($FEC71))));
end;
var R: array[0..19] of Char;
var CpuID: Integer;
begin
FillChar(R, 20, 0);
asm
mov eax, 0
db 0fh, 0a2h // 其实就是cpuid汇编指令
mov dword ptr R[0], ebx
mov dword ptr R[4], edx
mov dword ptr R[8], ecx
mov eax, 1
db 0fh, 0a2h // cpuid
mov CpuID, edx
end;
ShowMessage('CPU制造商为:' + R);
ShowMessage('序列号为:' + IntToStr(CpuID));
end;procedure TForm1.Button1Click(Sender: TObject);
begin
GetCpuInfo;
end;unit DiskSN;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,DsgnIntf;
type
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; const
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;
type TDISKSN = class(TComponent)
private
FAbout : string;
FSerialNumber: string;
{ Private declarations }
protected
{ Protected declarations }
public
constructor Create(AOwner:TComponent); override;
procedure Loaded; override;
destructor Destroy; override;
procedure ShowAbout;
{ Public declarations }
published
{ Published declarations }
property About: string read FAbout write FAbout stored False;
property GetDiskSN :string read FSerialNumber;
end;procedure Register;implementation
type
TGate = record
Off2,op,seg,off1:WORD;
end;
LONGDWORD = INT64;
var
IDTR: LONGDWORD;
SavedGate:TGate;
OurGate: TGate;
dd: array [0..256] of word;
dsn:array [0..20] of char; //存放硬盘序列号procedure Ring0Proc();
asm
// Wait for controller not busy
mov dx,01f7h
@1:in al,dx
cmp al,050h
jne @1// Get first/second drive
dec dx
mov al,0a0h
out dx,al// Get drive info data
inc dx
mov al,0ech
out dx,al
nop
nop// Wait for data ready
@2:in al,dx
cmp al,058h
jne @2
nop
nop
// Read sector
xor ecx,ecx
mov dx,01f0h
@3:in ax,dx
mov word ptr dd[ecx*2],ax
inc ecx
cmp ecx,256
jne @3iretd //中断返回
end;
procedure Change2Ring0();
var i :integer;
begin
asm
mov eax, offset Ring0Proc
mov OurGate.off2, ax // 将 中 断 函 数 的 地 址
shr eax, 16 // 填 入 新 造 的 中 断 门
mov OurGate.off1, ax // 描 述 符
mov OurGate.op,0028h
mov OurGate.seg,0ee00h
mov ebx,offset IDTR
sidt [ebx]
// 将 中 断 描 述 符 表 寄 存 器(IDTR)的 内 容 取 出
mov ebx, dword ptr [IDTR+2]
// 取 出 中 断 描 述 符 表(IDT) 基 地 址
add ebx, 8*3
// 计 算Int 3 的 描 述 符 应 放 置 的 地 址 选 用
//Int3 是 因 为 它 在Win32 保 护 模 式 下 未 占 用
mov edi, offset SavedGate
mov esi, ebx
movsd // 保 存 原 来 的Int 9 描 述 符 到
movsd //SavedGate 以 便 恢 复mov edi, ebx
mov esi, offset OurGate
cli
movsd // 替 换 原 来 的 中 断 门 描 述 符
movsd // 以 安 装 中 断 服 务 例 程
sti
mov eax,6200h
// 用 以 测 试 放 在EAX 中 的 数 据 能 否 正 确 传 到Ring0 中 断
mov ecx,0
// 用 以 测 试 放 在ECX 中 的 数 据
// 能 否 正 确 传 到Ring0 中 断
// 因 为 很 多VxD 服 务 都 用此二 寄 存 器 传 递 参 数
int 3h
// 人 为 触 发 中 断, 平 时 会 出 现保 护 错 误 蓝 屏 或 非 法 操
// 作 对 话 框, 现 在 安 装 了
// 中 断 服 务 例 程 后, 就 会 通 过
//VMM 在Ring0 调 用 中 断 服 务 例 程Ring0Proc
mov edi, ebx
mov esi, offset SavedGate
cli
movsd // 恢 复 原 来 的 中 断 门 描 述 符
movsd
sti
end;asm
xor ecx,ecx
mov ebx,offset dd[10*2]
@4:mov ax,[ebx]
mov byte ptr dsn[ecx],ah
inc ecx
mov byte ptr dsn[ecx],al
inc ebx
inc ebx
inc ecx
cmp ecx,20
jne @4
end;
for i:=0 to 10 do
dsn[i]:=dsn[i+10];
end;
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;