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

📄 unitread32.pas

📁 在delphi中实现windows核心编程.原书光盘代码核心编程.原书光盘代码
💻 PAS
字号:
unit UnitRead32;

interface

uses   SysUtils, WinTypes,WINPROCS, Messages, Classes, Graphics, Controls,
  StdCtrls, Dialogs,Windows,wjsthunk;

type
   P32Regs = ^T32Regs; //32位寄存器结构
   T32Regs = record
     EBX: Longint;
     EDX: Longint;
     ECX: Longint;
     EAX: Longint;
     EDI: Longint;
     ESI: Longint;
     Flags: Longint;
   end;
   TDISKRW = packed record
     len,res:byte;
     SecCount,BufferOffset,BufferSegment:word;
     SecLow,SecHigh:longint;
   end;
   PDISKRW=^TDISKRW;
   THandle16=Word;
   function WJSReadDisk32(drv:byte;buffer:Pchar;StartSecLow,StartSecHigh:longword;SecCount:word):boolean;stdcall;
   function WJSWriteDisk32(drv:byte;buffer:Pchar;StartSecLow,StartSecHigh:longword;SecCount:word):boolean;stdcall;
   
const
    VWIN32_DIOC_DOS_IOCTL = 1; { MS-DOS Int 21h 44xxh functions call }
    VWIN32_DIOC_DOS_INT25 = 2; { MS-DOS Int 25h function call }
    VWIN32_DIOC_DOS_INT26 = 3; { MS-DOS Int 26h function call }
    VWIN32_DIOC_DOS_INT13 = 4; { MS-DOS Int 13h functions call }
    VWIN32_DIOC_DOS_DRIVEINFO = 6; {MS-DOS Int 21h function 730X}

implementation

var
  VMM32Handle,hInst16: THandle;
  pFunc: Pointer; {函数指针}
  drive: array[0..255] of boolean;
  i:integer;
  
function LockDisk(VMM32Handle:cardinal;disk:byte;LockOrNot:boolean):boolean;
var
  R: T32Regs;
  cb: DWord;
begin
  if (VMM32Handle=INVALID_HANDLE_VALUE)then
  begin
     result:=false;
     exit;
  end;
  fillchar(r, sizeof(r), 0);
  if LockOrNot=true then
  begin
     R.ECX := $084b;
     R.EBX := $100+disk; //bh:0-3级  0,1,$80,$81...
     R.EDX := 1;    //1允许写,0允许格式化
  end
  else begin
     R.ECX := $086b;
     R.EBX := disk;   //0,1,$80,$81...
  end;
  R.EAX := $440D;
  DeviceiOControl(VMM32Handle, VWIN32_DIOC_DOS_IOCTL, @R, SizeOf(R), @R, SizeOf(R), cb, nil);
  Result := (R.Flags and 1 = 0); //and (R.EAX and $FFFF = 0);
end;

function LockDrive(VMM32Handle:cardinal;drive:byte;LockOrNot:boolean):boolean;
var
  R: T32Regs;
  cb: DWord;
begin
  if (VMM32Handle=INVALID_HANDLE_VALUE)then
  begin
     result:=false;
     exit;
  end;
  fillchar(r, sizeof(r), 0);
  if LockOrNot=true then
  begin
     R.ECX := $084a;
     R.EBX := $100+drive; //bh:0-4级  0当前盘,1:A,2:B,3:C
     R.EDX := 1;    //1允许写,0允许格式化
  end
  else begin
     R.ECX := $086A;
     R.EBX := drive;   //0当前盘,1:A,2:B,3:C
  end;
  R.EAX := $440D;
  DeviceiOControl(VMM32Handle, VWIN32_DIOC_DOS_IOCTL, @R, SizeOf(R), @R, SizeOf(R), cb, nil);
  Result := (R.Flags and 1 = 0); //and (R.EAX and $FFFF = 0);
end;

function WJSReadDisk32(drv:byte;buffer:Pchar;StartSecLow,StartSecHigh:longword;SecCount:word):boolean;stdcall;
var
   DiskRW:TDISKRW;
   DiskRW16,buf16:dword;
   DiskRW32,buf32:pchar;
   drv1:word;
begin
  result:=false;
  if hInst16 < 32 then exit;
  pFunc := GetProcAddress16(hInst16, 'WJSReadDisk16');
  if pFunc = nil then raise exception.create('WJSReadDisk16在ReadDisk.DLL中没找到');

  buf16 := MakeLong(0,GlobalAlloc16(GPTR,SecCount*512));
  buf32 := WOWGetVDMPointer(Buf16,0,True);

  DiskRW.len := sizeof(TDiskRW);
  DiskRW.res := 0;
  DiskRW.SecCount := SecCount;
  DiskRW.bufferoffset := LoWord(buf16);
  DiskRW.buffersegment := HiWord(buf16);
  DiskRW.SecLow := startSeclow;
  DiskRW.SecHigh := startSechigh;

  DiskRW16 := MakeLong(0,GlobalAlloc16(GPTR,sizeof(TDiskRW)));
  DiskRW32 := WOWGetVDMPointer(DiskRW16,0,True);
  Move(DiskRW,DiskRW32^,sizeof(TDiskRW));

  drv1:=drv; //由于drv是字节,必须转换为双字节

  asm  //以下汇编代码中,只有第一参数、第二参数、pFunc的值是需要改变的,其余都是固定的写法
      pushad
      push ebp        //#2,保存ebp
      sub esp,$2c     //#1,预留2c字节的栈空间
      push drv1       //第一参数,如果没有参数,则不用push
      push DiskRW16   //第二参数,如果没有参数,则不用push
      mov edx, pFunc  //函数地址
      mov ebp,esp     //
      add ebp,$2c     //ebp校正,是作者分析QT_Thunk时发现的
      call  QT_Thunk
      add esp,$2c     //#1,释放上面预留的2c字节的栈空间
      pop ebp         //#2,恢复ebp
      mov byte ptr @result,al  //result前必须加上@
      popad
  end;
  if Result then
     Move(buf32^,buffer^,SecCount*512);
  Move(DiskRW32^,DiskRW,sizeof(TDiskRW));
  GlobalFree16(HiWord(buf16));
  GlobalFree16(HiWord(DiskRW16));
end;

function WJSWriteDisk32(drv:byte;buffer:Pchar;StartSecLow,StartSecHigh:longword;SecCount:word):boolean;stdcall;
var
   DiskRW:TDISKRW;
   DiskRW16,buf16:dword;
   DiskRW32,buf32:pchar;
   drv1:word;
begin
  result:=false;
  if not drive[drv] then
     if LockDisk(VMM32Handle,drv,True) then drive[drv]:=true;
  if drive[drv]=false then exit;

  if hInst16 < 32 then exit;
  pFunc := GetProcAddress16(hInst16, 'WJSWriteDisk16');
  if pFunc = nil then raise exception.create('WJSWriteDisk16在ReadDisk.DLL中没找到');

  buf16 := MakeLong(0,GlobalAlloc16(GPTR,SecCount*512));
  buf32 := WOWGetVDMPointer(Buf16,0,True);
  Move(buffer^,buf32^,SecCount*512);

  DiskRW.len := sizeof(TDiskRW);
  DiskRW.res := 0;
  DiskRW.SecCount := SecCount;
  DiskRW.bufferoffset := LoWord(buf16);
  DiskRW.buffersegment := HiWord(buf16);
  DiskRW.SecLow := startSeclow;
  DiskRW.SecHigh := startSechigh;

  DiskRW16 := MakeLong(0,GlobalAlloc16(GPTR,sizeof(TDiskRW)));
  DiskRW32 := WOWGetVDMPointer(DiskRW16,0,True);
  Move(DiskRW,DiskRW32^,sizeof(TDiskRW));

  drv1:=drv; //由于drv是字节,必须转换为双字节

  asm  //以下汇编代码中,只有第一参数、第二参数、pFunc的值是需要改变的,其余都是固定的写法
      pushad
      push ebp        //#2,保存ebp
      sub esp,$2c     //#1,预留2c字节的栈空间
      push drv1       //第一参数,如果没有参数,则不用push
      push DiskRW16   //第二参数,如果没有参数,则不用push
      mov edx, pFunc  //函数地址
      mov ebp,esp     //
      add ebp,$2c     //ebp校正,是作者分析QT_Thunk时发现的
      call  QT_Thunk
      add esp,$2c     //#1,释放上面预留的2c字节的栈空间
      pop ebp         //#2,恢复ebp
      mov byte ptr @result,al  //result前必须加上@
      popad
  end;
  if Result then
     Move(buf32^,buffer^,SecCount*512);
  Move(DiskRW32^,DiskRW,sizeof(TDiskRW));
  GlobalFree16(HiWord(buf16));
  GlobalFree16(HiWord(DiskRW16));
end;

initialization
    VMM32Handle := CreateFile('\\.\VWIN32', GENERIC_READ or GENERIC_WRITE,
        FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    hInst16 := LoadLibrary16('READDISk.DLL');
    if hInst16<32 then showmessage('ReadDisk.DLL没找到');
    for i:=0 to 255 do drive[i]:=false;
finalization
    for i:=0 to 255 do
       if drive[i]=true then
          LockDisk(VMM32Handle,i,False);
    CloseHandle(VMM32Handle);
    FreeLibrary16(hInst16);

end.

⌨️ 快捷键说明

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