/svarcom/trunk/command.c |
---|
803,14 → 803,6 |
/* make COMPSEC point to myself */ |
set_comspec_to_self(*rmod_envseg); |
/* { |
unsigned short envsiz; |
unsigned short far *sizptr = MK_FP(*rmod_envseg - 1, 3); |
envsiz = *sizptr; |
envsiz *= 16; |
printf("rmod_inpbuff at %04X:%04X, env_seg at %04X:0000 (env_size = %u bytes)\r\n", rmod->rmodseg, RMOD_OFFSET_INPBUFF, *rmod_envseg, envsiz); |
}*/ |
/* on /P check for the presence of AUTOEXEC.BAT and execute it if found, |
* but skip this check if /D was also passed */ |
if ((cfg.flags & (FLAG_PERMANENT | FLAG_SKIP_AUTOEXEC)) == FLAG_PERMANENT) { |
877,14 → 869,26 |
/* skip the @ prefix if present, it is no longer useful */ |
if (cmdline[0] == '@') cmdline++; |
} else { |
unsigned char far *rmod_inputbuf = MK_FP(rmod->rmodseg, RMOD_OFFSET_INPUTBUF); |
unsigned short far *rmod_stacksig = MK_FP(rmod->rmodseg, RMOD_OFFSET_STACKSIG); |
/* invalidate input history if it appears to be damaged (could occur |
* because of a stack overflow, for example if some stack-hungry TSR is |
* being used) */ |
if (*rmod_stacksig != 0xCAFE) { |
*rmod_stacksig = 0xCAFE; |
rmod_inputbuf[0] = 128; /* max allowed input length */ |
rmod_inputbuf[1] = 0; |
rmod_inputbuf[2] = '\r'; |
/* printf("STACK OVERFLOW DETECTED: HISTORY FLUSHED\r\n"); */ |
} |
/* interactive mode: display prompt (if echo enabled) and wait for user |
* command line */ |
if (rmod->flags & FLAG_ECHOFLAG) build_and_display_prompt(BUFFER, *rmod_envseg); |
/* collect user input */ |
cmdline_getinput(FP_SEG(rmod->inputbuf), FP_OFF(rmod->inputbuf)); |
cmdline_getinput(rmod->rmodseg, RMOD_OFFSET_INPUTBUF); |
/* copy it to local cmdline */ |
if (rmod->inputbuf[1] != 0) _fmemcpy(cmdline, rmod->inputbuf + 2, rmod->inputbuf[1]); |
cmdline[(unsigned)(rmod->inputbuf[1])] = 0; /* zero-terminate local buff (oriignal is '\r'-terminated) */ |
if (rmod_inputbuf[1] != 0) _fmemcpy(cmdline, rmod_inputbuf + 2, rmod_inputbuf[1]); |
cmdline[rmod_inputbuf[1]] = 0; /* zero-terminate local buff (original is '\r'-terminated) */ |
} |
/* if nothing entered, loop again (but without appending an extra CR/LF) */ |
/svarcom/trunk/history.txt |
---|
10,8 → 10,8 |
- DOS errors are output to stdout, and also to stderr if stdout is redirected |
- fixed batch processing with /C (was executing only first command) |
- multi-lang support relies on SvarLANG.lib instead of its own routines |
- transient shell follows the int23h vector to locate RMOD (this is a |
workaround so SvarCOM works even when the LINK/LN TSR is loaded) |
- stack overflow detection degrades gracefully by invalidating command-line |
history (useful if a stack-hungry TSR overflows the RMOD stack) |
=== ver 2022.0 (01.02.2022) ================================================== |
/svarcom/trunk/rmod.asm |
---|
19,8 → 19,20 |
SIG1 dw 0x1983 ; +0 |
SIG2 dw 0x1985 ; +2 |
SIG3 dw 0x2017 ; +4 |
SIG4 dw 0x2019 ; +6 this acts also as a guardval to detect stack overflows |
SIG4 dw 0x2019 ; +6 acts also as a guardval to detect severe stack overflows |
; Buffer used to remember previous command, when SvarCOM calls the buffered |
; input service at INT 21h,AH=0x0A. |
; This buffer is right before the stack, so in case of a stack overflow event |
; (for example because of a "too ambitious" TSR) only this buffer is damaged, |
; and can be invalidated without much harm. |
INPUTBUF: times 130 db 0 |
; This stack sig is a guardian value that is checked by the transient part of |
; SvarCOM to detect possible stack overflows. If a stack overflow occurs, then |
; the INPUTBUFF area above is invalidated and stack signature reverted. |
STACKSIG dw 0xCAFE |
; DOS int 21h functions that I use require at least 40 bytes of stack under |
; DOS-C (FreeDOS) kernel, so here I reserve 64 bytes juste to be sure |
STACKBUF db "XXX SVARCOM RMOD BY MATEUSZ VISTE XXXXXXXXXXXXXXXXXXXXXXXXXXXX" |
/svarcom/trunk/rmodinit.c |
---|
147,11 → 147,16 |
pop ax |
} |
/* mark the input buffer as empty */ |
myptr = MK_FP(rmodseg, RMOD_OFFSET_INPUTBUF); |
myptr[0] = 128; |
myptr[1] = 0; |
myptr[2] = '\r'; |
/* prepare result (rmod props) */ |
res = MK_FP(rmodseg, 0x100 + rmodcore_len); |
_fmemset(res, 0, sizeof(*res)); /* zero out */ |
res->rmodseg = rmodseg; /* rmod segment */ |
res->inputbuf[0] = 128; /* input buffer for INT 0x21, AH=0Ah*/ |
res->origenvseg = origenvseg; /* original environment segment */ |
/* write env segment to rmod's PSP */ |
196,13 → 201,9 |
/* look up my parent: if it's rmod then return a ptr to its props struct, |
* otherwise return NULL |
* since RMOD sets itself as the CTRL+BREAK handler, I look at the int23 |
* field of the PSP to locate it. Previously I was looking at PSP[Ch] (ie. |
* "terminate address" but this was failing when using the LINK/LN TSR that |
* intercepts DOS EXEC calls and sets itself as the parent of all launched |
* applications */ |
* I look at PSP[Ch] to locate RMOD (ie. the "terminate address") */ |
struct rmod_props far *rmod_find(unsigned short rmodcore_len) { |
unsigned short *parent = (void *)0x10; /* look in PSP[10h] ("prev. int23 handler") */ |
unsigned short *parent = (void *)0x0C; |
unsigned short far *ptr; |
const unsigned short sig[] = {0x1983, 0x1985, 0x2017, 0x2019}; |
unsigned char *cmdtail = (void *)0x80; |
/svarcom/trunk/rmodinit.h |
---|
41,7 → 41,6 |
}; |
struct rmod_props { |
char inputbuf[130]; /* input buffer for INT 21, AH=0x0A */ |
unsigned short rmodseg; /* segment where rmod is loaded */ |
unsigned long origparent; /* original parent (far ptr) of the shell */ |
unsigned short origenvseg; /* original environment segment */ |
52,17 → 51,19 |
}; |
#define RMOD_OFFSET_ENVSEG 0x2C /* stored in rmod's PSP */ |
#define RMOD_OFFSET_COMSPECPTR (0x100 + 0x4A) |
#define RMOD_OFFSET_BOOTDRIVE (0x100 + 0x4C) |
#define RMOD_OFFSET_LEXITCODE (0x100 + 0x5B) |
#define RMOD_OFFSET_EXECPARAM (0x100 + 0x5C) |
#define RMOD_OFFSET_EXECPROG (0x100 + 0x6A) |
#define RMOD_OFFSET_STDINFILE (0x100 + 0xEA) |
#define RMOD_OFFSET_STDOUTFILE (0x100 + 0x16A) |
#define RMOD_OFFSET_STDOUTAPP (0x100 + 0x1EA) |
#define RMOD_OFFSET_STDIN_DEL (0x100 + 0x1EC) |
#define RMOD_OFFSET_BRKHANDLER (0x100 + 0x1ED) |
#define RMOD_OFFSET_ROUTINE (0x100 + 0x1EF) |
#define RMOD_OFFSET_INPUTBUF (0x100 + 0x08) |
#define RMOD_OFFSET_STACKSIG (0x100 + 0x8A) /* 0xCAFE */ |
#define RMOD_OFFSET_COMSPECPTR (0x100 + 0xCE) |
#define RMOD_OFFSET_BOOTDRIVE (0x100 + 0xD0) |
#define RMOD_OFFSET_LEXITCODE (0x100 + 0xDF) |
#define RMOD_OFFSET_EXECPARAM (0x100 + 0xE0) |
#define RMOD_OFFSET_EXECPROG (0x100 + 0xEE) |
#define RMOD_OFFSET_STDINFILE (0x100 + 0x16A) |
#define RMOD_OFFSET_STDOUTFILE (0x100 + 0x1EE) |
#define RMOD_OFFSET_STDOUTAPP (0x100 + 0x26E) |
#define RMOD_OFFSET_STDIN_DEL (0x100 + 0x270) |
#define RMOD_OFFSET_BRKHANDLER (0x100 + 0x271) |
#define RMOD_OFFSET_ROUTINE (0x100 + 0x273) |
struct rmod_props far *rmod_install(unsigned short envsize, unsigned char *rmodcore, unsigned short rmodcore_len); |
struct rmod_props far *rmod_find(unsigned short rmodcore_len); |