📄 main.pas
字号:
if((reg.Flags and 1)=1)then
raise exception.CreateFmt('错误代码: %.2x',[reg.EAX and $FFFF]);
str:='';
for i:=0 to 512-1 do
begin
str:=str+format('%.2x',[integer(boot[i])]);
if i mod 16=15 then str:=str+#13;
end;
showmessage(str);
LockDisk(hDevicehandle,disk,true);//加锁
reg.EAX:=$0301;{ah=03 表示读, al=01 表示1个扇区}
reg.EBX:=Integer(@boot);{缓冲区}
reg.ECX:=$0001;{ch=00 表示柱面编号,cl=01 表示起始扇区编号}
reg.EDX:=disk;{dh=00 磁道编号, disk=0 表示 A 盘}
reg.Flags:=0;
fresult:=DeviceIoControl(hDeviceHandle,VWIN32_DIOC_DOS_INT13,@reg,
sizeof(reg),@reg,sizeof(reg),cb,nil);
if((reg.Flags and 1)=1)then
if reg.EAX=$300 then
raise exception.Create('写保护')
else
raise exception.CreateFmt('错误代码: %.2x',[reg.EAX and $FFFF]);
LockDisk(hDevicehandle,disk,false);//解锁
end;
end;
//显示BPB信息
procedure TFmain.ShowBPBInfo;
var
VolumeInfo:TVolumeInfo;
BPBbuf:array[0..512-1] of char;
i:integer;
str:string;
begin
ReadAnyLSec(DrvCBox.Drive,0,BPBbuf); //读取所选逻辑盘的0号扇区
VolumeInfo:=GetVolumeInformation(DrvCBox.Drive);
with VolumeInfo do
begin
if FileSystemName='FAT16' then
begin
//显示该逻辑分区的BPB信息
for i:=0 to 7 do
str:=str+BPBbuf[$3+i];
LabOEMId.Caption:=str;
LabBytesPerSec.Caption:=IntToStr(integer(BPBbuf[$c])*256+integer(BPBbuf[$b]));
LabSecsPerClu.Caption:=IntToStr(integer(BPBbuf[$d]));
LabResSecs.Caption:=IntToStr(integer(BPBbuf[$f])*256+integer(BPBbuf[$e]));
LabFATCopies.Caption:=IntToStr(integer(BPBbuf[$10]));
LabRootDir.Caption:=IntToStr(integer(BPBbuf[$12])*256+integer(BPBbuf[$11]));
LabTotSecs.Caption:=IntToStr(integer(BPBbuf[$14])*256+integer(BPBbuf[$13]));
LabMedia.Caption:=format('%.2x Hex',[integer(BPBbuf[$15])]);
LabSecsPerFAT.Caption:=IntToStr(integer(BPBbuf[$17])*256+integer(BPBbuf[$16]));
LabSecsPerTrack.Caption:=IntToStr(integer(BPBbuf[$19])*256+integer(BPBbuf[$18]));
LabSides.Caption:=IntToStr(integer(BPBbuf[$1b])*256+integer(BPBbuf[$1a]));
LabHideSec.Caption:=IntToStr(integer(BPBbuf[$1f])*16777216+integer(BPBbuf[$1e])*65536+integer(BPBbuf[$1d])*256+integer(BPBbuf[$1c]));
LabTotalSec.Caption:=IntToStr(integer(BPBbuf[$23])*16777216+integer(BPBbuf[$22])*65536+integer(BPBbuf[$21])*256+integer(BPBbuf[$20]));
LabPdriveNum.Caption:=IntToStr(integer(BPBbuf[$24]));
LabEBRSign.Caption:=format('%.2x Hex',[integer(BPBbuf[$26])]);
LabVolID.Caption:=format('%.2x%.2x%.2x%.2x',[integer(BPBbuf[$2a]),integer(BPBbuf[$29]),integer(BPBbuf[$28]),integer(BPBbuf[$27])]);
str:='';
for i:=0 to 10 do
str:=str+BPBbuf[$2b+i];
LabVolLab.Caption:=str;
str:='';
for i:=0 to 7 do
str:=str+BPBbuf[$3c+i];
LabFileSystem.Caption:=str;
end; //end of if 'FAT16'
if FileSystemName='FAT32' then
begin
//显示该逻辑分区的BPB信息
for i:=0 to 7 do
str:=str+BPBbuf[$3+i];
LabOEMId.Caption:=str;
LabBytesPerSec.Caption:=IntToStr(integer(BPBbuf[$c])*256+integer(BPBbuf[$b]));
LabSecsPerClu.Caption:=IntToStr(integer(BPBbuf[$d]));
LabResSecs.Caption:=IntToStr(integer(BPBbuf[$f])*256+integer(BPBbuf[$e]));
LabFATCopies.Caption:=IntToStr(integer(BPBbuf[$10]));
LabRootDir.Caption:=IntToStr(integer(BPBbuf[$12])*256+integer(BPBbuf[$11]));
LabTotSecs.Caption:=IntToStr(integer(BPBbuf[$14])*256+integer(BPBbuf[$13]));
LabMedia.Caption:=format('%.2x Hex',[integer(BPBbuf[$15])]);
LabSecsPerFAT.Caption:=IntToStr(integer(BPBbuf[$17])*256+integer(BPBbuf[$16]));
LabSecsPerTrack.Caption:=IntToStr(integer(BPBbuf[$19])*256+integer(BPBbuf[$18]));
LabSides.Caption:=IntToStr(integer(BPBbuf[$1b])*256+integer(BPBbuf[$1a]));
LabHideSec.Caption:=IntToStr(integer(BPBbuf[$1f])*16777216+integer(BPBbuf[$1e])*65536+integer(BPBbuf[$1d])*256+integer(BPBbuf[$1c]));
LabTotalSec.Caption:=IntToStr(integer(BPBbuf[$23])*16777216+integer(BPBbuf[$22])*65536+integer(BPBbuf[$21])*256+integer(BPBbuf[$20]));
LabSecsPerFAT1.Caption:=IntToStr(integer(BPBbuf[$27])*16777216+integer(BPBbuf[$26])*65536+integer(BPBbuf[$25])*256+integer(BPBbuf[$24]));
LabExSign.Caption:=format('%.2x%.2x Hex',[integer(BPBbuf[$29]),integer(BPBbuf[$28])]);
LabFSysVer.Caption:=format('%.2x%.2x Hex',[integer(BPBbuf[$2b]),integer(BPBbuf[$2a])]);
LabRootDirClus.Caption:=IntToStr(integer(BPBbuf[$2d])*256+integer(BPBbuf[$2c]));
LabFSysInfoSecs.Caption:=IntToStr(integer(BPBbuf[$31])*256+integer(BPBbuf[$30]));
LabBootSecs.Caption:=IntToStr(integer(BPBbuf[$33])*256+integer(BPBbuf[$32]));
LabPdriveNum.Caption:=IntToStr(integer(BPBbuf[$40]));
LabEBRSign.Caption:=format('%.2x Hex',[integer(BPBbuf[$42])]);
LabVolID.Caption:=format('%.2x%.2x%.2x%.2x',[integer(BPBbuf[$46]),integer(BPBbuf[$45]),integer(BPBbuf[$44]),integer(BPBbuf[$43])]);
str:='';
for i:=0 to 10 do
str:=str+BPBbuf[$47+i];
LabVolLab.Caption:=str;
str:='';
for i:=0 to 7 do
str:=str+BPBbuf[$52+i];
LabFileSystem.Caption:=str;
end; //end of if 'FAT32'
end; //end of with
SEditStartSec.MaxValue:=integer(BPBbuf[$23])*16777216+integer(BPBbuf[$22])*65536+integer(BPBbuf[$21])*256+integer(BPBbuf[$20]);
end;
procedure TFmain.SEditStartSecChange(Sender: TObject);
begin
SEditSecCount.MaxValue:=SEditStartSec.MaxValue-SEditStartSec.Value;
end;
procedure TFmain.SEditCylinsChange(Sender: TObject);
var
SecAbsAddress:longword;
buf:array[0..512-1] of char;
i:integer;
begin
SecAbsAddress:=SEditCylins.Value*255*63+SEditHeads.Value*63
+SEditSectors.Value-1;
ReadAnyPSec(SecAbsAddress,buf);
for i:=0 to 512-1 do
FSec[i]:=buf[i];
LoadFileIntoHexViewer; {把文件以16进制读入StringGrid中}
Edit1.Text:=IntToStr(SecAbsAddress);
end;
procedure TFmain.MItemHDInfoClick(Sender: TObject);
begin
FrmPT.Show;
end;
procedure TFmain.MItemShutDownClick(Sender: TObject);
begin
FrmShutDown.show;
end;
procedure TFmain.MItemWriteClick(Sender: TObject);
var
SecStart:longword;
begin
SecStart:=StrToInt(Edit1.Text);
WriteAnyPSec(SecStart,FSec);
end;
procedure TFmain.TBtnSaveClick(Sender: TObject);
var
i:integer;
SecData:TSecInfo;
SecFile:File of TSecInfo;
begin
with SaveDialog1 do
if execute then
begin
if FileName<>'' then
begin
AssignFile(SecFile,SaveDialog1.FileName);
Rewrite(SecFile);
SecData.Cylin:=SEditCylins.Value;
SecData.Head:=SEditHeads.Value;
SecData.Sector:=SEditSectors.Value;
for i:=0 to 512-1 do
SecData.Data[i]:=Fsec[i];
write(SecFile,SecData);
CloseFile(SecFile);
end;
end; //end of if
end;
procedure TFmain.MItemSaveMBRClick(Sender: TObject);
begin
SaveDialog1.FileName:='MBR_Sec';
TBtnSave.OnClick(sender);
end;
procedure TFmain.MItemSaveBootClick(Sender: TObject);
begin
SaveDialog1.FileName:='Boot_Sec';
TBtnSave.OnClick(sender);
end;
procedure TFmain.TBtnOpenClick(Sender: TObject);
var
i:integer;
SecData:TSecInfo;
SecFile:File of TSecInfo;
begin
PnlCHS.Visible:=true;
with OpenDialog1 do
if execute then
begin
PnlCHS.Visible:=true;
if FileName<>'' then
begin
AssignFile(SecFile,OpenDialog1.FileName);
Reset(SecFile);
Read(SecFile,SecData);
CloseFile(SecFile);
SEditCylins.Enabled:=false;
SEditHeads.Enabled:=false;
SEditSectors.Enabled:=false;
SEditCylins.Value:=SecData.Cylin;
SEditHeads.Value:=SecData.Head;
SEditSectors.Value:=SecData.Sector;
SEditCylins.Enabled:=true;
SEditHeads.Enabled:=true;
SEditSectors.Enabled:=true;
for i:=0 to 512-1 do
Fsec[i]:=SecData.Data[i];
LoadFileIntoHexViewer; {把文件以16进制读入StringGrid中}
end;
end //end of if
else
PnlCHS.Visible:=false;
end;
procedure TFmain.MItemLoadMBRClick(Sender: TObject);
begin
OpenDialog1.FileName:='MBR_Sec';
TBtnOpen.OnClick(Sender);
end;
procedure TFmain.MItemLoadBootClick(Sender: TObject);
begin
OpenDialog1.FileName:='Boot_Sec';
TBtnOpen.OnClick(Sender);
end;
procedure TFmain.MItemFormatClick(Sender: TObject);
begin
FrmFormat.Show;
end;
procedure TFmain.MItemAboutClick(Sender: TObject);
begin
FrmAbout.Show;
end;
procedure TFmain.BBtnPrintClick(Sender: TObject);
begin
FrmPrint.QRLabDrvTitle.Caption:=fmain.DrvCBox.Drive+' 区BPB详细信息';
FrmPrint.QRLabOEMID.Caption:=fmain.LabOEMId.Caption;
FrmPrint.QRLabBytesPerSec.Caption:=Fmain.LabBytesPerSec.Caption;
FrmPrint.QRLabSecsPerClu.Caption:=Fmain.LabSecsPerClu.Caption;
FrmPrint.QRLabResSecs.Caption:=Fmain.LabResSecs.Caption;
FrmPrint.QRLabFATCopies.Caption:=Fmain.LabFATCopies.Caption;
FrmPrint.QRLabRootDir.Caption:=Fmain.LabRootDir.Caption;
FrmPrint.QRLabTotSecs.Caption:=Fmain.LabTotSecs.Caption;
FrmPrint.QRLabMedia.Caption:=Fmain.LabMedia.Caption;
FrmPrint.QRLabSecsPerFAT.Caption:=Fmain.LabSecsPerFAT.Caption;
FrmPrint.QRLabSecsPerTrack.Caption:=Fmain.LabSecsPerTrack.Caption;
FrmPrint.QRLabSides.Caption:=Fmain.LabSides.Caption;
FrmPrint.QRLabHideSec.Caption:=Fmain.LabHideSec.Caption;
FrmPrint.QRLabTotalSec.Caption:=Fmain.LabTotalSec.Caption;
FrmPrint.QRLabPdriveNum.Caption:=Fmain.LabPdriveNum.Caption;
FrmPrint.QRLabEBRSign.Caption:=Fmain.LabEBRSign.Caption;
FrmPrint.QRLabVolID.Caption:=Fmain.LabVolID.Caption;
FrmPrint.QRLabVolLab.Caption:=Fmain.LabVolLab.Caption;
FrmPrint.QRLabFileSystem.Caption:=Fmain.LabFileSystem.Caption;
FrmPrint.QRLabSecsPerFAT1.Caption:=Fmain.LabSecsPerFAT1.Caption;
FrmPrint.QRLabExSign.Caption:=Fmain.LabExSign.Caption;
FrmPrint.QRLabFSysVer.Caption:=Fmain.LabFSysVer.Caption;
FrmPrint.QRLabRootDirClus.Caption:=Fmain.LabRootDirClus.Caption;
FrmPrint.QRLabFSysInfoSecs.Caption:=Fmain.LabFSysInfoSecs.Caption;
FrmPrint.QRLabBootSecs.Caption:=Fmain.LabBootSecs.Caption;
FrmPrint.QuickRep1.Preview;
end;
procedure TFmain.MItemSaveFileClick(Sender: TObject);
begin
FrmSaveAsFile.Show;
end;
procedure TFmain.MItemQuitClick(Sender: TObject);
begin
close;
end;
procedure TFmain.MItemWriteMBRClick(Sender: TObject);
begin
if MessageDlg('是否要恢复主引导扇区的内容?',mtConfirmation,[mbYes,mbNo],0)=IdYes then
begin
fmain.MItemLoadMBRClick(Sender);
if MessageDlg('确保你所选的备份扇区为正确的MBR备份?',mtConfirmation,[mbYes,mbNo],0)=IdYes then
fmain.MItemWriteClick(Sender);
end;
end;
//----------RING0权限读写磁盘
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 of asm
end;
begin
Ring0DiskRW.result:=false;
Ring0ToRun;
end;
procedure TFmain.MItemMBRCodeClick(Sender: TObject);
const
Pdrive2000='\\.\PHYSICALDRIVE0'; //物理磁盘 0表示第一个硬盘
var
i:integer;
SecData:TSecInfo;
SecFile:File of TSecInfo;
buf:array[0..446-1]of char;
s:string;
p:pchar; //2000下使用
Mybuf:array[0..446-1]of char; //9x下使用
begin
AssignFile(SecFile,'\MBR_Data');
Reset(SecFile);
Read(SecFile,SecData);
CloseFile(SecFile);
for i:=0 to 446-1 do
buf[i]:=SecData.Data[i];
if GetWinVer=2 then //当前系统为winNT/2000
begin
p:=allocmem(446);
//p 必须为新申请的内存或全局变量,不能是局部变量,用于临时缓冲
//如"p:array[0..446-1] of char" 定义为局部变量是不能读写磁盘的。
for i:=0 to 446-1 do
p[i]:=buf[i];
s:='';
for i:=0 to 446-1 do
begin
s:=s+format('%.2X ',[integer(p[i])]) ;//
if i mod 16=15 then s:=s+#13;
end;
showmessage(s);
if Messagedlg('是否执行主引导程序恢复操作',mtConfirmation,[mbYes,mbNo],0)=IdYes then //2
begin
hDeviceHandle:=CreateFile(Pdrive2000,GENERIC_ALL,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if (hDeviceHandle<>INVALID_HANDLE_VALUE)then //3
begin
//写盘
FileSeek(hDevicehandle,0,0);//起始扇区
if FileWrite(hDevicehandle,p[0],446)<>446 then //写扇区
raise exception.Create('Write 错误%d')
else
Messagedlg('已经成功恢复主引导(MBR)程序',mtInformation,[mbOK],0);
end; //end of if 3
freemem(p,446);
closehandle(hDeviceHandle);
end; //end of if 2
end
else //当前系统为WIN9X,或者其他
begin
for i:=0 to 446-1 do
Mybuf[i]:=buf[i];
{ s:='';
for i:=0 to 446-1 do
begin
s:=s+format('%.2X ',[integer(Mybuf[i])]) ;//
if i mod 16=15 then s:=s+#13;
end;
showmessage(s);
}
if Messagedlg('是否执行主引导程序恢复操作',mtConfirmation,[mbYes,mbNo],0)=IdYes then //4
begin
Ring0DiskRW.Drv:=$80;
Ring0DiskRW.ReadOrNot:=false; //读
Ring0DiskRW.StartSecLo:=0;
Ring0DiskRW.StartSecHi:=0;
Ring0DiskRW.DiskBuffer:=@Mybuf;
Ring0ReadWriteDisk;
if not Ring0DiskRW.result then
raise exception.create('读写出错')
else
Messagedlg('已经成功恢复主引导(MBR)程序',mtInformation,[mbOK],0);
end; //end of if 4
end;
end;
procedure TFmain.MItemAbsReadClick(Sender: TObject);
begin
FrmAbsRead.Show;
end;
procedure TFmain.MItemHelp1Click(Sender: TObject);
begin
frmHelp.Show;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -