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

📄 pdiskio.pas

📁 一个磁盘文件被删除后恢复的源程序! 内嵌汇编代码~!
💻 PAS
📖 第 1 页 / 共 2 页
字号:
      al, ah, al2, ah2: byte);
    1: (
      bx, bx2         : word;
      dx, dx2         : word;
      cx, cx2         : word;
      ax, ax2         : word;
      di, di2         : word;
      si, si2         : word);
    2: (
      ebx: longword;
      edx: longword;
      ecx: longword;
      eax: longword;
      edi: longword;
      esi: longword;
      flags: longword);
  end;
  PDEVIOCTL_REGISTERS = ^DEVIOCTL_REGISTERS;


function DoINT13(preg: PDEVIOCTL_REGISTERS): boolean;
var
  res: boolean;
  cb: dword;
  hDevice: thandle;
begin
  res:=false;
  preg.flags := CARRY_FLAG; { assume error (carry flag set) }

  hDevice := CreateFile('\\.\vwin32',
        GENERIC_READ, FILE_SHARE_READ OR FILE_SHARE_WRITE,
        NIL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, 0);

  if (hDevice <> INVALID_HANDLE_VALUE) then
  begin
    res:=DeviceIoControl(hDevice, VWIN32_DIOC_DOS_INT13,
      preg, sizeof(DEVIOCTL_REGISTERS),
      preg, sizeof(DEVIOCTL_REGISTERS), cb, nil);
    CloseHandle(hDevice);
  end;
  DoINT13:=res;
end;


function INT13_reset(drv: byte): boolean;
var
  r: DEVIOCTL_registers;
  res: boolean;
begin
  res:=false;
  fillchar(r, sizeof(DEVIOCTL_REGISTERS), 0);
  r.ah:=0;
  r.dl:=drv;
  res:=DoINT13(@r);
  if res then
  begin
    res:=((r.flags and CARRY_FLAG) = 0);
  end;
  INT13_reset:=res;
end;

{ Get sector and cylinder number from combined sector/cylinder-code
  (e.g. found in partition sector) }
procedure CnvSecCyl(SecCyl: word; var sector: byte; var cylinder: word);
begin
  sector:=seccyl and 63;
  cylinder:=hi(seccyl) + (lo(seccyl) and 192) shl 2;
end;

function INT13_GetDriveParams(drv: byte; params: PLegacyDriveParams): boolean;
var
  r: DEVIOCTL_registers;
  res: boolean;
  cb: integer;
  sec: byte;
  cyl: word;

begin
  res:=false;
  fillchar(r, sizeof(DEVIOCTL_REGISTERS), 0);
  r.ah:=8;
  r.dl:=drv;
  res:=DoINT13(@r);
  if res then
  begin
    res:=((r.flags and CARRY_FLAG) = 0);
    if res then
    begin
      CnvSecCyl(r.cx, sec, cyl);
      params^.cylinders:=cyl+1;
      params^.secpertrack:=sec;
      params^.status:=r.ah;
      params^.CMOS_DriveType:=r.bl;
      params^.heads:=r.dh+1;
      params^.drives:=r.dl;
    end;
  end;
  INT13_GetDriveParams:=res;
end;

{ counterpart to CnvSecCyl }
procedure SetCnvSecCyl(sector, cylinder: word; var SecCyl: word);
begin
  SecCyl:=WORD((LO(cylinder) SHL 8) OR ((HI(cylinder) AND 3) SHL 6) OR (sector AND 63));
end;

{ legacy read sector: returns number of sectors read }
function INT13_ReadSec(drv: byte; count: byte; cyl: word; sec: byte; head: byte; buf: pointer): byte;
var
  r: DEVIOCTL_registers;
  res: byte;
  cb: integer;
  SecCyl: word;
  retry: byte;
begin
  res:=0;
  retry:=0;
  repeat
    SetCnvSecCyl(sec, cyl, SecCyl);
    fillchar(r, sizeof(DEVIOCTL_REGISTERS), 0);
    r.ah:=2;
    r.al:=count;
    r.cx:=SecCyl;
    r.dh:=head;
    r.dl:=drv;
    r.ebx:=longword(@buf);
    if (DoINT13(@r)) AND ((r.flags and CARRY_FLAG) = 0) then
    begin
      res:=r.al; 
    end;
    inc(retry);
  until (retry >= 3) OR (res > 0);
  INT13_ReadSec:=res;
end;


// -----------------------------------------------------------------------------------
//     INT13 Extensions...
// -----------------------------------------------------------------------------------


function CheckExtensions(drv: byte; var ver:byte; var subsets: word):Boolean;
var
  res: boolean;
  outbuf: array[0..3] of byte;
  cb: dword;
