首页  编辑  

在9x下直接访问硬盘

Tags: /超级猛料/Hardware.硬件相关/驱动器相关/硬盘/   Date Created:

]、。·ˉˇ¨〃々—~‖…’”〕〉》」』〗】∶!"'),.:;?]` 在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,&reg,sizeof(reg),&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.