有段源代码,是从别人的控件里找的,他是从VC5的头文件里逆向出来的
有问题,你要仔细把常量重新翻译一下
unit IOCTL;
//CONVERTED FROM IOCTL.INC (VISUAL DEVSTUDIO 5) - I'm a plagiat afterall
//not required - just a collection of numbers (so did with WINDOWS.PAS ))
//this version not including a structure/record that might be needed
//any comments just send to me: aa, a_@geocities.com
interface
const
//DeviceType
File_Device_BEEP = $00000001;
File_Device_CD_ROM = $00000002;
File_Device_CD_ROM_File_System = $00000003;
File_Device_CONTROLLER = $00000004;
File_Device_DataLINK = $00000005;
File_Device_DFS = $00000006;
File_Device_Disk = $00000007;
File_Device_Disk_File_System = $00000008;
File_Device_File_System = $00000009;
File_Device_INPORT_PORT = $0000000A;
File_Device_KEYBOARD = $0000000B;
File_Device_MAILSLOT = $0000000C;
File_Device_MIDI_IN = $0000000D;
File_Device_MIDI_OUT = $0000000E;
File_Device_MOUSE = $0000000F;
File_Device_MULTI_UNC_PROVIDER = $00000010;
File_Device_NAMED_PIPE = $00000011;
File_Device_NETWORK = $00000012;
File_Device_NETWORK_BROWSER = $00000013;
File_Device_NETWORK_File_System = $00000014;
File_Device_NULL = $00000015;
File_Device_PARALLEL_PORT = $00000016;
File_Device_PHYSICAL_NETCARD = $00000017;
File_Device_PRINTER = $00000018;
File_Device_SCANNER = $00000019;
File_Device_SERIAL_MOUSE_PORT = $0000001A;
File_Device_SERIAL_PORT = $0000001B;
File_Device_SCREEN = $0000001C;
File_Device_SOUND = $0000001D;
File_Device_STREAMS = $0000001E;
File_Device_TAPE = $0000001F;
File_Device_TAPE_File_System = $00000020;
File_Device_TRANSPORT = $00000021;
File_Device_UNKNOWN = $00000022;
File_Device_VIDEO = $00000023;
File_Device_VIRTUAL_Disk = $00000024;
File_Device_WAVE_IN = $00000025;
File_Device_WAVE_OUT = $00000026;
File_Device_8042_PORT = $00000027;
File_Device_NETWORK_REDIRECTOR = $00000028;
File_Device_BATTERY = $00000029;
File_Device_BUS_EXTENDER = $0000002A;
File_Device_MODEM = $0000002B;
File_Device_VDM = $0000002C;
File_Device_Mass_Storage = $0000002D;
//Method
Method_Buffered = 0;
Method_IN_Direct = 1;
Method_OUT_Direct = 2;
Method_Neither = 3;
//Access
File_Any_Access = 0;
File_Read_Access = ($0001);
// file &
pipe
File_Write_Access = ($0002);
// file &
pipe
//FSCTL Access
File_Read_Data = File_Read_Access;
File_Write_Data = File_Write_Access;
//Storage
IOCTL_Storage_Base = File_Device_MASS_Storage;// $002D
IOCTL_Disk_Base = File_Device_Disk;
// $0007
//Partition
Partition_ENTRY_UNUSED = $00;
// Entry unused
Partition_FAT_12 = $01;
// 12-bit FAT entries
Partition_XENIX_1 = $02;
// Xenix
Partition_XENIX_2 = $03;
// Xenix
Partition_FAT_16 = $04;
// 16-bit FAT entries
Partition_EXTENDED = $05;
// Extended Partition entry
Partition_HUGE = $06;
// Huge Partition MS-DOS V4
Partition_IFS = $07;
// IFS Partition
Partition_FAT32 = $0B;
// FAT32
Partition_FAT32_XINT13 = $0C;
// FAT32 using extended int13 services
Partition_XINT13 = $0E;
// Win95 Partition using extended int13 services
Partition_XINT13_EXTENDED = $0F;
// Same as type 5 but uses extended int13 services
Partition_PREP = $41;
// PowerPC Reference Platform (PReP) Boot Partition
Partition_UNIX = $63;
// Unix
VALID_NTFT = $C0;
// NTFT uses high order bits
//IOCTL/FSCTL/SMART Code
IOCTL_Storage_Check_Verify : integer = 0;
IOCTL_Storage_Media_REMOVAL : integer = 0;
IOCTL_Storage_Eject_Media : integer = 0;
IOCTL_Storage_Load_Media : integer = 0;
IOCTL_Storage_RESERVE : integer = 0;
IOCTL_Storage_RELEASE : integer = 0;
IOCTL_Storage_Find_New_Devices : integer = 0;
IOCTL_Storage_Get_Media_Types : integer = 0;
IOCTL_Disk_Get_Drive_Geometry : integer = 0;
IOCTL_Disk_Get_Partition_Info : integer = 0;
IOCTL_Disk_Set_Partition_Info : integer = 0;
IOCTL_Disk_Get_Drive_Layout : integer = 0;
IOCTL_Disk_Set_Drive_Layout : integer = 0;
IOCTL_Disk_Verify : integer = 0;
IOCTL_Disk_Format_Tracks : integer = 0;
IOCTL_Disk_Reassign_Blocks : integer = 0;
IOCTL_Disk_Performance : integer = 0;
IOCTL_Disk_is_Writable : integer = 0;
IOCTL_Disk_Logging : integer = 0;
IOCTL_Disk_Format_Tracks_EX : integer = 0;
IOCTL_Disk_Histogram_Structure : integer = 0;
IOCTL_Disk_Histogram_Data : integer = 0;
IOCTL_Disk_Histogram_Reset : integer = 0;
IOCTL_Disk_Request_Structure : integer = 0;
IOCTL_Disk_Request_Data : integer = 0;
FSCTL_Lock_Volume : integer = 0;
FSCTL_Unlock_Volume : integer = 0;
FSCTL_Dismount_Volume : integer = 0;
FSCTL_Mount_DBLS_Volume : integer = 0;
FSCTL_Get_Compression : integer = 0;
FSCTL_Set_Compression : integer = 0;
FSCTL_Read_Compression : integer = 0;
FSCTL_Write_Compression : integer = 0;
SMART_Get_Version : integer = 0;
SMART_SEND_Drive_Command : integer = 0;
SMART_RCV_Drive_Data : integer = 0;
procedure Init;
implementation
function Ctl_Code(DeviceType, FuncNo, Method, Access: integer): integer;
begin
Result:= (DeviceType shl 16) or (Access shl 14) or (FuncNo shl 2) or (Method)
end;
procedure Init;
begin
IOCTL_Storage_Check_Verify := Ctl_Code(IOCTL_Storage_Base, $0200, Method_Buffered, File_Read_Access);
IOCTL_Storage_Media_REMOVAL := Ctl_Code(IOCTL_Storage_Base, $0201, Method_Buffered, File_Read_Access);
IOCTL_Storage_Eject_Media := Ctl_Code(IOCTL_Storage_Base, $0202, Method_Buffered, File_Read_Access);
IOCTL_Storage_Load_Media := Ctl_Code(IOCTL_Storage_Base, $0203, Method_Buffered, File_Read_Access);
IOCTL_Storage_RESERVE := Ctl_Code(IOCTL_Storage_Base, $0204, Method_Buffered, File_Read_Access);
IOCTL_Storage_RELEASE := Ctl_Code(IOCTL_Storage_Base, $0205, Method_Buffered, File_Read_Access);
IOCTL_Storage_Find_New_Devices := Ctl_Code(IOCTL_Storage_Base, $0206, Method_Buffered, File_Read_Access);
IOCTL_Storage_Get_Media_Types := Ctl_Code(IOCTL_Storage_Base, $0300, Method_Buffered, File_Any_Access);
IOCTL_Disk_Get_Drive_Geometry := Ctl_Code(IOCTL_Disk_Base, $0000, Method_Buffered, File_Any_Access);
IOCTL_Disk_Get_Partition_Info := Ctl_Code(IOCTL_Disk_Base, $0001, Method_Buffered, File_Read_Access);
IOCTL_Disk_Set_Partition_Info := Ctl_Code(IOCTL_Disk_Base, $0002, Method_Buffered, File_Read_Access or File_Write_Access);
IOCTL_Disk_Get_Drive_Layout := Ctl_Code(IOCTL_Disk_Base, $0003, Method_Buffered, File_Read_Access);
IOCTL_Disk_Set_Drive_Layout := Ctl_Code(IOCTL_Disk_Base, $0004, Method_Buffered, File_Read_Access or File_Write_Access);
IOCTL_Disk_Verify := Ctl_Code(IOCTL_Disk_Base, $0005, Method_Buffered, File_Any_Access);
IOCTL_Disk_Format_Tracks := Ctl_Code(IOCTL_Disk_Base, $0006, Method_Buffered, File_Read_Access or File_Write_Access);
IOCTL_Disk_Reassign_Blocks := Ctl_Code(IOCTL_Disk_Base, $0007, Method_Buffered, File_Read_Access or File_Write_Access);
IOCTL_Disk_Performance := Ctl_Code(IOCTL_Disk_Base, $0008, Method_Buffered, File_Any_Access);
IOCTL_Disk_is_Writable := Ctl_Code(IOCTL_Disk_Base, $0009, Method_Buffered, File_Any_Access);
IOCTL_Disk_Logging := Ctl_Code(IOCTL_Disk_Base, $000A, Method_Buffered, File_Any_Access);
IOCTL_Disk_Format_Tracks_EX := Ctl_Code(IOCTL_Disk_Base, $000B, Method_Buffered, File_Read_Access or File_Write_Access);
IOCTL_Disk_Histogram_Structure := Ctl_Code(IOCTL_Disk_Base, $000C, Method_Buffered, File_Any_Access);
IOCTL_Disk_Histogram_Data := Ctl_Code(IOCTL_Disk_Base, $000D, Method_Buffered, File_Any_Access);
IOCTL_Disk_Histogram_Reset := Ctl_Code(IOCTL_Disk_Base, $000E, Method_Buffered, File_Any_Access);
IOCTL_Disk_Request_Structure := Ctl_Code(IOCTL_Disk_Base, $000F, Method_Buffered, File_Any_Access);
IOCTL_Disk_Request_Data := Ctl_Code(IOCTL_Disk_Base, $0010, Method_Buffered, File_Any_Access);
FSCTL_Lock_Volume := Ctl_Code(File_Device_File_System, 6, Method_Buffered, File_Any_Access);
FSCTL_Unlock_Volume := Ctl_Code(File_Device_File_System, 7, Method_Buffered, File_Any_Access);
FSCTL_Dismount_Volume := Ctl_Code(File_Device_File_System, 8, Method_Buffered, File_Any_Access);
FSCTL_Mount_DBLS_Volume := Ctl_Code(File_Device_File_System,13, Method_Buffered, File_Any_Access);
FSCTL_Get_Compression := Ctl_Code(File_Device_File_System,15, Method_Buffered, File_Any_Access);
FSCTL_Set_Compression := Ctl_Code(File_Device_File_System,16, Method_Buffered, File_Read_Data or File_Write_Data);
FSCTL_Read_Compression := Ctl_Code(File_Device_File_System,17, Method_Neither, File_Read_Data);
FSCTL_Write_Compression := Ctl_Code(File_Device_File_System,18, Method_Neither, File_Write_Data);
SMART_Get_Version := CTL_CODE(IOCTL_Disk_Base, $0020, Method_Buffered, File_Read_Access);
SMART_SEND_Drive_Command := CTL_CODE(IOCTL_Disk_Base, $0021, Method_Buffered, File_Read_Access or File_Write_Access);
SMART_RCV_Drive_Data := CTL_CODE(IOCTL_Disk_Base, $0022, Method_Buffered, File_Read_Access or File_Write_Access);
end;
initialization
Init;
end.
unit maincode;
interface
//Absolute Read/Write test
//use w/ care - might destroy your disk critical area (PART/MBR/FAT etc.)
//you may modify, redistribute or even trashed out this code as you wish
//no licenses, no warranty, though I guarantee it to work )
//by aa, aa@bitsmart.com
//thanks to Ralf Brown for interrupt list
uses
IOCTL,
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, ToolWin, StdCtrls, Spin, ExtCtrls;
type
Tfrm = class(TForm)
ToolBar1: TToolBar;
StatusBar1: TStatusBar;
StaticText1: TStaticText;
spindriveno: TSpinEdit;
ToolButton1: TToolButton;
StaticText2: TStaticText;
spinsecstart: TSpinEdit;
ToolButton2: TToolButton;
StaticText3: TStaticText;
spinsecnum: TSpinEdit;
ToolButton3: TToolButton;
ToolButton4: TToolButton;
ToolButton5: TToolButton;
Memo1: TMemo;
Splitter1: TSplitter;
ToolButton6: TToolButton;
GetDevHandleNo: TToolButton;
CloseDevHandle: TToolButton;
ToolButton7: TToolButton;
ToolButton8: TToolButton;
ToolButton9: TToolButton;
Memo2: TMemo;
ToolButton10: TToolButton;
ToolButton11: TToolButton;
ToolButton12: TToolButton;
Label1: TLabel;
ToolButton13: TToolButton;
ToolButton14: TToolButton;
procedure GetDevHandleNoClick(Sender: TObject);
procedure CloseDevHandleClick(Sender: TObject);
procedure ToolButton5Click(Sender: TObject);
procedure ToolButton6Click(Sender: TObject);
procedure ToolButton8Click(Sender: TObject);
procedure ToolButton9Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ToolButton11Click(Sender: TObject);
procedure ToolButton12Click(Sender: TObject);
procedure ToolButton13Click(Sender: TObject);
procedure ToolButton14Click(Sender: TObject);
private
hDevice:THandle;// read GetDeviceHandle;
Success:boolean;
function GetDeviceHandle:THandle;
function Hex4(x:integer):shortstring;
procedure ShowErr(const m:string;
const i:integer);
public
procedure hexen(Buffer:array of char;
Count:integer);
function INT13Read(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Buf
ointer):BOOL;
function INT13Write(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Buf
ointer):BOOL;
function ReadSectors(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Buf
ointer):BOOL;
function WriteSectors(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Buf
ointer):BOOL;
//INT25H-26Hdo
ES NOT WORK ON FAT32
function INT25ReadLogicalSectors(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Buf
ointer):BOOL;
function INT26WriteLogicalSectors(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Buf
ointer):BOOL;
function ReadTrack(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Buf
ointer):BOOL;
function WriteTrack(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Buf
ointer):BOOL;
end;
var
frm: Tfrm;
implementation
{$R *.DFM}
const
VWIN32_DIOC_DIOS_IOCTL = 1;
//Performs the specified MS-DOS device I/O control function (Interrupt 21h Function 4400h through 4411h).
VWIN32_DIOC_DIOS_INT25 = 2;
VWIN32_DIOC_DIOS_INT26 = 3;
VWIN32_DIOC_DIOS_INT13 = 4;
//Performs Interrupt 13h commands.
VWIN32_DIOC_DIOS_DRIVEINFO = 6;
CARRY_FLAG = 1;
type
TDIOCRegisters = packed record
reg_EBX, reg_EDX, reg_ECX, reg_EAX,
reg_EDI, reg_ESI, reg_Flags: dword;
end;
TDiskIO = packed record
StartSector:dword;
Sectors:word;
Buffer:dword;
end;
TRWBlock = packed record
SpecFunc: byte;
//db ? special functions (must be zero)
Head:word;
//dw ? head to read/write
Cylinder:word;
//dw ? cylinder to read/write
FirstSector:word;
//dw ? first sector to read/write
Sectors:word;
//dw ? number of sectors to read/write
Buffer:dword;
//dd ? address of buffer for read/write data
end;
TDisk_Addr_pkt = packed record
packet_size:byte;
//db 16
size of packet in bytes
reserved:byte;
//db 0
reserved, must be 0
block_count:word;
//dw ?
number of blocks to transfer
buffer_addr:dword;
//dd ?
address of transfer buffer
block_num:comp;
//dq ?
starting absolute block number
end;
var B:array[0..1024*8-1] of char;
cb:dword;
function tfrm.hex4(x:integer):shortstring;
begin
result:=inttohex(x,4);
end;
procedure tfrm.showerr;
begin
showmessage(m +#$D+'Return value: '+hex4(i)+'H');
end;
function Tfrm.GetDeviceHandle:THandle;
var OS:TOSVersionInfo;
begin
OS.dwOSVersionInfoSize:=sizeof(OS);
GetVersionEx(OS);
case OS.dwPlatformId of
VER_PLATFORM_WIN32_WINDOWS:
result:=CreateFile('//./VWin32', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_DELETE_ON_CLOSE, 0);
VER_PLATFORM_WIN32_NT:
result:=CreateFile('//./PhysicalDrive0', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_DELETE_ON_CLOSE, 0);
else
result:=INVALID_HANDLE_VALUE;
end;
end;
procedure tfrm.hexen;
var i:integer;
S:String;
begin
S:='';
for i:=0 to spinsecnum.value*512-1do
begin
S:=S+inttohex(ord(Buffer
),2);
if ((i+1) mod 4 = 0) and (i>0) then
S:=S+' - '
else
if ((i+1) mod 16 = 0) and (i>0) then
begin
S:=S+#$D#$A;
end
else
S:=S+' ';
end;
memo1.lines.Clear;
memo1.lines.Add(S);
S:='';
for i:=0 to spinsecnum.value*512-1do
begin
if ord(Buffer)>$20 then
S:=S+Buffer
else
S:=S+'.';
end;
memo2.lines.Clear;
memo2.lines.Add(S);
end;
function LockPhysVolume(Dev:THandle;
Level:dword):BOOL;
var reg:TDIOCRegisters;
const DRIVE_C = $80;
//Level = 1;
begin
reg.reg_ESI:=$0;
reg.reg_EDI:=$0;
//unnecessary?
reg.reg_Flags:=$8000;
//set carry flag
reg.reg_EAX:=$440D;
//Generic IOCTL function
reg.reg_EBX:=LEVEL shl 8 or DRIVE_C;
reg.reg_ECX:=$484B;
//CH=$48:OSR2, CL=$4B:LOCK Physical Volume
reg.reg_EDX:=$2;
//write/map still enabled
result:= DeviceIOControl(Dev, VWIN32_DIOC_DIOS_IOCTL, @reg,
sizeof(reg), @reg, sizeof(reg), cb, nil);
end;
function UnLockPhysVolume(Dev:THandle;
Level:dword):BOOL;
var reg:TDIOCRegisters;
const DRIVE_C = $80;
//Level = 1;
begin
reg.reg_ESI:=$0;
reg.reg_EDI:=$0;
//unnecessary?
reg.reg_Flags:=$8000;
//set carry flag
reg.reg_EAX:=$440D;
//Generic IOCTL function
reg.reg_EBX:=LEVEL shl 8 or DRIVE_C;
reg.reg_ECX:=$486B;
//CH=$48:OSR2, CL=$6B:UNLOCK Physical Volume
reg.reg_EDX:=$2;
//write/map still enabled
result:= DeviceIOControl(Dev, VWIN32_DIOC_DIOS_IOCTL, @reg,
sizeof(reg), @reg, sizeof(reg), cb, nil);
end;
function FSCTLLock(Dev:THandle):BOOL;
begin
Result:=DeviceIOControl(Dev,FSCTL_LOCK_VOLUME,nil,0,nil,0,cb,nil);
end;
function FSCTLUnlock(Dev:THandle):BOOL;
begin
Result:=DeviceIOControl(Dev,FSCTL_UNLOCK_VOLUME,nil,0,nil,0,cb,nil);
end;
{ INT13H;
AH = 02h (read)
AL = number of sectors to read (must be nonzero)
CH = low eight bits of cylinder number
CL = sector number 1-63 (bits 0-5)
high two bits of cylinder (bits 6-7, hard disk only)
DH = head number
DL = drive number (bit 7 set for hard disk)
ES:BX -> data buffer
}
function tfrm.INT13Read(Dev:thandle;
Drive:byte;
//drive not used
StartSector:dword;
Sectors:word;
Bufointer):BOOL;
var reg:TDIOCRegisters;
dio:TDiskIO;
pak:TDisk_Addr_pkt;
const INT13H_READ = $0200;
DRIVE_C = $80;
begin
dio.StartSector:=StartSector;
dio.Sectors:=Sectors;
dio.Buffer:=dword(Buf);
fillchar(pak, sizeof(pak),0);
pak.packet_size:=16;
//must be (at least) 16
pak.block_count:=sectors;
pak.buffer_addr:=dword(Buf);
pak.block_num:=StartSector;
fillchar(reg, sizeof(reg),0);
if Sectors>0 then
reg.reg_EAX:=INT13H_READ + Sectors //mov AH,02
mov AL,Sectors
else
reg.reg_EAX:=INT13H_READ + 1;
//mov AH,02
mov AL,Sectors
if StartSector>0 then
reg.reg_ECX:=StartSector //CL Sector Number
else
reg.reg_ECX:=1;
//CH Cylinder Number, wiped off
reg.reg_EDX:=DRIVE_C;
//DH = head no - cleared off
reg.reg_EBX:=dword(Buf);
//dword(@dio);
Result:=DeviceIOControl(Dev, VWIN32_DIOC_DIOS_INT13,
@reg, sizeof(reg), @reg, sizeof(reg), cb, pOverlapped(0));
if Result then
Result:=
Result and (not boolean(reg.reg_Flags and CARRY_FLAG));
end;
function tfrm.INT13Write(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Bufointer):BOOL;
var reg:TDIOCRegisters;
dio:TDiskIO;
begin
dio.StartSector:=StartSector;
dio.Sectors:=Sectors;
dio.Buffer:=dword(Buf);
fillchar(reg, sizeof(reg),0);
reg.reg_EAX:=Drive-1;
reg.reg_EBX:=dword(@dio);
reg.reg_ECX:=$FFFF;
Result:=DeviceIOControl(Dev, VWIN32_DIOC_DIOS_INT13,
@reg, sizeof(reg), @reg, sizeof(reg), cb, pOverlapped(0));
if Result then
Result:=
Result and (not BOOL(reg.reg_Flags and CARRY_FLAG));
end;
//INT25H-26H DID NOT WORK WITH FAT32
function tfrm.INT25ReadLogicalSectors(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Bufointer):BOOL;
var reg:TDIOCRegisters;
dio:TDiskIO;
begin
dio.StartSector:=StartSector;
dio.Sectors:=Sectors;
dio.Buffer:=dword(Buf);
fillchar(reg, sizeof(reg),0);
reg.reg_EAX:=Drive-1;
// zero based
reg.reg_EBX:=dword(@dio);
reg.reg_ECX:=$FFFF;
// use DISKIO structure
Result:=DeviceIOControl(Dev, VWIN32_DIOC_DIOS_INT25,
@reg, sizeof(reg), @reg, sizeof(reg), cb, pOverlapped(0));
if Result then
Result:=
Result and (not boolean(reg.reg_Flags and CARRY_FLAG));
end;
//INT25H-26H DID NOT WORK WITH FAT32
function tfrm.INT26WriteLogicalSectors(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Bufointer):BOOL;
var reg:TDIOCRegisters;
dio:TDiskIO;
begin
dio.StartSector:=StartSector;
dio.Sectors:=Sectors;
dio.Buffer:=dword(Buf);
fillchar(reg, sizeof(reg),0);
reg.reg_EAX:=Drive-1;
reg.reg_EBX:=dword(@dio);
reg.reg_ECX:=$FFFF;
Result:=DeviceIOControl(Dev, VWIN32_DIOC_DIOS_INT26,
@reg, sizeof(reg), @reg, sizeof(reg), cb, pOverlapped(0));
if Result then
Result:=
Result and (not BOOL(reg.reg_Flags and CARRY_FLAG));
end;
function tfrm.ReadSectors(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Bufointer):BOOL;
var reg:TDIOCRegisters;
dio:TDiskIO;
begin
dio.StartSector:=StartSector;
dio.Sectors:=Sectors;
dio.Buffer:=dword(Buf);
fillchar(reg, sizeof(reg),0);
reg.reg_EAX:=$7305;
// Ext_Abs_Disk_Read_Write
reg.reg_EBX:=dword(@dio);
reg.reg_ECX:=-1;
reg.reg_EDX:=Drive;
// 1-based INT21H-7305H
Result:=DeviceIOControl(Dev, VWIN32_DIOC_DIOS_DRIVEINFO,
@reg, sizeof(reg), @reg, sizeof(reg), cb, pOverlapped(0));
if Result then
Result:=
Result and (not BOOL(reg.reg_Flags and CARRY_FLAG));
end;
function tfrm.WriteSectors(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Bufointer):BOOL;
var reg:TDIOCRegisters;
dio:TDiskIO;
begin
dio.StartSector:=StartSector;
dio.Sectors:=Sectors;
dio.Buffer:=dword(Buf);
fillchar(reg, sizeof(reg),0);
reg.reg_EAX:=$7305;
// Ext_Abs_Disk_Read_Write
reg.reg_EBX:=dword(@dio);
reg.reg_ECX:=-1;
reg.reg_EDX:=Drive;
// 1-based INT21H-7305H
reg.reg_ESI:=$6001;
// Normal file data
Result:=DeviceIOControl(Dev, VWIN32_DIOC_DIOS_DRIVEINFO,
@reg, sizeof(reg), @reg, sizeof(reg), cb, pOverlapped(0));
if Result then
Result:=
Result and (not BOOL(reg.reg_Flags and CARRY_FLAG));
end;
function tfrm.ReadTrack(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Bufointer):BOOL;
var reg:TDIOCRegisters;
Block:TRWBlock;
begin
Block.SpecFunc:=0;
Block.Head:=0;
Block.Cylinder:=0;
Block.FirstSector:=StartSector;
Block.Sectors:=Sectors;
Block.Buffer:=dword(Buf);
fillchar(reg, sizeof(reg),0);
reg.reg_EAX:=$440D;
// IOCTL for Block Device
reg.reg_EBX:=Drive;
reg.reg_ECX:=$4861;
// Read Track Win95 OSR2
reg.reg_EDX:=dword(@Block);
// DTA
Result:=DeviceIOControl(Dev, VWIN32_DIOC_DIOS_IOCTL,
@reg, sizeof(reg), @reg, sizeof(reg), cb, pOverlapped(0));
if Result then
Result:=
Result and (not BOOL(reg.reg_Flags and CARRY_FLAG));
end;
function tfrm.WriteTrack(Dev:thandle;
Drive:byte;
StartSector:dword;
Sectors:word;
Bufointer):BOOL;
begin
Result:=FALSE;
end;
procedure Tfrm.GetDevHandleNoClick(Sender: TObject);
begin
hDevice:=GetDeviceHandle;
if hDevice=INVALID_HANDLE_VALUE then
begin
ShowErr('Invalid handle!', hDevice);
CloseDevHandle.OnClick:=nil;
GetDevHandleNnClick:=GetDevHandleNoClick;
end
else
begin
ShowErr('Handle OK', hDevice);
GetDevHandleNnClick:=nil;
CloseDevHandle.OnClick:=CloseDevHandleClick;
end;
end;
procedure Tfrm.CloseDevHandleClick(Sender: TObject);
begin
if CloseHandle(hDevice) then
begin
ShowErr('Handle closed', hDevice);
CloseDevHandle.OnClick:=nil;
GetDevHandleNnClick:=GetDevHandleNoClick;
end
else
begin
ShowErr('Couldn''t close handle!', hDevice);
GetDevHandleNnClick:=nil;
CloseDevHandle.OnClick:=CloseDevHandleClick;
end;
end;
procedure Tfrm.ToolButton5Click(Sender: TObject);
var i:integer;
begin
if hDevice=INVALID_HANDLE_VALUE then
begin
ShowErr('Invalid handle!', hDevice);
exit;
end;
if LockPhysVolume(hDevice, 1) then
begin
if LockPhysVolume(hDevice, 2) then
begin
if LockPhysVolume(hDevice, 3) then
begin
//showErr('locked-3', hDevice);
Success:=INT25ReadLogicalSectors(hDevice, spindriveno.value,
spinsecstart.value, spinsecnum.value, @B);
for i:=1 to 3do
UnLockPhysVolume(hDevice, 3);
end;
end;
end;
if Success then
hexen(B, cb)
else
ShowErr('error', -1);
end;
procedure Tfrm.ToolButton6Click(Sender: TObject);
begin
//
end;
procedure Tfrm.ToolButton8Click(Sender: TObject);
var i:integer;
begin
if hDevice=INVALID_HANDLE_VALUE then
begin
ShowErr('Invalid handle!', hDevice);
exit;
end;
if LockPhysVolume(hDevice, 1) then
begin
if LockPhysVolume(hDevice, 2) then
begin
if LockPhysVolume(hDevice, 3) then
begin
//showErr('locked-3', hDevice);
Success:=ReadSectors(hDevice, spindriveno.value, spinsecstart.value,
spinsecnum.value, @B);
for i:=1 to 3do
UnLockPhysVolume(hDevice, 3);
end;
end;
end;
if Success then
hexen(B, cb)
else
ShowErr('error', -1);
end;
procedure Tfrm.ToolButton9Click(Sender: TObject);
var i:integer;
const S:String='TESTA';
startpoint:integer=3;
begin
if Application.MessageBox('Are You Sure?','Absolute write confirmation',
MB_OKCANCEL) <> IDOK then
exit;
if hDevice=INVALID_HANDLE_VALUE then
begin
ShowErr('Invalid handle!', hDevice);
exit;
end;
S:='TESTA';
//STRING TO BE WRITTEN
move(S[1],B[startpoint],SizeOf(S));
if LockPhysVolume(hDevice, 1) then
begin
if LockPhysVolume(hDevice, 2) then
begin
if LockPhysVolume(hDevice, 3) then
begin
//showErr('locked-3', hDevice);
Success:=WriteSectors(hDevice, spindriveno.value, spinsecstart.value,
spinsecnum.value, @B);
for i:=1 to 3do
UnLockPhysVolume(hDevice, 3);
end;
end;
end;
if Success then
hexen(B, cb)
else
ShowErr('error', -1);
end;
procedure Tfrm.ToolButton11Click(Sender: TObject);
var i:integer;
begin
if hDevice=INVALID_HANDLE_VALUE then
begin
ShowErr('Invalid handle!', hDevice);
exit;
end;
if LockPhysVolume(hDevice, 1) then
begin
if LockPhysVolume(hDevice, 2) then
begin
if LockPhysVolume(hDevice, 3) then
begin
//remove the message, it's 3-rd level LOCK!
// showErr('locked-3', hDevice);
//change it with flag indicating OK
Success:=TRUE;
//uncomment pair of lines below to check read/write mode
//OK Success:=ReadSectors(hDevice, spindriveno.value, spinsecstart.value,
// spinsecnum.value, @B);
//OK Success:=ReadLogicalSectors(hDevice, spindriveno.value, spinsecstart.value,
// spinsecnum.value, @B);
//NOT Success:=ReadTrack(hDevice, spindriveno.value, spinsecstart.value,
// spinsecnum.value, @B);
// Success:=INT13Read(hDevice, spindriveno.value, spinsecstart.value,
// spinsecnum.value, @B);
//???-test
// if SetFilePointer(hDevice,512,nil,FILE_begin
)=512 then
for i:=1 to 3do
UnLockPhysVolume(hDevice, 3);
end;
end;
end;
if Success then
begin
ShowErr('Success', hDevice);
end
else
ShowErr('error', -1);
hexen(B, cb);
end;
procedure Tfrm.ToolButton12Click(Sender: TObject);
begin
//
end;
procedure Tfrm.FormCreate(Sender: TObject);
begin
GetDevHandleNoClick(GetDevHandleNo);
end;
procedure Tfrm.ToolButton13Click(Sender: TObject);
var S:string;
begin
S:='Locked Fails';
//start with block-1, ie. sector after PARTITION TABLE
if SetFilePointer(hDevice,512,nil,FILE_begin
)=512 then
//ReadFile(hdevice, B, spinsecnum.value*512, cb, POverlapped(0));
if ReadFile(hdevice, B, spinsecnum.value*512, cb, POverlapped(0)) then
begin
if FSCTLLock(hDevice) then
begin
S:='Locked OK';
FSCTLUnlock(hDevice);
hexen(B, spinsecnum.value*512);
end;
end;
ShowErr(S, hdevice);
end;
procedure Tfrm.ToolButton14Click(Sender: TObject);
var S:string;
const T:String='TESTA';
startpoint:integer=3;
begin
S:='Locked Fails';
T:='TESTA';
//start with block-1, ie. sector after PARTITION TABLE
if SetFilePointer(hDevice, 512, nil, FILE_begin
)=512 then
//ReadFile(hdevice, B, spinsecnum.value*512, cb, POverlapped(0));
if ReadFile(hdevice, B, spinsecnum.value*512, cb, POverlapped(0)) then
begin
SetFilePointer(hDevice, 512, nil, FILE_begin
);
move(T[1],B[startpoint],sizeof(T));
if FSCTLLock(hDevice) then
begin
if WriteFile(hdevice,B,spinsecnum.value*512,cb,POverlapped(0)) then
S:='Locked OK';
FSCTLUnlock(hDevice);
hexen(B, spinsecnum.value*512);
end;
end;
ShowErr(S, hdevice);
end;
end.