?? unitread32.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 + -