From bdc55699959077d444f27d16cf37933fcff6eaf7 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Wed, 24 Sep 2003 19:34:11 +0000 Subject: [PATCH] Set the Critical Error number immediately after calling a device driver. This solves problems with int24 handlers that call int21/ah=59. Let truename and blockrw return with an error if there is a critical error. Don't overwrite the critical error # with the DOS error #. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@709 6ac86273-5f31-0410-b378-82cca8765d1b --- hdr/device.h | 2 +- kernel/blockio.c | 2 +- kernel/dosfns.c | 5 +++-- kernel/error.c | 8 ++++++-- kernel/fatfs.c | 8 ++++---- kernel/inthndlr.c | 24 ++++++++++++------------ kernel/newstuff.c | 3 ++- kernel/proto.h | 2 +- 8 files changed, 30 insertions(+), 24 deletions(-) diff --git a/hdr/device.h b/hdr/device.h index 53167d7..156a737 100644 --- a/hdr/device.h +++ b/hdr/device.h @@ -462,7 +462,7 @@ ddt * getddt(int dev); /* error.c */ COUNT char_error(request * rq, struct dhdr FAR * lpDevice); -COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice); +COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice, int mode); /* sysclk.c */ WORD ASMCFUNC FAR clk_driver(rqptr rp); diff --git a/kernel/blockio.c b/kernel/blockio.c index 61a2021..2f0bec7 100644 --- a/kernel/blockio.c +++ b/kernel/blockio.c @@ -446,7 +446,7 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, return (IoReqHdr.r_status); loop: - switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device)) + switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device, mode)) { case ABORT: case FAIL: diff --git a/kernel/dosfns.c b/kernel/dosfns.c index 632903d..bca962a 100644 --- a/kernel/dosfns.c +++ b/kernel/dosfns.c @@ -306,8 +306,9 @@ long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode) } /* /// End of additions for SHARE - Ron Cemer */ { - UCOUNT XferCount; - XferCount = rwblock(s->sft_status, bp, n, mode); + long XferCount = rwblock(s->sft_status, bp, n, mode); + if (XferCount < 0) + return XferCount; if (mode == XFR_WRITE) s->sft_size = dos_getfsize(s->sft_status); s->sft_posit += XferCount; diff --git a/kernel/error.c b/kernel/error.c index 89c8d9d..84332fd 100644 --- a/kernel/error.c +++ b/kernel/error.c @@ -78,14 +78,18 @@ VOID fatal(BYTE * err_msg) /* Abort, retry or fail for character devices */ COUNT char_error(request * rq, struct dhdr FAR * lpDevice) { + CritErrCode = (rq->r_status & S_MASK) + 0x13; return CriticalError(EFLG_CHAR | EFLG_ABORT | EFLG_RETRY | EFLG_IGNORE, 0, rq->r_status & S_MASK, lpDevice); } /* Abort, retry or fail for block devices */ -COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice) +COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice, + int mode) { - return CriticalError(EFLG_ABORT | EFLG_RETRY | EFLG_IGNORE, + CritErrCode = (rq->r_status & S_MASK) + 0x13; + return CriticalError(EFLG_ABORT | EFLG_RETRY | EFLG_IGNORE | + (mode == DSKWRITE ? EFLG_WRITE : 0), nDrive, rq->r_status & S_MASK, lpDevice); } diff --git a/kernel/fatfs.c b/kernel/fatfs.c index a72d0db..63eb082 100644 --- a/kernel/fatfs.c +++ b/kernel/fatfs.c @@ -1537,7 +1537,7 @@ STATIC COUNT dos_extend(f_node_ptr fnp) /* Read/write block from disk */ /* checking for valid access was already done by the functions in dosfns.c */ -UCOUNT rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode) +long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode) { REG f_node_ptr fnp; REG struct buffer FAR *bp; @@ -1714,7 +1714,7 @@ UCOUNT rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode) mode == XFR_READ ? DSKREAD : DSKWRITE)) { fnp->f_offset = startoffset; - return ret_cnt; + return DE_ACCESS; } goto update_pointers; @@ -2080,7 +2080,7 @@ COUNT media_check(REG struct dpb FAR * dpbp) || !(MediaReqHdr.r_status & S_DONE)) { loop1: - switch (block_error(&MediaReqHdr, dpbp->dpb_unit, dpbp->dpb_device)) + switch (block_error(&MediaReqHdr, dpbp->dpb_unit, dpbp->dpb_device, 0)) { case ABORT: case FAIL: @@ -2129,7 +2129,7 @@ COUNT media_check(REG struct dpb FAR * dpbp) { loop2: switch (block_error - (&MediaReqHdr, dpbp->dpb_unit, dpbp->dpb_device)) + (&MediaReqHdr, dpbp->dpb_unit, dpbp->dpb_device, 0)) { case ABORT: case FAIL: diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 2e85b9f..7bc37af 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -400,8 +400,14 @@ dispatch: } #endif - if ((lr.AH >= 0x38 && lr.AH <= 0x4F) || (lr.AH >= 0x56 && lr.AH <= 0x5c)) + if ((lr.AH >= 0x38 && lr.AH <= 0x4F) || (lr.AH >= 0x56 && lr.AH <= 0x5c) || + (lr.AH >= 0x5e && lr.AH <= 0x60) || (lr.AH >= 0x65 && lr.AH <= 0x6a) || + lr.AH == 0x6c) + { CLEAR_CARRY_FLAG(); + if (lr.AH != 0x59) + CritErrCode = SUCCESS; + } /* Clear carry by default for these functions */ @@ -1328,12 +1334,12 @@ dispatch: CLEAR_CARRY_FLAG(); break; default: + CritErrCode = SUCCESS; goto error_invalid; } break; case 0x5e: - CLEAR_CARRY_FLAG(); switch (lr.AL) { case 0x00: @@ -1355,7 +1361,6 @@ dispatch: break; case 0x5f: - CLEAR_CARRY_FLAG(); if (lr.AL == 7 || lr.AL == 8) { struct cds FAR *cdsp; @@ -1400,7 +1405,6 @@ dispatch: break; case 0x60: /* TRUENAME */ - CLEAR_CARRY_FLAG(); if ((rc = DosTruename(MK_FP(lr.DS, lr.SI), adjust_far(FP_ES_DI))) < SUCCESS) goto error_exit; break; @@ -1490,12 +1494,10 @@ dispatch: break; } - CLEAR_CARRY_FLAG(); break; /* Code Page functions */ case 0x66: - CLEAR_CARRY_FLAG(); switch (lr.AL) { case 1: @@ -1514,7 +1516,6 @@ dispatch: /* Set Max file handle count */ case 0x67: - CLEAR_CARRY_FLAG(); if ((rc = SetJFTSize(lr.BX)) != SUCCESS) goto error_exit; break; @@ -1522,14 +1523,12 @@ dispatch: /* Flush file buffer -- COMMIT FILE. */ case 0x68: case 0x6a: - CLEAR_CARRY_FLAG(); if ((rc = DosCommit(lr.BX)) < 0) goto error_exit; break; /* Get/Set Serial Number */ case 0x69: - CLEAR_CARRY_FLAG(); rc = (lr.BL == 0 ? default_drive : lr.BL - 1); if (lr.AL == 0 || lr.AL == 1) { @@ -1560,8 +1559,7 @@ dispatch: case 0x6c: { long lrc; - CLEAR_CARRY_FLAG(); - + if (lr.AL != 0 || (lr.DL & 0x0f) > 0x2 || (lr.DL & 0xf0) > 0x10) goto error_invalid; @@ -1588,6 +1586,7 @@ dispatch: /* DOS 7.0+ FAT32 extended functions */ case 0x73: CLEAR_CARRY_FLAG(); + CritErrCode = SUCCESS; rc = int21_fat32(&lr); if (rc != SUCCESS) goto error_exit; @@ -1640,7 +1639,8 @@ error_invalid: rc = DE_INVLDFUNC; error_exit: lr.AX = -rc; - CritErrCode = lr.AX; /* Maybe set */ + if (CritErrCode == SUCCESS) + CritErrCode = lr.AX; /* Maybe set */ error_carry: SET_CARRY_FLAG(); exit_dispatch: diff --git a/kernel/newstuff.c b/kernel/newstuff.c index 73f26ff..6cd7d4a 100644 --- a/kernel/newstuff.c +++ b/kernel/newstuff.c @@ -449,7 +449,8 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode) *p = '\\'; /* force backslash! */ } p++; - DosGetCuDir((UBYTE)((result & 0x1f) + 1), p); + if (DosGetCuDir((UBYTE)((result & 0x1f) + 1), p) < 0) + return DE_PATHNOTFND; if (*src != '\\' && *src != '/') p += strlen(p); else /* skip the absolute path marker */ diff --git a/kernel/proto.h b/kernel/proto.h index 3999f1a..cefd177 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -162,7 +162,7 @@ BOOL dos_setfsize(COUNT fd, LONG size); COUNT dos_mkdir(BYTE * dir); BOOL last_link(f_node_ptr fnp); COUNT map_cluster(REG f_node_ptr fnp, COUNT mode); -UCOUNT rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode); +long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode); COUNT dos_read(COUNT fd, VOID FAR * buffer, UCOUNT count); COUNT dos_write(COUNT fd, const VOID FAR * buffer, UCOUNT count); LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin);