⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.pas

📁 界面精美
💻 PAS
📖 第 1 页 / 共 3 页
字号:
      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 + -