📄 disksn.pas
字号:
// 提示! 改变名称可适用于其它驱动器,如第二个驱动器: '\\.\PhysicalDrive1\'
if i=0 then
hDevice := CreateFile( '\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 )
else hDevice := CreateFile( '\\.\PhysicalDrive1', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 )
end
else if SysUtils.Win32Platform=1 then// Version Windows 95 OSR2, Windows 98
//hDevice := CreateFile( '\\.\SMARTVSD', 0,0, nil, CREATE_NEW , 0, 0 );
begin //Windows98,只获取第一个驱动器的,其他的我也不知道怎么获取,
//如果你知道的话,请告诉我:htxy99@yahoo.com,谢谢。
if (FSCSI0SN<>'') or (FSCSI1SN<>'') then exit;
result:=pchar(Change2Ring0());
exit;
end;
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;
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 dd1[ecx*2],ax
inc ecx
cmp ecx,256
jne @3
iretd //中断返回
end;
function TDISKSN.Change2Ring0:string;
begin
result:='';
try
asm
mov eax, offset Ring0Proc
mov OurGate.off2, ax // 将 中 断 函 数 的 地 址
shr eax, 16 // 填 入 新 造 的 中 断 门
mov OurGate.off1, ax // 描 述 符
mov OurGate.op,0028h
mov OurGate.seg1,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 dd1[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,10
jne @4
end;
result:=dsn;
except
end;
end;
function TDISKSN.ScsiHddSerialNumber(i:smallint) : String;
{$ALIGN ON}
type
TScsiPassThrough = record
Length : Word;
ScsiStatus : Byte;
PathId : Byte;
TargetId : Byte;
Lun : Byte;
CdbLength : Byte;
SenseInfoLength : Byte;
DataIn : Byte;
DataTransferLength : ULONG;
TimeOutValue : ULONG;
DataBufferOffset : DWORD;
SenseInfoOffset : ULONG;
Cdb : Array[0..15] of Byte;
end;
TScsiPassThroughWithBuffers = record
spt : TScsiPassThrough;
bSenseBuf : Array[0..31] of Byte;
bDataBuf : Array[0..191] of Byte;
end;
{ALIGN OFF}
var dwReturned : DWORD;
len : DWORD;
Buffer : Array[0..SizeOf(TScsiPassThroughWithBuffers)+SizeOf(TScsiPassThrough)-1] of Byte;
sptwb : TScsiPassThroughWithBuffers absolute Buffer;
hDevice:thandle;
begin
if SysUtils.win32Platform=2 then
begin
if i=0 then hDevice := CreateFile( '\\.\PhysicalDrive0',
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0 )
else hDevice := CreateFile( '\\.\PhysicalDrive1',
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0 );
end
else exit;
if hDevice=invalid_handle_value then exit;
Result := '';
try
FillChar(Buffer,SizeOf(Buffer),#0);
with sptwb.spt do
begin
Length := SizeOf(TScsiPassThrough);
CdbLength := 6; // CDB6GENERIC_LENGTH
SenseInfoLength := 24;
DataIn := 1; // SCSI_IOCTL_DATA_IN
DataTransferLength := 192;
TimeOutValue := 2;
DataBufferOffset := PChar(@sptwb.bDataBuf)-PChar(@sptwb);
SenseInfoOffset := PChar(@sptwb.bSenseBuf)-PChar(@sptwb);
Cdb[0] := $12; // OperationCode := SCSIOP_INQUIRY;
Cdb[1] := $01; // Flags := CDB_INQUIRY_EVPD; Vital product data
Cdb[2] := $80; // PageCode Unit serial number
Cdb[4] := 192; // AllocationLength
end;
len := sptwb.spt.DataBufferOffset+sptwb.spt.DataTransferLength;
if DeviceIoControl( hDevice, $0004d004, @sptwb, SizeOf(TScsiPassThrough), @sptwb, len, dwReturned, nil )
and ((PChar(@sptwb.bDataBuf)+1)^=#$80)
then SetString( Result, PChar(@sptwb.bDataBuf)+4, Ord((PChar(@sptwb.bDataBuf)+3)^) );
except
end;
end;
function TDISKSN.GetCPUSpeed: Double;
const
DelayTime = 500; // 时间单位是毫秒
var
TimerHi, TimerLo: DWORD;
PriorityClass, Priority: Integer;
begin
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
Sleep(10);
asm
dw 310Fh // rdtsc
mov TimerLo, eax
mov TimerHi, edx
end;
Sleep(DelayTime);
asm
dw 310Fh // rdtsc
sub eax, TimerLo
sbb edx, TimerHi
mov TimerLo, eax
mov TimerHi, edx
end;
SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
Result := TimerLo / (1000.0 * DelayTime);
end;
function TDISKSN.NBGetAdapterAddress(a: integer): string;
//a指定多个网卡适配器中的哪一个0,1,2...
var NCB: TNCB; // Netbios control block file://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);
// 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);
// 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;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -