Battle DeviceIocontrol 7: Read the disk sector in Windows 9x

zhaozj2021-02-16  47

In Windows NT / 2K / XP, open the name directly with "//./a:" with "//./a:", you can drive it with the device, and access the disk with the readFile / WriteFile. But Windows 9x does not support this simple method. This article describes a method of implementing a disk directly accessed in Windows 9x: Use the system's vwin32.vxd, complete the DOS INT21 7305H and 440DH functionality through DeviceIoControl. This call supports FAT12, FAT16, and FAT32 for Windows 95 SR2 and higher.

Let's take a look at the entrance parameters of the DOS INT21 7305H function:

AX - Function No. 7305H

DS: BX - Information structure for reading and writing sectors

CX - must be -1

DL - Drive Number: 1 = A:, 2 = B: 3 = C: ...

Si - read and write logo: lowest 0 = read, 1 = write

If you call success, clear the C flag; otherwise set the C flag.

DS: BX points to a structure, this structure is defined as follows:

Diskio Struc

DWSTARTSECTOR DD?; start sector

WSECTOR DW?;

LPBuffer DD?; Data buffer address

Diskio Ends

Under Write operation, you need to "lock" drives. The 4AH / 6AH feature of DOS INT21 440DH enables lock / unlocks of logical drives. The entrance parameters are:

AX - Function number 440DH

BH - lock level, 0-3, direct writing sectors 1

BL - Drive Number: 1 = A: 2 = B: 3 = C: ...

CH - 0x08

CL - 0x4a

DX - 0

AX - Function number 440DH

BL - Drive Number: 1 = A: 2 = B: 3 = C: ...

CH - 0x08

CL - 0x6A

The above two calls, if the success is successful, clear the C flag; otherwise set the C flag.

The above interrupt is called by IOCTL code VWIN32_DIOC_DOS_DRIVEINFO. The key code to achieve absolute disk read and write is as follows:

// int21 IOCTL code

#define vwin32_dioc_dos_iocTl 1

#define vwin32_dioc_dos_driveInfo 6

// Register group

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;

// IO parameters (pay attention to byte alignment)

#pragma pack (1)

Typedef struct _diskio {

DWORD DWSTARTSector; // Start sector

Word Wsectors; // Distance

Void * pBuffer; // buffer pointer

} DISKIO, * PDISKIO;

#pragma pack ()

Bool absdiskread

Byte ndisknumber, // disk number, 1 = A:, 2 = B:, 3 = C:, ...

DWORD DWSTARTSector, // Start sector

Word Wsectors, // Distance

VOID * PBUFFER) // Data buffer pointer {

Handle HDevice;

DIOC_REGISTERS Regs;

Diskio DIO;

DWORD DWOUTBYTES;

Bool Bresult;

// Open the device to get a VXD handle

HDevice = CREATEFILE (".// vwin32", // device path

Generic_read | generic_write, // Read and write

File_share_read | file_share_write, // shared method

NULL, / / ​​Default security descriptor

Open_existing, // creation method

FILE_ATTRIBUTE_NORMAL, // File Properties

NULL); // Do not need to refer to the template file

IF (HDevice == Invalid_Handle_Value)

{

Return False;

}

// Fill the DISKIO parameter structure

Dio.dwstartsector = dwstartsector;

Dio.wsectors = WSECTORS;

Dio.pbuffer = pbuffer;

// Fill Register Group - Interrupt Portactor

MEMSET (& Regs, 0, SizeOf (Dioc_registers);

Regs.reg_eax = 0x7305; // AX = 0x7305

Regs.reg_ebx = (dword) & dio; // EBX = DS: bx = parameter pointer

Regs.reg_ecx = 0xfffff; // CX = -1

Regs.reg_edx = ndiskNumber; // DL = disk number

Regs.reg_esi = 0; // si = 0 - read operation

// Read the disk with vwin32_dioc_dos_driveinfo

DwoutBytes = 0;

BRESULT = Deviceiocontrol (HDevice, // Equipment handle

Vwin32_dioc_dos_driveinfo, // int21

& regs, sizeof (regs), // output data buffer and length

& regs, sizeof (regs), // output data buffer and length

& dwoutBytes, // Output data length

Null); // with synchronous I / O

/ / Determine that DeviceIocontrol and INT21 have no error

BRESULT = BRESULT &&! (regs.reg_flags & 1);

CloseHandle (HDEvice);

Return BRESULT;

}

Bool absdiskwrite

Byte ndisknumber, // disk number, 1 = A:, 2 = B:, 3 = C:, ...

DWORD DWSTARTSector, // Start sector

Word Wsectors, // Distance

VOID * PBUFFER) // Data buffer pointer {

Handle HDevice;

DIOC_REGISTERS Regs;

Diskio DIO;

DWORD DWOUTBYTES;

Bool Bresult;

// Open the device to get a VXD handle

HDevice = CREATEFILE (".// vwin32", // device path

Generic_read | generic_write, // Read and write

File_share_read | file_share_write, // shared method

NULL, / / ​​Default security descriptor

Open_existing, // creation method

FILE_ATTRIBUTE_NORMAL, // File Properties

NULL); // Do not need to refer to the template file

IF (HDevice == Invalid_Handle_Value)

{

Return False;

}

// Fill the DISKIO parameter structure

Dio.dwstartsector = dwstartsector;

Dio.wsectors = WSECTORS;

Dio.pbuffer = pbuffer;

// Fill Register Group - Interrupt Portactor

MEMSET (& Regs, 0, SizeOf (Dioc_registers);

Regs.reg_eax = 0x7305; // AX = 0x7305

Regs.reg_ebx = (dword) & dio; // EBX = DS: bx = parameter pointer

Regs.reg_ecx = 0xfffff; // CX = -1

Regs.reg_edx = ndiskNumber; // DL = disk number

Regs.reg_esi = 0x6001; // si = 0x6001 - ordinary write operation

// Write disk with vwin32_dioc_dos_driveinfo

DwoutBytes = 0;

BRESULT = Deviceiocontrol (HDevice, // Equipment handle

Vwin32_dioc_dos_driveinfo, // int21

& regs, sizeof (regs), // output data buffer and length

& regs, sizeof (regs), // output data buffer and length

& dwoutBytes, // Output data length

Null); // with synchronous I / O

/ / Determine that DeviceIocontrol and INT21 have no error

BRESULT = BRESULT &&! (regs.reg_flags & 1);

CloseHandle (HDEvice);

Return BRESULT;

}

Bool LockVolume

Byte ndisknumber) / / disk number, 1 = A:, 2 = B:, 3 = C:, ...

{

Handle HDevice;

DIOC_REGISTERS Regs;

DWORD DWOUTBYTES;

Bool Bresult; // Open the device to get the VXD handle

HDevice = CREATEFILE (".// vwin32", // device path

Generic_read | generic_write, // Read and write

File_share_read | file_share_write, // shared method

NULL, / / ​​Default security descriptor

Open_existing, // creation method

FILE_ATTRIBUTE_NORMAL, // File Properties

NULL); // Do not need to refer to the template file

IF (HDevice == Invalid_Handle_Value)

{

Return False;

}

// Fill Register Group - Interrupt Portactor

MEMSET (& Regs, 0, SizeOf (Dioc_registers);

Regs.reg_eax = 0x440d; // AX = 0x440d

Regs.reg_ebx = 0x0100 | ndisknumber; // BH = Lock level, BL = disk number

Regs.reg_ecx = 0x084a;

Regs.reg_edx = 0;

// Read the disk with vwin32_dioc_dos_driveinfo

DwoutBytes = 0;

BRESULT = Deviceiocontrol (HDevice, // Equipment handle

Vwin32_dioc_dos_iocTl, // int21

& regs, SIZEOF (Regs), // Enter data buffer and length

& regs, sizeof (regs), // output data buffer and length

& dwoutBytes, // Output data length

Null); // with synchronous I / O

/ / Determine that DeviceIocontrol and INT21 have no error

BRESULT = BRESULT &&! (regs.reg_flags & 1);

CloseHandle (HDEvice);

Return BRESULT;

}

Bool unlockvolume

Byte ndisknumber) / / disk number, 1 = A:, 2 = B:, 3 = C:, ...

{

Handle HDevice;

DIOC_REGISTERS Regs;

DWORD DWOUTBYTES;

Bool Bresult;

// Open the device to get a VXD handle

HDevice = CREATEFILE (".// vwin32", // device path

Generic_read | generic_write, // Read and write

File_share_read | file_share_write, // shared method

NULL, / / ​​Default security descriptor

Open_existing, // creation method

File_attribute_normal, // file attribute null; // Do not need to reference template files

IF (HDevice == Invalid_Handle_Value)

{

Return False;

}

// Fill Register Group - Interrupt Portactor

MEMSET (& Regs, 0, SizeOf (Dioc_registers);

Regs.reg_eax = 0x440d; // AX = 0x440d

Regs.reg_ebx = ndisknumber; // BL = disk number

Regs.reg_ecx = 0x086a;

// Read the disk with vwin32_dioc_dos_driveinfo

DwoutBytes = 0;

BRESULT = Deviceiocontrol (HDevice, // Equipment handle

Vwin32_dioc_dos_iocTl, // int21

& regs, SIZEOF (Regs), // Enter data buffer and length

& regs, sizeof (regs), // output data buffer and length

& dwoutBytes, // Output data length

Null); // with synchronous I / O

/ / Determine that DeviceIocontrol and INT21 have no error

BRESULT = BRESULT &&! (regs.reg_flags & 1);

CloseHandle (HDEvice);

Return BRESULT;

}

The following example begins with the 0 sector of the A disk, read the data of 10 sectors, and saves in the file:

UNSIGNED Char BUF [512 * 10];

IF (Absdiskread (1, 0, 10, BUF))

{

FILE * fp = fopen ("a.dat", "w b");

FWRITE (BUF, 512, 10, FP);

Fclose (fp);

}

The following example reads the 8888 sector of the D drive, then write back:

UNSIGNED Char BUF [512]

LockVolume (4);

IF (Absdiskread (4, 8888, 1, buf))

{

...

IF (AbsdiskWrite (4, 8888, 1, buf))

{

...

}

}

UNLOCKVOLUME (4);

In a write mode, the bit 0 of the Si register is set to 1, and the bit 15-13 needs to have different values ​​in different regions of the disk:

Bit 15bit 14bit 13description000other / unknown.001fat data.010directory data.011normal file data.100Reselved.

If you do not follow the above value, although it is possible to write success, the system cannot automatically complete the relevant functionality, it may cause problems with the FAT data backup, drive data compression.

[related resources]

BHW98 column: http://www.9cbs.net/develop/author/netauthor/bhw98/

First release: 2003-08-20 Last revision: 2003-09-12

转载请注明原文地址:https://www.9cbs.com/read-23665.html

New Post(0)