begin
  outbuf[0]:=0;
  res:=DeviceIoControl(W95handle, DIOC_CHECKEXTENSIONS,
      @drv, 1,
      @outbuf, 1, cb, nil);
  ver:=outbuf[1];
  subsets:=(outbuf[2] SHL 8) OR outbuf[3];

  CheckExtensions:=res AND (outbuf[0]=1);
end;


function ReadPhysicalSectors(drv: byte; LBA: longword; blocks: word; buf: pointer; ErrorDlg: boolean): boolean;
var
  res: boolean;
  struc: extstruc;
  cb: dword;
  tempbuf: array[0..511] of byte;
  count: integer;
  msgRes: integer;

begin
  res:=FALSE;
  if winNTflag then
    res:=NT_Read(drv,  LBA, blocks, buf, ErrorDlg)
  else begin
    if optUseINT13EXT then
    begin
      count:=0;

      struc.Drv    := drv;
      struc.LBA    := LBA;
      struc.blocks := 1; //blocks;
      struc.buf    := {buf;} @tempbuf;
      repeat
        repeat
          res:=DeviceIoControl(W95handle, DIOC_EXTENDEDREAD,
              @struc, sizeof(extstruc),
              nil, 0, cb, nil);
          msgRes := id_abort;
          if (NOT res) AND (ErrorDlg) then
          begin
            msgRes:=messagebox(0, pchar('Error reading sector, '+#13#10+'drv:'+inttostr(drv)+' LBA:'+inttostr(LBA)
              +' blocks:'+inttostr(blocks) +#13#10#13#10
              +' Abort, Retry or Ignore?'), 'ExtendedRead error',  mb_applmodal or mb_iconwarning or mb_abortretryignore);
            if msgRes = id_Retry then
            begin
              // try to reset controller...
              INT13_reset(drv);
            end;
          end;
        until NOT ((ErrorDlg) AND (msgRes = id_Retry));
        if (NOT res) AND (ErrorDlg) AND (msgRes = id_ignore) then res:=true;
        if res then move(tempbuf, buf^, 512);

        inc(longword(buf),512);
        inc(count);
        inc(struc.LBA);
      until (NOT res) OR (count >= blocks);
    end;
  end;

  result:=res;
end;


function WritePhysicalSectors(drv: byte; LBA: longword; blocks: word; buf: pointer;
  verify: boolean; ErrorDlg: boolean): boolean;
var
  res: boolean;
  struc: extstruc;
  cb: dword;
  count: integer;
  tempbuf: array[0..511] of byte;
  msgRes: integer;

begin
  res:=FALSE;
  if winNTflag then
    res:=NT_Write(drv,  LBA, blocks, buf, ErrorDlg)
  else begin
    if optUseINT13EXT then
    begin
      count:=0;

      struc.Drv    := drv;
      struc.LBA    := LBA;
      struc.blocks := 1; //blocks;
      struc.buf    := @tempbuf; //buf;
      struc.verify := byte(verify);

      repeat
        move(buf^, tempbuf, 512);
        repeat
          res:=DeviceIoControl(W95handle, DIOC_EXTENDEDWRITE,
              @struc, sizeof(extstruc),
              nil, 0, cb, nil);
          msgRes := id_abort;
          if (NOT res) AND (ErrorDlg) then
          begin
            msgRes:=messagebox(0, pchar('Error writing sector, '+#13#10+'drv:'+inttostr(drv)+' LBA:'+inttostr(LBA)
              +' blocks:'+inttostr(blocks) +#13#10#13#10
              +' Abort, Retry or Ignore?'), 'ExtendedWrite error',  mb_applmodal or mb_iconwarning or mb_abortretryignore);
          end;
        until NOT ((ErrorDlg) AND (msgRes = id_Retry));
        if (NOT res) AND (ErrorDlg) AND (msgRes = id_ignore) then res:=true;

        inc(longword(buf),512);
        inc(struc.LBA);
        inc(count);
      until (NOT res) OR (count >= blocks);
    end;
  end;

  result:=res;
end;


function GetPhysDriveParams(drv: byte; resultbuf: PPhysDriveParams): boolean;
var
  res: boolean;
  struc: extstruc;
  cb: dword;
  dg: TDisk_Geometry;
  ver: byte;
  subsets: word;
  legacy: TLegacyDriveParams;
  dp: TDriveParams;
begin
  res:=false;
  if WinNTflag then
  begin
    // Windows NT...
      
    res:=NT_GetDriveGeometry(drv, @dg);
    if res then
    begin
      resultbuf^.MediaAttr:=0;
      resultbuf^.Heads:=dg.cylinders.lowpart;
      resultbuf^.TracksPerHead:=dg.trackspercylinder;
      resultbuf^.SectorsPerTrack:=dg.sectorspertrack;
      resultbuf.BytesPerSector:=dg.bytespersector;
      resultbuf^.TotalPhysSec:=dg.cylinders.lowpart * dg.TracksPerCylinder * dg.SectorsPerTrack;
      case dg.MediaType of
        0:             resultbuf^.MediaType:=PMEDIA_TYPE_UNKNOWN;
        1..10, 13..22: begin
                         resultbuf^.MediaType:=PMEDIA_TYPE_FLOPPY;
                         resultbuf^.MediaAttr:=PMEDIA_ATTR_REMOVABLE;
                       end;
        11:            begin
                         resultbuf^.MediaType:=PMEDIA_TYPE_REMOVABLE;
                         resultbuf^.MediaAttr:=PMEDIA_ATTR_REMOVABLE;
                       end;
        12:            resultbuf^.MediaType:=PMEDIA_TYPE_FIXED;
      end;
    end;
  end else
  begin
    // Windows 9X...

    //INT13_reset(drv);
    if drv < $80 then
    begin
      if OptUseINT13 then
      begin
        // legacy INT13...
        res:=INT13_GetDriveParams(drv, @legacy);
        if (res) AND (legacy.secpertrack = 0) then res:=false;
        if (res) then
        begin
          if drv IN [0,1] then resultbuf^.MediaType:=PMEDIA_TYPE_FLOPPY
            else resultbuf^.MediaType:=PMEDIA_TYPE_REMOVABLE; // ??
          resultbuf^.MediaAttr:=PMEDIA_ATTR_REMOVABLE;
          resultbuf^.Heads:=legacy.heads;
          resultbuf^.TracksPerHead:=legacy.cylinders;
          resultbuf^.SectorsPerTrack:=legacy.secpertrack;
          resultbuf^.BytesPerSector:=512;
          resultbuf^.TotalPhysSec:=legacy.cylinders * legacy.heads * legacy.secpertrack;
        end;
      end;
    end else
    begin
      if OptUseINT13EXT then
      begin
        // INT13 Extensions...
        struc.Drv    := drv;
        struc.buf    := @dp;
        dp.bufsize:=30;

        res:=DeviceIoControl(W95handle, DIOC_GETDRIVEPARAMS,
          @struc, sizeof(extstruc),
          nil, 0, cb, nil);
        if res then
        begin
          resultbuf^.MediaAttr:=0;
          if (dp.infoflags AND IFLAG_REMOVABLE) <> 0 then
          begin
            resultbuf^.MediaType:=PMEDIA_TYPE_REMOVABLE;
            resultbuf^.MediaAttr:=PMEDIA_ATTR_REMOVABLE;
          end else resultbuf^.MediaType:=PMEDIA_TYPE_FIXED;
          resultbuf^.Heads:=dp.physheads;
          resultbuf^.TracksPerHead:=dp.physcyl;
          resultbuf^.SectorsPerTrack:=dp.physsecptrk;
          resultbuf^.BytesPerSector:=dp.bytesPerSec;
          resultbuf^.TotalPhysSec:=dp.physsecLO;
        end;
      end;
    end;
  end;

  result:=res;
end;


// -----------------------------------------------------------------------------------
//     Main...
// -----------------------------------------------------------------------------------


procedure MyExit;
begin
  ExitProc := ExitSave;            { first restore old vector }

  if NOT (winNTflag) then
  begin
    // Win9X...
    if (W95handle <> INVALID_HANDLE_VALUE) then
    begin
      // CloseHandle(hDevice);
      DeleteFile('\\.\INT13EXT');
    end;
  end else
  begin
    // WinNT...
    if (NThandle <> INVALID_HANDLE_VALUE) then CloseHandle(NThandle);
  end;
end;


begin
  OptUseINT13:=TRUE;
  OptUseINT13EXT:=TRUE;
  
  W95handle:=INVALID_HANDLE_VALUE;
  NThandle:=INVALID_HANDLE_VALUE;
  winNTflag:=IsWinNT;

  ExitSave := ExitProc;
  ExitProc := @MyExit;


  if NOT winNTflag then
  begin
    W95handle:=CreateFile('\\.\INT13EXT.VXD', 0, 0, nil, 0,
      FILE_FLAG_DELETE_ON_CLOSE, 0);

    if W95handle = INVALID_HANDLE_VALUE then
    begin
      MessageBox(0, 'Error loading "INT13EXT.VXD"', 'Error', mb_IconExclamation + mb_ok);
    end;
  end;
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -