Summary: This article introduces knowledge about DOS disk systems, and discusses more in-depth discussion on how to block DOS disk system serious errors
Key words: DOS disk system is serious, interrupt vector, interrupt modification, disk detection (Disk verifying)
When designing the C language program, the programmer may encounter such an embarrassing scene: the user-designed user interface is destroyed by DOS disk error prompts such as "Not Ready Reading Drive A", which is catastrophic. This problem may appear when the programmer uses the Fopen function to operate the file on the A disk. For the convenience of discussions, we have divided the disk system serious errors: disk detection errors (such as the sector is not found, disk is not prepared, write protection errors, etc.), general hardware errors (such as prompt "General Fail in Drive A "Wait) and disk software errors (such as files do not exist). As long as these three issues are solved, then the main issues of this article are solved.
1. Disk detection error
The 1H subscription in the 13H interrupt call provided by the BIOS system is a Verify Disk Sector. Calling this disk detection function to obtain some disk status, such as whether the disk is ready. The return parameters of this feature are as follows: In the disk system, the changing plate is also considered an error, but for the user, the changing operation is allowed, so this function should be at least three times, and then determine the return parameter to ensure correctness.
The disk sector detection function can detect some hardware errors of the disk such as "no find", "Disk is not prepared", but there are still some errors, such as write protection errors. To this end, we can only use the physical sector of the disk to determine the state of the disk or drive, the method is: first read a sector (read three times), write the sector back (write three times) with 13h 03h function , Finally judge the return parameter of the 03H function (return parameter format is the same as 04h). The following program implements this feature, if the results, return 0, if the error is fails, returns the error code.
Void iosector (unsigned drive, unsigned action,
INT Head, Int Seig, Int Cylinder,
Unsigned char * buffer)
{
Regs.h.ah = Action; regs.h.al = 1;
Regs.h.ch = cylinder; regs.h.cl = sector;
Regs.h.dh = head; regs.h.dl = drive;
Regs.x.bx = fp_off (buffer); Sregs.es = fp_seg (buffer);
INT86X (0x13, & Regs, & Regs, & Sregs);
}
INT Checksector (unsigned drive, unsigned head, unsigned, unsigned
Cylinder
{
INT I;
UNSIGNED Char Temp [512];
For (i = 0; i <3; i ) iosector (drive, 0x02, 0, 1, 0, temp);
For (i = 0; i <3; i )
{
Regs.h.ah = 3; regs.h.al = 1;
Regs.x.bx = fp_off (temp);
SREGS.ES = fp_seg (TEMP);
Regs.h.ch = cylinder;
Regs.h.cl = sector;
Regs.h.dh = head;
Regs.h.dl = drive;
INT86X (0x13, & Regs, & Regs, & Sregs);
}
IF (regs.x.cflag)
Return regs.h.ah;
Else
Return 0;
}
For example, Err = Checksector (0, 0, 1, 0) can be used to obtain the value of ERR, and then determine the state of the A disk or drive.
Readers CAUTION: You can also use the BIOS 13H function, 01 subsystems to implement disk status tests, which will be more simple and convenient. If you are interested, you can write a disk status test function in accordance with the above method.
Attachment: Entrance parameters: AH = 01H, DL = Drive (bit 7 set for hard disk)
Export Parameters: Cf Clear if Successful (Return Value = 0), SET for ERROR
AH = Status of Previous Operation. (See Appendex)
2, general hardware error
To resolve these errors, you can only modify the interrupt vector. The 24H interrupt of DOS is a serious error interruption, and the interrupt is activated when the error occurs. This interrupt program is very special, it does not require programmers to recover the definition of the 24H interrupt when exiting the program, these things DOS will deal with it. The programmer can only set only one flag in the 24H interrupt program to represent "Errors" event, and finally, in the main program, it is judged to judge whether such errors have occurred. The implementation code of this operation is as follows:
#include
#ifdef __cplusplus
#define __argument ...
#ELSE
#define __ARGUMENT
#ENDIF
INT globaler = 0;
Void Interrupt New24 (__ARGUMENT)
{
Globalerr = 1;
}
Void Install (__ argument), int Num)
{
disable ();
SetVect (NUM, FADD);
ENABLE ();
}
void main ()
{
Install (new24, 0x24);
}
3, disk software error
This type of error is easier to solve, as long as the error flag is set after the file fails.
During the C language program design, the severity of the DOS disk system can be shielded in conjunction with the above three methods, so that the user interface will not be destroyed when the error occurs. At the end of this article, it is a complete test program. Interested readers may wish to debug it up. I believe it is very big for you.
#include
#include
#include
#define color (x, y) TextColor (x); Textbackground (Y)
#define locate (x, y) gotoxy (x, y)
#ifdef __cplusplus
#define __argument ...
#ELSE
#define __ARGUMENT
#ENDIF
INT globaler = 0;
Union regs regs;
Struct Sregs Sregs;
Void Interrupt New24 (__ argument) {
Globalerr = 1;
}
Void Install (__ argument), int Num)
{
disable ();
SetVect (NUM, FADD);
ENABLE ();
}
Void iosector (unsigned drive, unsigned action,
INT Head, Int Seig, Int Cylinder,
Unsigned char * buffer)
{
Regs.h.ah = Action; regs.h.al = 1;
Regs.h.ch = cylinder; regs.h.cl = sector;
Regs.h.dh = head; regs.h.dl = drive;
Regs.x.bx = fp_off (buffer); Sregs.es = fp_seg (buffer);
INT86X (0x13, & Regs, & Regs, & Sregs);
}
INT Checksector (unsigned drive, unsigned head, unsigned, unsigned
Cylinder
{
INT I;
UNSIGNED Char Temp [512];
For (i = 0; i <3; i ) iosector (drive, 0x02, 0, 1, 0, temp);
For (i = 0; i <3; i )
{
Regs.h.ah = 3;
Regs.h.al = 1;
Regs.x.bx = fp_off (temp);
SREGS.ES = fp_seg (TEMP);
Regs.h.ch = cylinder;
Regs.h.cl = sector;
Regs.h.dh = head;
Regs.h.dl = drive;
INT86X (0x13, & Regs, & Regs, & Sregs);
}
IF (regs.x.cflag)
Return regs.h.ah;
Else
Return 0;
}
void main ()
{
File * fp;
INT Verifyerr = 0, fpointerr = 0;
Install (new24, 0x24);
Color (15, 1);
CLRSCR ();
Verifyerr = Checksector (0, 0, 1, 0);
IF ((fp = fopen ("A: //Abc.txt", "RB")) == null) fpointerr = 1;
IF (Globalerr)
{
Locate (10, 10);
CPrintf ("Hardware Error!");
Goto handle;
}
IF (Verifyerr)
{
Locate (10, 10);
CPrintf ("Disk error: Code% XH", Verifyerr);
Goto handle;
}
IF (fpointerr)
{
Locate (10, 10);
CPRINTF ("Unable to seek file!");
Goto handle;
}
Printf ("% XH / N", FGETC (FP));
Handle:
Fclose (fp);
Getch ();
}
Appendix: Disk operation status reference
00h Successful Completion
01h Invalid Function in Ah Or Invalid Parameter
02H Address Mark Not Found03h Disk Write-Protected
04H Sector Not Found / Read Error
05H RESET FAILED (HARD DISK)
05h Data Did Not Verify Correctly (Ti Professional PC)
06h disk change (Floppy)
07h Drive Parameter Activity Faird (Hard Disk)
08H DMA overrun
09h Data Boundary Error (Attempted DMA Across 64K Boundary Or> 80h Sectors)
0AH Bad Sector Detected (Hard Disk)
0BH Bad TRACK Detected (Hard Disk)
0ch unsupported TRACK OR Invalid Media
0DH INVALID NUMBER OF SECTORS ON FORMAT (PS / 2 HARD DISK)
0EH Control Data Address Mark Detected (Hard Disk)
0FH DMA Arbitration Level Out of Range (Hard Disk)
10h uncoRrectable CRC or ECC Error on Read
11h Data ECC CORRECTED (HARD DISK)
20h Controller Failure
31H NO Media In Drive (IBM / MS INT 13 EXTENSIONS)
32h IncorRect Drive Type Stored In CMOS (Compaq)
40h seek failed
80H Timeout (Not Ready)
AAH Drive Not Ready (Hard Disk)
B0H Volume Not Locked in Drive (int 13 extensions)
B1H Volume Locked in Drive (int 13 extensions)
B2H Volume Not Removable (INT 13 EXTENSIONS)
B3H Volume in Use (int 13 extensions)
B4H Lock Count Exceeded (INT 13 EXTENSIONS)
B5H Valid Eject Request Faled (INT 13 EXTENSIONS)
BBH Undefined Error (HARD DISK)
CCH Write Fault (Hard Disk)
E0H STATUS Register Error (Hard Disk)
FFH SENSE OPERATION FAILED (HARD DISK)