📄 unit1.pas
字号:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
const
IOR_READ=0;
IOR_WRITE=1;
IORF_PHYS_CMD=$40000000;
IORF_VERSION_002=$400;
IORF_SYNC_COMMAND=$100;
IORF_HIGH_PRIORITY=1;
type
Ttype_sdeffsd_req_usage = packed record
_IOR_ioctl_drive:word;
_IOR_ioctl_function:word;
_IOR_ioctl_control_param:longword;
_IOR_ioctl_buffer_ptr:longword;
_IOR_ioctl_client_params:longword;
_IOR_ioctl_return:longword;
end;
Turequestor_usage = packed record
case integer of
1:(
_IOR_requestor_usage:array[0..4]of longword;);
2:(
sdeffsd_req_usage:Ttype_sdeffsd_req_usage;);
end;
TIOR=packed record
IOR_next:longword;{ 为BCB的(MBZ for IORF_VERSION_002) 的客户链接 }
IOR_func:word;{子功能号}
IOR_status:word;{请求的状态}
IOR_flags:longword;{请求控制标志}
IOR_callback:procedure;{如果IORF_SYNC_COMMAND未设置,则为回调函数地址}
IOR_start_addr:array[0..1]of longword;{相对开始地址}
IOR_xfer_count:longword;{处理的扇区数}
IOR_buffer_ptr:longword;{客户缓冲区指针}
IOR_private_client:longword;{ BlockDev/IOS客户保留}
IOR_private_IOS:longword;{IOS保留空间}
IOR_private_port:longword;{端口驱动的私有区域}
_ureq:Turequestor_usage;
IOR_req_req_handle:longword;{请求句柄}
IOR_req_vol_handle:longword;{媒体句柄,指向VRP结构}
IOR_sgd_lin_phys:longword;{指向第一个物理SGD }
IOR_num_sgds:byte;{物理SGD的数目}
IOR_vol_designtr:byte;{视子功能号的不同,可能是以下两种情况:(1)A盘为0,B盘为1,C盘为2……(2)软盘是0-7F,硬盘是80-FF}
IOR_ios_private_1:word;{由IOS保留强制对齐}
IOR_reserved_2:array[0..1]of longword; {保留,内部使用}
end;
PIOR=^TIOR;
TRing0DiskRW = record
ReadOrNot:boolean;
Drv:byte;
StartSecLo,StartSecHi:longword;
DiskBuffer:pchar;
result:boolean;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
IDT : array [0..5] of byte;
lpOldGate : dword;
Ring0DiskRW:TRing0DiskRW;
implementation
{$R *.DFM}
procedure Ring0ReadWriteDisk;stdcall;
procedure SendCommand; stdcall;
var
IOR:PIOR;
iorBuffer:array[0..$fc-1]of char; //$fc=$ac+$58 sizeof(IOR)=$58
buffer:array[0..512-1]of char;
begin
fillchar(iorbuffer[0],sizeof(iorBuffer),0);
ior:=PIOR(@iorBuffer[$ac]);
ior^.IOR_vol_designtr := Ring0DiskRW.Drv;
if Ring0DiskRW.ReadOrNot then
ior^.IOR_func := IOR_READ
else begin
ior^.IOR_func := IOR_WRITE;
move(Ring0DiskRW.Diskbuffer[0],buffer[0],512);
end;
ior^.IOR_flags := IORF_PHYS_CMD or IORF_VERSION_002 or IORF_SYNC_COMMAND or IORF_HIGH_PRIORITY;
ior^.IOR_buffer_ptr := longword(@buffer);
ior^.IOR_xfer_count := 1;
ior^.IOR_start_addr[0] := Ring0DiskRW.StartSecLo;
ior^.IOR_start_addr[1] := Ring0DiskRW.StartSecHi;
ior^.IOR_next := 1;
asm
push es
push ds
pushad
mov esi,ior
mov ax,ss
mov es,ax
mov ds,ax
int 20h
dd 00100004h // IOS_SendCommand(ior,NULL);
popad
pop ds
pop es
end;
Ring0DiskRW.result:=(ior^.IOR_status=0);
if Ring0DiskRW.result and Ring0DiskRW.ReadOrNot then
move(buffer[0],Ring0DiskRW.Diskbuffer[0],512);
end;
procedure Ring0ToRun; stdcall;
const ExceptionUsed = $03; // 中断号
begin
asm
sidt IDT {读入中断描述符表}
mov ebx, dword ptr [IDT+2]
add ebx, 8*ExceptionUsed {计算中断在中断描述符表中的位置}
cli {关中断}
mov dx, word ptr [ebx+6]
shl edx, 16d {左移166位}
mov dx, word ptr [ebx]
mov [lpOldGate], edx {保存旧的中断门}
mov eax, offset @@Ring0Code{修改向量,指向Ring0级代码段}
mov word ptr [ebx], ax
shr eax, 16d
mov word ptr [ebx+6], ax
int ExceptionUsed { 发生中断}
mov ebx, dword ptr [IDT+2] {重新定位到中断描述符表中}
add ebx, 8*ExceptionUsed
mov edx, [lpOldGate]
mov word ptr [ebx], dx
shr edx, 16d
mov word ptr [ebx+6], dx {恢复被改了的向量}
ret
@@Ring0Code: {Ring0级代码段}
push es
push ds
pushad
call SendCommand
popad
pop ds
pop es
iretd {中断返回}
end;
end;
begin
Ring0DiskRW.result:=false;
Ring0ToRun;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
buf:array[0..512-1]of char;
s:string;
i:integer;
begin
Ring0DiskRW.Drv:=$80;
Ring0DiskRW.ReadOrNot:=true; //读
Ring0DiskRW.StartSecLo:=0;
Ring0DiskRW.StartSecHi:=0;
Ring0DiskRW.DiskBuffer:=@buf;
Ring0ReadWriteDisk;
if not Ring0DiskRW.result then raise exception.create('读出错');
s:='';
for i:=0 to 512-1 do
begin
s:=s+format('%.2X ',[integer(Ring0DiskRW.Diskbuffer[i])]);
if i mod 16=15 then s:=s+#13;
end;
showmessage(s);
Ring0DiskRW.Drv:=$80;
Ring0DiskRW.ReadOrNot:=false; //写
Ring0DiskRW.StartSecLo:=0;
Ring0DiskRW.StartSecHi:=0;
Ring0DiskRW.DiskBuffer:=@buf;
Ring0ReadWriteDisk;
if not Ring0DiskRW.result then raise exception.create('写出错');
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -