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

📄 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;
   TInt13Reg = packed record
     SecCount:byte; {AL}
     SecStart:byte; {CL的0-5bit,表示范围是:0-63}
     Cylinder:word; {CH和CL的6-7bit,表示范围是:0-1023}
     Head:byte;  {DH}
     drv:byte;   {DL}
     BufferSegment,BufferOffset:word;
   end;
   PInt13Reg=^TInt13Reg;
   THandle16=Word;
   function WJSReadDisk32(drv:byte;SecCount,SecStart:byte;Cylinder:word;Head:byte;buffer:pchar):boolean;stdcall;
   function WJSWriteDisk32(drv:byte;SecCount,SecStart:byte;Cylinder:word;Head:byte;buffer:pchar):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
  i:integer;
  VMM32Handle,hInst16: THandle;
  pFunc: Pointer; {函数指针}
  drive: array[0..255] of boolean;

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;SecCount,SecStart:byte;Cylinder:word;Head:byte;buffer:pchar):boolean;stdcall;
var
   Int13Reg:TInt13Reg;
   Int13Reg32,buf32:pchar;
   Int13Reg16,Buf16:dword;
begin
  result:=false;
  if hInst16 < 32 then exit;
  pFunc := GetProcAddress16(hInst16, 'WJSReadDisk16');
  if pFunc = nil then raise exception.create('WJSReadDisk16在Read.DLL中没找到');
  if (Cylinder>$3FF)or(SecStart>$3F)or(SecStart<1)then exit;

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

  Int13Reg.SecCount := SecCount;
  Int13Reg.SecStart := SecStart;
  Int13Reg.Cylinder := Cylinder;
  Int13Reg.Head     := Head;
  Int13Reg.Drv      := Drv;
  Int13Reg.bufferoffset := LoWord(Buf16);
  Int13Reg.buffersegment := HiWord(Buf16);

  Int13Reg16 := MakeLong(0,GlobalAlloc16(GPTR,sizeof(TInt13Reg)));
  Int13Reg32 := WOWGetVDMPointer(Int13Reg16,0,True);
  Move(Int13Reg,Int13Reg32^,sizeof(TInt13Reg));

  asm  //以下汇编代码中,只有第一参数、第二参数、pFunc的值是需要改变的,其余都是固定的写法
      pushad
      push ebp           //#2,保存ebp
      sub esp,$2c        //#1,预留2c字节的栈空间
      push Int13Reg16    //第一参数,如果没有参数,则不用push
                         //第二参数,如果没有参数,则不用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
      popad
  end;
  if Result then
     Move(buf32^,buffer^,SecCount*512);
  Move(Int13Reg32^,Int13Reg,sizeof(TInt13Reg));
  GlobalFree16(HiWord(Buf16));
  GlobalFree16(Hiword(Int13Reg16));
end;

function WJSWriteDisk32(drv:byte;SecCount,SecStart:byte;Cylinder:word;Head:byte;buffer:pchar):boolean;stdcall;
var
   Int13Reg:TInt13Reg;
   Int13Reg32,buf32:pchar;
   Int13Reg16,Buf16:dword;
begin
  result:=false;
  if hInst16 < 32 then exit;
  pFunc := GetProcAddress16(hInst16, 'WJSWriteDisk16');
  if pFunc = nil then raise exception.create('WJSWriteDisk16在Read.DLL中没找到');
  if (Cylinder>$3FF)or(SecStart>$3F)or(SecStart<1)then exit;

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

  Int13Reg.SecCount := SecCount;
  Int13Reg.SecStart := SecStart;
  Int13Reg.Cylinder := Cylinder;
  Int13Reg.Head     := Head;
  Int13Reg.Drv      := Drv;
  Int13Reg.bufferoffset := LoWord(buf16);
  Int13Reg.buffersegment := HiWord(buf16);
  Move(buffer^,buf32^,SecCount*512);

  Int13Reg16 := MakeLong(0,GlobalAlloc16(GPTR,sizeof(TInt13Reg)));
  Int13Reg32 := WOWGetVDMPointer(Int13Reg16,0,True);
  Move(Int13Reg,Int13Reg32^,sizeof(TInt13Reg));

  asm  //以下汇编代码中,只有第一参数、第二参数、pFunc的值是需要改变的,其余都是固定的写法
      pushad
      push ebp           //#2,保存ebp
      sub esp,$2c        //#1,预留2c字节的栈空间
      push Int13Reg16    //第一参数,如果没有参数,则不用push
                         //第二参数,如果没有参数,则不用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
      popad
  end;
  Move(Int13Reg32^,Int13Reg,sizeof(TInt13Reg));
  GlobalFree16(HiWord(buf16));
  GlobalFree16(HiWord(Int13Reg16));
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('READ.DLL');
    if hInst16<32 then showmessage('Read.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 + -