int exec(const char *cmd, char *cmdLine, const unsigned segOfEnv) { #ifdef FEATURE_XMS_SWAP # define buf dosCMDTAIL # define memcpy _fmemcpy #else unsigned char buf[128]; #endif struct fcb fcb1, fcb2; struct ExecBlock execBlock; int retval; assert(cmd); assert(cmdLine); assert(strlen(cmdLine) <= 125); invalidateNLSbuf(); /* generate Pascal string from the command line */ memcpy(&buf[1], cmdLine, buf[0] = strlen(cmdLine)); memcpy(&buf[1] + buf[0], "\xd", 2); /* fill FCBs */ if ((cmdLine = parsfnm(cmdLine, &fcb1, 1)) != 0) parsfnm(cmdLine, &fcb2, 1); saveSession(); #ifdef FEATURE_XMS_SWAP if(XMSisactive() && swapOnExec == TRUE) { /* Copy the prepared values into the buffers in CSWAP.ASM module */ _fmemcpy(dosFCB1, &fcb1, sizeof(fcb1)); _fmemcpy(dosFCB2, &fcb2, sizeof(fcb1)); assert(strlen(cmd) < 128); _fstrcpy(dosCMDNAME, cmd); dosParamDosExec.envSeg = segOfEnv; retval = XMSexec(); } else #endif { /* fill execute structure */ execBlock.segOfEnv = segOfEnv; execBlock.cmdLine = (char far *)buf; execBlock.fcb1 = (struct fcb far *)&fcb1; execBlock.fcb2 = (struct fcb far *)&fcb2; retval = lowLevelExec((char far*)cmd, (struct ExecBlock far*)&execBlock); } restoreSession(); return decode_exec_result(retval); }
/* Also: The contents of both buffers is monitored in order to check if they got overflowed during the MUX call. If so, the executation is aborted. */ int runExtension(char * const command, char * const line) { int clen, llen; union REGPACK r; char *p; int rc = 0; /* Default: is no extension */ assert(command); assert(line); assert(strlen(command) < BUFFER_SIZE_MUX_AE); assert(strlen(line) <= BUFFER_SIZE_MUX_AE); assert(FP_SEG(command) == FP_SEG(line)); /* Fill the length bytes */ command[-1] = (char)(clen = strlen(command)); line[-1] = (char)(llen = strlen(line)); command[-2] = line[-2] = (char)BUFFER_SIZE_MUX_AE; /* 4dos v4 compatible space padding */ memset(command + clen, ' ', BUFFER_SIZE_MUX_AE - clen); /* The command line is \xd terminated, for savety reasons an \0 is added too */ strcat(line + llen, "\xd"); line[BUFFER_SIZE_MUX_AE] = '\0'; /* Both strings have been prepared now; the MUX call is going to happen */ r.r_ax = 0xae00; /* Installable Commands check for extension */ r.r_dx = 0xffff; /* Magic value */ r.r_cx = -llen; /* length of command line tail (4dos v4) */ r.r_ds = r.r_es = FP_SEG(command); r.r_bx = FP_OFF(line) - 2; r.r_si = FP_OFF(command) - 1; r.r_di = 0; /* Magic value 4dos v4 */ intr(0x2F, &r); switch(r.r_ax & 0xFF) { case 0x00: /* No appropriate extension found */ break; default: /* Invalid response */ dprintf( ("[Invalid response from Installable Commands handler: 0x%02x]\n", r.r_ax & 0xFF) ); break; case 0xFF: /* Is an extension -> execute the Installable Command */ r.r_ax = 0xae01; intr(0x2F, &r); invalidateNLSbuf(); if(command[-1] == 0) /* The command had been processed */ rc = 1; /* Stop interpreting the command */ else rc = 2; /* buffers rewritten */ break; } /* Cleanup: Adjust buffers and check for overflow */ if((unsigned char)line[-2] != BUFFER_SIZE_MUX_AE #if BUFFER_SIZE_MUX_AE < 255 || (unsigned char)line[-1] > BUFFER_SIZE_MUX_AE #endif || line[BUFFER_SIZE_MUX_AE]) { /* Yiek! That looks very much like an overflow!! */ dprintf( ("[Memory corrupted during Installable Commands handler]\n") ); longjmp(jmp_beginning, E_CorruptMemory); } /* Check command and transform it back into C-style string */ p = command + command[-1]; while(--p >= command && isspace(*p)); p[1] = 0; /* Check the command line and transform it into a C-style string */ /* Must terminate as line[BUFFER_SIZE] == 0 */ line[(unsigned char)line[-1]] = line[(unsigned char)line[-2]] = '\0'; if(0 != (p = strchr(line, '\xd'))) *p = 0; return rc; }