如何获取本机的cpu序列号和硬盘序列号来对软件进行加密?

honghust 2008-12-26 09:51:33
看到那中调用asm程序获取cpu的序列号还有createfile获取硬盘序列号的方法,不是太懂,哪位懂的帮忙贴出可用的代码并讲一下,谢谢。
...全文
2085 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
csdnstudyc 2009-02-07
  • 打赏
  • 举报
回复
用这个做为加密条件,没有意义,因为不是唯一
castlooo 2009-02-07
  • 打赏
  • 举报
回复
mark
windsky0821 2009-01-22
  • 打赏
  • 举报
回复
学习了
shiweifu 2009-01-21
  • 打赏
  • 举报
回复
LZ可以去看下
www.cppfans.com
这里面有些读取端口的实例。
里面有获取一些硬件信息的功能
是使用WINIO.DLL来实现的
shiweifu 2009-01-21
  • 打赏
  • 举报
回复
支持19L的
shiweifu 2009-01-21
  • 打赏
  • 举报
回复
支持19L的
志山之家 2009-01-21
  • 打赏
  • 举报
回复
有c++builder的代码吗?
jiangshx 2009-01-16
  • 打赏
  • 举报
回复
加密是必须的,即使客户群没这个能力,但同行也有这个能力不是?
加密尽量复杂化,即使别人能破,也让他多花个八月的时间。
lovetsfuer 2009-01-14
  • 打赏
  • 举报
回复
还防着人家破解吗?根本就不要想,你的客户群在哪?客户一般情况下都是一般的电脑使用者,没必要那么较真,够用就可以了
flymoon99 2009-01-12
  • 打赏
  • 举报
回复
- -!不知道你那个啥软件,还需要用到硬件加密,现在外面卖的大部分软件不都是用软件加密么,呵呵。
honghust 2009-01-09
  • 打赏
  • 举报
回复
谢谢各位了,小弟现在放弃了采用软加密的方式,现在在看硬件加密方面的书籍,但是发现,如果真像书中所说,其实硬件加密也不是那么安全。 加密->难啊!!
星光伴月 2009-01-06
  • 打赏
  • 举报
回复

add eax,HookExceptionNo * 08h + 04h//这一行里的HookExceptionNo 是一个宏,值为3
//改为:
add eax,HookExceptionNo * 08h + 04h//这一行里的HookExceptionNo 是一个宏,值为3


调用函数:
unsigned short DiskInfo[256];

if(GetDiskInfo_9x(0,DiskInfo))
{
//这里处理DiskInfo包含的序列号
}
星光伴月 2009-01-06
  • 打赏
  • 举报
回复
给你一个C/C++函数:(Win9x的)
bool GetDiskInfo_9x(int iDriver,unsigned short *DiskData)
{
const unsigned char cBusy=0x80;
const unsigned short BaseAddress[4]={0x01f0,0x0170,0x01e8,0x0168}; //IDE插槽口号
const unsigned int MastOrSalve[2]={0x0a0,0x0b0}; //Master or Salve
unsigned short OutData[256];
unsigned short BaseAddr = BaseAddress[iDriver/2];
unsigned char MOS = MastOrSalve[iDriver%2];
unsigned char idtr[6];
unsigned long oldExceptionHook;
bool bSuccess;
__asm
{
mov bSuccess,0
jmp EnterRing0
WaitWhileBusy:
mov ebx,100000
mov dx,BaseAddr
add dx,7
LoopWhileBusy:
dec ebx
cmp ebx,0
jz Timeout
in al,dx
test al,cBusy
jnz LoopWhileBusy
jmp DriveReady
Timeout:
jmp LeaveRing0_wait
DriveReady:
ret

LeaveRing0_wait:
popad
iretd

SelectDevice:
mov dx,BaseAddr
add dx,6
mov al,MOS
out dx,al
ret

SendCmd:
mov dx,BaseAddr
add dx,7
mov al,bl
out dx,al
ret

Ring0Proc:
pushad

mov dx,BaseAddr
add dx,7
in al,dx

cmp al,0ffh
jz LeaveRing0
cmp al,07fh
jz LeaveRing0

call WaitWhileBusy
call SelectDevice
call WaitWhileBusy

test al,040h
jz LeaveRing0

call WaitWhileBusy
call SelectDevice
mov bl,0ech
call SendCmd
call WaitWhileBusy

mov dx, BaseAddr
add dx,7
in al,dx
test al,01h
jz ReadDiskInfo

call WaitWhileBusy
call SelectDevice
mov bl,0a1h
call SendCmd
call WaitWhileBusy

mov dx,BaseAddr
add dx,7
in al,dx
test al,01h
jz ReadDiskInfo
jmp LeaveRing0

ReadDiskInfo:
lea edi,OutData
mov ecx,256
mov dx,BaseAddr
cld
rep insw
mov bSuccess,1

LeaveRing0:
popad
iretd

EnterRing0:
sidt fword ptr idtr
mov eax,dword ptr idtr + 02h
add eax,HookExceptionNo * 08h + 04h//这一行里的HookExceptionNo 是一个宏,值为3
cli

mov ecx,dword ptr [eax]
mov cx,word ptr [eax-04h]
mov oldExceptionHook,ecx

lea ebx,Ring0Proc
mov word ptr [eax-04h],bx
shr ebx,10h
mov word ptr[eax+02h],bx

int HookExceptionNo

mov ecx,oldExceptionHook
mov word ptr[eax-04h],cx
shr ecx,10h
mov word ptr[eax+02h],cx
sti
}

for(int i=0;i<256;i++)
{
DiskData[i]=OutData[i];
OutData[i]=0;
}
return bSuccess;
}
LLTing 2009-01-06
  • 打赏
  • 举报
回复
//------------------------------------------------------------------------------
//取MAC(非集成网卡)
function NBGetAdapterAddress(a: Integer): string;
var
NCB: TNCB; // Netbios control block //NetBios控制块
ADAPTER: TADAPTERSTATUS; // Netbios adapter status//取网卡状态
LANAENUM: TLANAENUM; // Netbios lana
intIdx: Integer; // Temporary work value//临时变量
cRC: Char; // Netbios return code//NetBios返回值
strTemp: string; // Temporary string//临时变量
begin
// Initialize
Result := '';
try
// Zero control blocl
ZeroMemory(@NCB, SizeOf(NCB));
// Issue enum command
NCB.ncb_command := Chr(NCBENUM);
//cRC := NetBios(@NCB);
NetBios(@NCB);
// Reissue enum command
NCB.ncb_buffer := @LANAENUM;
NCB.ncb_length := SizeOf(LANAENUM);
cRC := NetBios(@NCB);
if Ord(cRC) <> 0 then
exit;
// Reset adapter
ZeroMemory(@NCB, SizeOf(NCB));
NCB.ncb_command := Chr(NCBRESET);
NCB.ncb_lana_num := LANAENUM.lana[a];
cRC := NetBios(@NCB);
if Ord(cRC) <> 0 then
exit;
// Get adapter address
ZeroMemory(@NCB, SizeOf(NCB));
NCB.ncb_command := Chr(NCBASTAT);
NCB.ncb_lana_num := LANAENUM.lana[a];
StrPCopy(NCB.ncb_callname, '*');
NCB.ncb_buffer := @ADAPTER;
NCB.ncb_length := SizeOf(ADAPTER);
//cRC := NetBios(@NCB);
NetBios(@NCB);
// Convert it to string
strTemp := '';
for intIdx := 0 to 5 do
strTemp := strTemp + InttoHex(Integer(ADAPTER.adapter_address[intIdx]), 2);
Result := strTemp;
finally
end;
end;
//------------------------------------------------------------------------------
//取MAC地址(集成网卡和非集成网卡)
function Getmac:string;
var
ncb : TNCB;
s:string;
adapt : TASTAT;
lanaEnum : TLanaEnum;
i, j, m : integer;
strPart, strMac : string;
begin
FillChar(ncb, SizeOf(TNCB), 0);
ncb.ncb_command := Char(NCBEnum);
ncb.ncb_buffer := PChar(@lanaEnum);
ncb.ncb_length := SizeOf(TLanaEnum);
s:=Netbios(@ncb);
for i := 0 to integer(lanaEnum.length)-1 do
begin
FillChar(ncb, SizeOf(TNCB), 0);
ncb.ncb_command := Char(NCBReset);
ncb.ncb_lana_num := lanaEnum.lana[i];
Netbios(@ncb);
Netbios(@ncb);
FillChar(ncb, SizeOf(TNCB), 0);
ncb.ncb_command := Chr(NCBAstat);
ncb.ncb_lana_num := lanaEnum.lana[i];
ncb.ncb_callname := '* ';
ncb.ncb_buffer := PChar(@adapt);
ncb.ncb_length := SizeOf(TASTAT);
m:=0;
if (Win32Platform = VER_PLATFORM_WIN32_NT) then
m:=1;
if m=1 then
begin
if Netbios(@ncb) = Chr(0) then
strMac := '';
for j := 0 to 5 do
begin
strPart := IntToHex(integer(adapt.adapter.adapter_address[j]), 2);
strMac := strMac + strPart + '-';
end;
SetLength(strMac, Length(strMac)-1);
end;
if m=0 then
if Netbios(@ncb) <> Chr(0) then
begin
strMac := '';
for j := 0 to 5 do
begin
strPart := IntToHex(integer(adapt.adapter.adapter_address[j]), 2);
strMac := strMac + strPart + '-';
end;
SetLength(strMac, Length(strMac)-1);
end;
end;
result:=strmac;
end;

function PartitionString(StrV,PrtSymbol: string): TStringList;
var
iTemp: integer;
begin
result := TStringList.Create;
iTemp := pos(PrtSymbol,StrV);
while iTemp>0 do begin
if iTemp>1 then result.Append(copy(StrV,1,iTemp-1));
delete(StrV,1,iTemp+length(PrtSymbol)-1);
iTemp := pos(PrtSymbol,StrV);
end;
if Strv<>'' then result.Append(StrV);
end;

function MacStr():String;
var
Str:TStrings;
i:Integer;
MacStr1:String;
begin
MacStr1:='';
//Str:=TStringList.Create;
TStringList.Create;
Str:=PartitionString(Getmac,'-');
for i:=0 to Str.Count-1 do
MacStr1:=MacStr1+Str[i];
Result:=MacStr1;
end;
//---------------自定义函数结束-------------------------------------------------
procedure TMainForm.FormCreate(Sender: TObject);
begin
MainForm.Caption:='获取设备序列号 演示程序v2';
Label1.Caption:='CPU 序列号:';
Label2.Caption:='硬盘序列号:';
Label3.Caption:='网卡序列号:';
Label4.Caption:='GUID序列号:';
Button1.Caption:='获取序列号(&G)';
Button2.Caption:='退出(&Q)';
Edit1.Clear;
Edit2.Clear;
Edit3.Clear;
Edit4.Clear;
end;
//------------------------------------------------------------------------------
procedure TMainForm.Button1Click(Sender: TObject);
begin
Edit1.text:=GetCPUIDStr; //CPU系列号
Edit2.Text:=GetIdeSerialNumber; //取硬盘号
Edit3.text:=MacStr; //集成和非集成网卡
//Edit3.Text:=NBGetAdapterAddress(12);//非集成网卡
Edit4.Text:=GetGUID; //GUID序列号
end;
//------------------------------------------------------------------------------
procedure TMainForm.Button2Click(Sender: TObject);
begin
Close();
end;
//------------------------------------------------------------------------------
end.
//完.
LLTing 2009-01-06
  • 打赏
  • 举报
回复
//给一个我以前写的完整例子参考吧,正如上面的那些大牛所说的一样,不是很管用了.
//本例通过中断获取CPU序列号,硬盘序列号,网卡序列号,GUID序列号
//获取设备序列号 演示程序v2
//Delphi7
unit UntMainForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,nb30, ExtCtrls, ComObj, ActiveX; //重要引用

type //重要变量定义
PASTAT = ^TASTAT;
TASTAT = record
adapter : TAdapterStatus;
name_buf : TNameBuffer;
end;
TMainForm = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Button2: TButton;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Bevel1: TBevel;
Label4: TLabel;
Label8: TLabel;
Edit4: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
MainForm: TMainForm;

implementation

{$R *.dfm}
//------------------------------------------------------------------------------
//获取唯一识别码GUID
Function GetGUID:String;
var
Guid:TGUID;
begin
CoCreateGuid(Guid);
Result:=GuidToString(Guid);
end;
//------------------------------------------------------------------------------
//获取CPU系列号:
type //定义结构
TCPUID = array[1..4] of Longint;
FUNCTION GetCPUID : TCPUID; assembler; register;
asm
PUSH EBX {Save affected register}
PUSH EDI
MOV EDI,EAX {@Resukt}
MOV EAX,1
DW $A20F {CPUID Command}
STOSD {CPUID[1]}
MOV EAX,EBX
STOSD {CPUID[2]}
MOV EAX,ECX
STOSD {CPUID[3]}
MOV EAX,EDX
STOSD {CPUID[4]}
POP EDI {Restore registers}
POP EBX
END;
function GetCPUIDStr:String;
var
CPUID:TCPUID;
begin
CPUID:=GetCPUID;
Result:=IntToHex(CPUID[1],8)+IntToHex(CPUID[2],8)+IntToHex(CPUID[3],8)+IntToHex(CPUID[4],8);
end;
//------------------------------------------------------------------------------
//获取硬盘的出厂系列号
function GetIdeSerialNumber:string;
const IDENTIFY_BUFFER_SIZE = 512;
type
TIDERegs = packed record
bFeaturesReg: BYTE;
bSectorCountReg: BYTE;
bSectorNumberReg: BYTE;
bCylLowReg: BYTE;
bCylHighReg: BYTE;
bDriveHeadReg: BYTE;
bCommandReg: BYTE;
bReserved: BYTE;
end;

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;

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
bDriverError: Byte;
bIDEStatus: Byte;
bReserved: array[0..1] of Byte;
dwReserved: array[0..1] of DWORD;
end;

TSendCmdOutParams = packed record
cBufferSize: DWORD;
DriverStatus: TDriverStatus;
bBuffer: array[0..0] of BYTE;
end;
var
hDevice: Thandle;
cbBytesReturned: DWORD;
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;

begin //函数主体
Result := '';
if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT then
begin // Windows NT, Windows 2000
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;
with SCIP do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
with irDriveRegs do
begin
bSectorCountReg := 1;
bSectorNumberReg := 1;
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 := Trim(strpas(Pchar(@sSerialNumber)));//取硬盘号
end;
end;
honghust 2009-01-05
  • 打赏
  • 举报
回复
还是硬件加密好些,不过也不能太相信那些厂家了,你要是真做大了,说不定他们会提供破解,猜测,哈哈。揭贴去了。
路过路人乙 2009-01-05
  • 打赏
  • 举报
回复
7L的方法和ADO控件冲突...

获取CPU是难啊...难啊...
wenyongjie 2009-01-04
  • 打赏
  • 举报
回复
读硬盘和CPU的序列号进行加密,这个办法目前行不通了,还是楼上说得对,用加密狗吧,我们公司就一直要加密狗进行加密,即安全(相对)又方便客户
GeoPhoenix 2009-01-04
  • 打赏
  • 举报
回复
硬盘和CPU的序列号都不可靠,以前我用过首先发现CPU读出来的序列号是一样的,硬盘的序列号也有误,如果想加密建议还是采用USB狗,这也符合客户的要求,因为前面的两种加密方式将软件绑定到一个机器上了,尽管降低了您的软件开发成本,但是给用户带来了极大的麻烦,尤其是硬件更新换代的这么快。
hcqi2004 2008-12-30
  • 打赏
  • 举报
回复
{***********************************************
* *
* *
* 这个模块是用来获取CPU、硬盘序列号, *
* *
* ip地址信息的 *
* *
* *
*        *
*************************************************}
unit gethardinf;

interface

uses
Windows,SysUtils,Nb30,Winsock;

const
ID_BIT = $200000; // EFLAGS ID bit

type
TCPUID = array[1..4] of Longint;
TVendor = array [0..11] of char;

function IsCPUID_Available : Boolean; register; //判断CPU序列号是否可用函数
function GetCPUID: TCPUID; assembler; register; //获取CPU序列号函数
function GetCPUInfo: string; //CPU序列号(格式化成字符串)
function GetIdeSerialNumber: pchar;
function GetLocalIP: string;

implementation

function IsCPUID_Available : Boolean; register;
asm
PUSHFD {direct access to flags no possible, only via stack}
POP EAX {flags to EAX}
MOV EDX,EAX {save current flags}
XOR EAX,ID_BIT {not ID bit}
PUSH EAX {onto stack}
POPFD {from stack to flags, with not ID bit}
PUSHFD {back to stack}
POP EAX {get back to EAX}
XOR EAX,EDX {check if ID bit affected}
JZ @exit {no, CPUID not availavle}
MOV AL,True {Result=True}
@exit:
end;



function GetCPUID: TCPUID; assembler; register;
asm
PUSH EBX {Save affected register}
PUSH EDI
MOV EDI,EAX {@Resukt}
MOV EAX,1
DW $A20F {CPUID Command}
STOSD {CPUID[1]}
MOV EAX,EBX
STOSD {CPUID[2]}
MOV EAX,ECX
STOSD {CPUID[3]}
MOV EAX,EDX
STOSD {CPUID[4]}
POP EDI {Restore registers}
POP EBX
end;


function GetCPUInfo: string;
var
CPUID: TCPUID;
begin
if IsCPUID_Available then begin
CPUID:= GetCPUID;
Result:= IntToHex(CPUID[1], 8)
// +IntToHex(CPUID[2], 8)
+IntToHex(CPUID[3], 8)
+IntToHex(CPUID[4], 8);
end
else Result:='0000000000000000000';
end;


function GetLocalIP: string; //获取本机IP地址
type
TaPInAddr = array[0..255] of PInAddr; //Use Winsock.pas
PaPInAddr = ^TaPInAddr;
var
phe: PHostEnt;
pptr: PaPInAddr;
Buffer: array[0..63] of char;
i: integer;
GInitData: TWSADATA;
begin
wsastartup($101, GInitData);
result := '';
GetHostName(Buffer, SizeOf(Buffer));
phe := GetHostByName(buffer);
if not assigned(phe) then
exit;
pptr := PaPInAddr(Phe^.h_addr_list);
i := 0;
while pptr^[I] <> nil do begin
result := Result + StrPas(inet_ntoa(pptr^[I]^)) + ',';
inc(i);
end;
Delete(Result, Length(Result), 1);
wsacleanup;
end;



//取硬盘系列号:
function GetIdeSerialNumber: pchar; //获取硬盘的出厂系列号;
const IDENTIFY_BUFFER_SIZE = 512;
type
TIDERegs = packed record
bFeaturesReg: BYTE;
bSectorCountReg: BYTE;
bSectorNumberReg: BYTE;
bCylLowReg: BYTE;
bCylHighReg: BYTE;
bDriveHeadReg: BYTE;
bCommandReg: BYTE;
bReserved: BYTE;
end;

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;

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
bDriverError: Byte;
bIDEStatus: Byte;
bReserved: array[0..1] of Byte;
dwReserved: array[0..1] of DWORD;
end;

TSendCmdOutParams = packed record
cBufferSize: DWORD;
DriverStatus: TDriverStatus;
bBuffer: array[0..0] of BYTE;
end;
var
hDevice: Thandle;
cbBytesReturned: DWORD;
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;

begin //函数主体
Result := '';
if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000
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;
with SCIP do begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
with irDriveRegs do begin
bSectorCountReg := 1;
bSectorNumberReg := 1;
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.
加载更多回复(6)

13,871

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