]、。·ˉˇ¨〃々—~‖…’”〕〉》」』〗】∶!"'),.:;?]` 在9x下直接访问硬盘
在Windows9X中,由于内存和进程的保护,直接使用INT将会引起GPFs。
在很多资料上都说要在windows中直接读写硬盘的方法只有使用VxD。这并
不是真的,事实上使用windows9x公开的API就可以直接对硬盘进行操作。
在microsoft programmer's guide to win95中,关于Device I/O Control
中就有说明如何使用VWIN32呼叫MSDOS系统服务(磁盘访问类)。
定义了一下5个控制码
VWIN32_DIOC_DOS_DRIVEINFO (6) INT 21h AX=730Xh,win95 osr2与以后
版本提供的FAT32文件系统的访问
VWIN32_DIOC_DOS_INT13 (4) BIOS INT13h
VWIN32_DIOC_DOS_INT25 (2) DOS INT25h
VWIN32_DIOC_DOS_INT26 (3) DOS INT26h
VWIN32_DIOC_DOS_IOCTL (1) DOS设备I/O,(int 21h,ax=4400h到4411h)
使用方法如下:
使用
CreateFile("\\\\.\\vwin32",0,0,NULL,0,FILE_FLAG_DELETE_ON_CLOSE,NULL);
打开vwin32.vxd
根据调用的功能所用到的寄存器填充以下结构体:
typedef struct _DIOC_REGISTERS {
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
} DIOC_REGISTERS, *PDIOC_REGISTERS;
使用
DeviceIoControl(hDevice,CONTROL_CODE,®,sizeof(reg),®,sizeof(reg),
&dwBytesReturn,0);
调用MS-DOS的磁盘访问功能。
最后调用 CloseHandle(hDevice);
************************
//下面的两个文件就是在WIN32下访问INT 25和INT 26
//文件1
{=====================================================================}
{ Device I/O Unit for Delphi 2.0, for Windows95 13/Oct./'97 }
{ http://www.kobira.co.jp/sakura/windows.htm }
{ author Seiji-Yasuda seiji@kobira.co.jp }
{ }
{ You may use it freely at your own risk in any kind of environment. }
{ }
{=====================================================================}
unit dev_io;
interface
uses
Windows,SysUtils;
type
REGSTER = packed record
reg_ebx : DWORD;
reg_edx : DWORD;
reg_ecx : DWORD;
reg_eax : DWORD;
reg_edi : DWORD;
reg_esi : DWORD;
reg_cflag : DWORD;
end;
const
WIN95_IOCTL_DEV = '\\.\vwin32';
WIN32_DOS_IOCTL = 1;
WIN32_DOS_INT25 = 2;
WIN32_DOS_INT26 = 3;
function win95_ioctl( cmd:Integer; var regs: REGSTER ):boolean;
implementation
function win95_ioctl( cmd:Integer; var regs: REGSTER ):boolean;
var
hd:THandle; ret:DWORD; ans:Boolean;
begin
Result := False;
try
{Open WIN95_IOCTL_DEV}
hd := 0;
hd := CreateFile(WIN95_IOCTL_DEV,0,0,NIL,0,FILE_FLAG_DELETE_ON_CLOSE,0);
if hd = 0 then
exit;
{Device I/O Control}
ans := DeviceIoControl(hd,cmd,@regs,sizeof(regs),@regs,sizeof(regs),ret,NIL);
if not ans then
exit;
Result := True;
finally
{Close WIN95_IOCTL_DEV}
CloseHandle(hd);
end;
end;
end.
//文件2
{=====================================================================}
{ DOS Int25/26 Unit for Delphi 2.0, for Windows95 13/Oct./'97 }
{ http://www.kobira.co.jp/sakura/windows.htm }
{ author Seiji-Yasuda seiji@kobira.co.jp }
{ }
{ You may use it freely at your own risk in any kind of environment. }
{ }
{=====================================================================}
unit disk2526;
interface
uses
Windows, SysUtils, dev_io;
function DOS_IOErrToStr(ret:Integer):String;
function DOS_25h_DiskRead(Drive:Integer;Buffer:PChar;
StartSector,Count:Integer; var ret:Integer):Boolean;
function DOS_26h_DiskWrite(Drive:Integer;Buffer:PChar;
StartSector,Count:Integer; var ret:Integer):Boolean;
implementation
//==============================================================================
// DOS Function to string (I/O Request error)
//==============================================================================
function DOS_IOErrToStr(ret:Integer):String;
begin
case ret of
$00: Result := 'disk is write-protected';
$01: Result := 'bad disk unit';
$02: Result := 'drive is not ready';
$03: Result := 'invalid disk command';
$04: Result := 'CRC error';
$05: Result := 'invalid length (disk operation)';
$06: Result := 'seek error';
$07: Result := 'wrong disk';
$08: Result := 'sector not found';
$09: Result := 'out of paper';
$0a: Result := 'write fault';
$0b: Result := 'read fault';
$0c: Result := 'general fault';
$0f: Result := 'invalid disk change';
else
Result := 'unknown';
end;
end;
//==============================================================================
// DOS INT 25h Function
// ret : -1...ioctl function error. etc...I/O Request error code.
//==============================================================================
function DOS_25h_DiskRead(Drive:Integer;Buffer:PChar;
StartSector,Count:Integer; var ret:Integer):Boolean;
var
regs : REGSTER;
begin
regs.reg_EAX := DWORD(Drive); // AL: 0:A, 1:B..
regs.reg_EBX := DWORD(Buffer); // buffer
regs.reg_ECX := DWORD(Count); // read sector count.
regs.reg_EDX := DWORD(StartSector); // start sector
regs.reg_cflag := DWORD($00000001); // clear cflg.
if (not win95_ioctl(WIN32_DOS_INT25,regs)) then begin
Result := False;
ret := -1;
exit;
end;
if (regs.reg_cflag and $00000001) <> 0 then begin
Result := False;
ret := Integer(regs.reg_EAX and $0000000f);
exit;
end;
Result := True;
end;
//==============================================================================
// DOS INT 26H Function
// ret : -1...ioctl function error. etc...I/O Request error code.
//==============================================================================
function DOS_26h_DiskWrite(Drive:Integer;Buffer:PChar;
StartSector,Count:Integer; var ret:Integer):Boolean;
var
regs : REGSTER;
begin
regs.reg_EAX := DWORD(Drive); // AL: 0:A, 1:B..
regs.reg_EBX := DWORD(Buffer); // buffer
regs.reg_ECX := DWORD(Count); // write sector count.
regs.reg_EDX := DWORD(StartSector); // start sector
regs.reg_cflag := DWORD($00000001); // clear cflg.
if (not win95_ioctl(WIN32_DOS_INT26,regs)) then begin
Result := False;
ret := -1;
exit;
end;
if (regs.reg_cflag and $00000001) <> 0 then begin
Result := False;
ret := Integer(regs.reg_EAX and $0000000f);
exit;
end;
Result := True;
end;
end.