/svarcom/trunk/cmd/exit.c |
---|
34,7 → 34,7 |
outputnl("EXIT\r\n"); |
outputnl("Quits the COMMAND.COM program (command interpreter)"); |
} else { |
exit(0); |
sayonara(p->rmod_seg); |
} |
return(-1); |
} |
/svarcom/trunk/cmd.c |
---|
37,6 → 37,7 |
#include "env.h" |
#include "helpers.h" |
#include "rmodinit.h" |
#include "sayonara.h" |
#define BUFFER_SIZE 2048 /* make sure this is not bigger than the static buffer in command.c */ |
/svarcom/trunk/command.c |
---|
77,6 → 77,7 |
#include "helpers.h" |
#include "redir.h" |
#include "rmodinit.h" |
#include "sayonara.h" |
#define FLAG_EXEC_AND_QUIT 1 |
476,5 → 477,6 |
} while ((cfg.flags & FLAG_EXEC_AND_QUIT) == 0); |
sayonara(rmod_seg); |
return(0); |
} |
/svarcom/trunk/makefile |
---|
21,8 → 21,8 |
all: command.com |
command.com: deflang.h rmod.h command.c cmd.c doserr.c env.c redir.c rmodinit.c helpers.c cmd\*.c |
wcl $(CFLAGS) command.c cmd.c doserr.c env.c redir.c rmodinit.c helpers.c |
command.com: deflang.h rmod.h command.c cmd.c doserr.c env.c redir.c rmodinit.c sayonara.c helpers.c cmd\*.c |
wcl $(CFLAGS) command.c cmd.c doserr.c env.c redir.c rmodinit.c sayonara.c helpers.c |
rmod.h: file2c.com rmod.com |
file2c /c rmod.com rmod.h rmod |
/svarcom/trunk/rmod.asm |
---|
45,8 → 45,11 |
; COMMAND.COM to chain multiple batch files (through CALL). 0 means "none". |
BATCHCHAIN dw 0 ; +A0h |
skipsig: ; +A2h |
; original parent (segment of) |
ORIGPARENT dd 0 ; +A2h |
skipsig: ; +A6h |
; set up CS=DS=SS and point SP to my private stack buffer |
mov ax, cs |
mov ds, ax |
/svarcom/trunk/rmod.h |
---|
9,18 → 9,18 |
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, |
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 0, 0, |
64, 58, 92, 67, 79, 77, 77, 65, 78, 68, 46, 67, 79, 77, 0, 1, |
0, 0,140,200,142,216,142,192,142,208,188,111, 1,180, 77,205, |
33, 48,228,163, 10, 0,186,144, 0,131, 14,142, 0, 0,116, 8, |
142, 6, 8, 0,139, 22,142, 0,161, 8, 0,163,253, 0,184,252, |
0,163,255, 0,140, 14, 1, 1,184, 0, 75, 6, 31, 14, 7,187, |
253, 0,205, 33,115,188,140,203,142,219, 4, 48,162, 15, 1,180, |
9,186, 11, 1,205, 33,180, 8,205, 33,235,166, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 82, 82, 32,120, |
44, 32, 70, 65, 73, 76, 69, 68, 32, 84, 79, 32, 76, 79, 65, 68, |
32, 67, 79, 77, 77, 65, 78, 68, 46, 67, 79, 77, 13, 10, 36, 48, |
49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, |
49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, |
49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, |
49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,120, |
120}; |
#define rmod_len 369 |
0, 0, 0, 0, 0, 0,140,200,142,216,142,192,142,208,188,115, |
1,180, 77,205, 33, 48,228,163, 10, 0,186,144, 0,131, 14,142, |
0, 0,116, 8,142, 6, 8, 0,139, 22,142, 0,161, 8, 0,163, |
1, 1,184, 0, 1,163, 3, 1,140, 14, 5, 1,184, 0, 75, 6, |
31, 14, 7,187, 1, 1,205, 33,115,188,140,203,142,219, 4, 48, |
162, 19, 1,180, 9,186, 15, 1,205, 33,180, 8,205, 33,235,166, |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, |
82, 82, 32,120, 44, 32, 70, 65, 73, 76, 69, 68, 32, 84, 79, 32, |
76, 79, 65, 68, 32, 67, 79, 77, 77, 65, 78, 68, 46, 67, 79, 77, |
13, 10, 36, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, |
68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, |
68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, |
68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, |
68, 69, 70,120,120}; |
#define rmod_len 373 |
/svarcom/trunk/rmodinit.c |
---|
118,7 → 118,7 |
*owner = rmodseg; |
_fmemcpy(mcb + 8, "SVARCOM", 8); |
/* mark env memory as "self owned" */ |
/* mark env memory as "owned by rmod" */ |
mcb = MK_FP(envseg - 1, 0); |
owner = (void far *)(mcb + 1); |
*owner = rmodseg; |
149,15 → 149,32 |
pop ax |
} |
/* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I terminate */ |
/* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I |
* terminate and save the original handler in rmod's memory */ |
_asm { |
push ax |
push bx |
push si |
push di |
push es |
/* save my original parent in rmod's memory */ |
mov es, [rmodseg] |
mov si, 0x0a |
mov di, RMOD_OFFSET_ORIGPARENT |
cld |
movsw /* mov ES:[DI], DS:[SI] and SI += 2 and DI += 2 */ |
movsw |
mov bx, 0x0a /* int22 handler is at 0x0A of the PSP */ |
mov ax, RMOD_OFFSET_ROUTINE |
mov [bx], ax /* int handler offset */ |
mov ax, rmodseg |
mov [bx+2], ax /* int handler segment */ |
pop es |
pop di |
pop si |
pop bx |
pop ax |
} |
166,29 → 183,18 |
} |
/* scan memory for rmod, returns its segment if found, 0xffff otherwise */ |
/* look up my parent: if it's rmod then return its segment, |
* otherwise return 0xffff */ |
unsigned short rmod_find(void) { |
unsigned short i; |
unsigned short far *ptrword; |
unsigned char far *ptrbyte; |
/* iterate over all paragraphs, looking for my signature */ |
for (i = 1; i != 65535; i++) { |
ptrword = MK_FP(i, 0); |
if (ptrword[0] != 0x1983) continue; |
if (ptrword[1] != 0x1985) continue; |
if (ptrword[2] != 0x2017) continue; |
if (ptrword[3] != 0x2019) continue; |
/* extra check: make sure the paragraph before is an MCB block and that it |
* belongs to itself. otherwise I could find the rmod code embedded inside |
* the command.com binary... */ |
ptrbyte = MK_FP(i - 1, 0); |
if ((*ptrbyte != 'M') && (*ptrbyte != 'Z')) continue; /* not an MCB */ |
ptrword = MK_FP(i - 1, 1); |
if (*ptrword != i) continue; /* not belonging to self */ |
return(i); |
} |
return(0xffff); |
unsigned short *parent = (void *)0x0C; /* parent's seg in PSP[Ch] ("prev. int22 handler") */ |
unsigned short far *ptr; |
const unsigned short sig[] = {0x1983, 0x1985, 0x2017, 0x2019}; |
unsigned char i; |
/* is it rmod? */ |
ptr = MK_FP(*parent, 0); |
for (i = 0; i < 4; i++) if (ptr[i] != sig[i]) return(0xffff); |
/* match successfull (rmod is my parent) */ |
return(*parent); |
} |
/svarcom/trunk/rmodinit.h |
---|
32,7 → 32,8 |
#define RMOD_OFFSET_BOOTDRIVE 0x90 |
#define RMOD_OFFSET_ECHOFLAG 0x9F |
#define RMOD_OFFSET_BATCHCHAIN 0xA0 |
#define RMOD_OFFSET_ROUTINE 0xA2 |
#define RMOD_OFFSET_ORIGPARENT 0xA2 |
#define RMOD_OFFSET_ROUTINE 0xA6 |
unsigned short rmod_install(unsigned short envsize); |
unsigned short rmod_find(void); |
/svarcom/trunk/sayonara.c |
---|
0,0 → 1,59 |
/* This file is part of the SvarCOM project and is published under the terms |
* of the MIT license. |
* |
* Copyright (C) 2021 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <i86.h> |
#include "rmodinit.h" |
#include "sayonara.h" |
/* rewires my parent pointer, uninstalls rmod let DOS terminate me, UNLESS |
* my parent is unknown */ |
void sayonara(unsigned short rmodseg) { |
unsigned long far *orgparent = MK_FP(rmodseg, RMOD_OFFSET_ORIGPARENT); |
unsigned long *myparent = (void *)0x0A; |
unsigned short far *rmodenv_ptr = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG); |
unsigned short rmodenv = *rmodenv_ptr; |
/* set my parent back to original value (if 0 = shell is permanent) */ |
if (*orgparent == 0) return; |
*myparent = *orgparent; |
_asm { |
/* free RMOD's code segment and env segment */ |
mov ah, 0x49 /* DOS 2+ -- Free Memory Block */ |
mov es, [rmodseg] |
int 0x21 |
/* free RMOD's env segment */ |
mov ah, 0x49 /* DOS 2+ -- Free Memory Block */ |
mov es, [rmodenv] |
int 0x21 |
/* gameover */ |
mov ax, 0x4C00 /* DOS 2+ -- Terminate with exit code 0 */ |
int 0x21 |
} |
} |
/svarcom/trunk/sayonara.h |
---|
0,0 → 1,32 |
/* This file is part of the SvarCOM project and is published under the terms |
* of the MIT license. |
* |
* Copyright (C) 2021 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#ifndef SAYONARA_H |
#define SAYONARA_H |
/* rewires my parent pointer, uninstalls rmod let DOS terminate me, UNLESS |
* my parent is unknown */ |
void sayonara(unsigned short rmodseg); |
#endif |
/svarcom/trunk/todo.txt |
---|
12,6 → 12,8 |
pipes redirections |
basic BAT support (without workflow controls, FOR loops etc) |
merge adjacent assembly blocks in rmod_install() |
/P switch for permanent copy |
AT SOME LATER TIME: |