From d99cfc38c180000416bab4af299da1f13222d3fc Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Tue, 15 May 2007 17:50:22 +0000 Subject: [PATCH] Add Tom Ehlert's freeing of near f_node's work-around for problems with INT24 handling. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1317 6ac86273-5f31-0410-b378-82cca8765d1b --- kernel/inthndlr.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 82092a6..7d3ca2c 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -425,7 +425,29 @@ dispatch: } /* Clear carry by default for these functions */ - + /* We force clear the near fnodes, + On a normal int21h entry these are unused, so should already + be clear, thus this code is effectively redundant. + However when re-entering int21h, such as a device driver + (e.g. shsufdrv), the fnodes may contain the values of the + in progress call; as long as the driver/tsr causing the + reentrancey saves and restores the SDA across the call then + any changes we do (ie clearing these) should go unnoticed + and if the cause of the reentrancy does not save/restore the + SDA then the caller should expected the unexpected. + Failure to do this will at a minimal result in the extra + output indicating fnodes not 0 (and possibly clearing at end + of call) when the re-entered int21h call completes, but could + result in the re-entered call to fail with no free near fnodes + if both are already in use by the original int21h call (?bug 1879?). + See also PATCH TE 5 jul 04 explanation at end + */ + if (/*ErrorMode && */lr.AH > 0x0c && lr.AH != 0x30 && lr.AH != 0x59) + { + /*if (ErrorMode)*/ ErrorMode = 0; + fnode[0].f_count = 0; /* don't panic - THEY ARE unused !! */ + fnode[1].f_count = 0; + } /* Check for Ctrl-Break */ if (break_ena || (lr.AH >= 1 && lr.AH <= 5) || (lr.AH >= 8 && lr.AH <= 0x0b)) check_handle_break(&syscon); @@ -1545,6 +1567,31 @@ exit_dispatch: r->ES = lr.ES; real_exit:; + /* PATCH !! TE 5 JUL 04 + what happened: + Application does FindFirst("I:\*.*"); + this fails, and causes Int24 + this sets ErrorMode, and calls Int24 + Application decides NOT to return to DOS, + but instead pop the stack and return to itself + (this is legal; see RBIL/INT 24 description + + a) now the alloc()'ed fnode[0] never gets free()'ed + b) errormode NEVER gets set back to 0 unyil exit() + + I have NO idea how real DOS handles this; + the appended patch cures the worst symptoms + */ + if (fnode[0].f_count != 0 || + fnode[1].f_count != 0 ) + { + if (ErrorMode == 0) + put_string("near_fnodes not 0"); /* panic ?? */ + fnode[0].f_count = 0; /* don't panic - THEY ARE unused !! */ + fnode[1].f_count = 0; + } + /* PATCH !! END TE 5 JUL 04 */ + #ifdef DEBUG if (bDumpRegs) {