home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1992
/
20
/
ntshell
/
ntshell.c
< prev
next >
Wrap
Text File
|
1992-11-02
|
6KB
|
172 lines
// NTSHELL.C Simple extendable command interpreter
// illustrating use of the WIN32 console API.
//
// Copyright 1992 Ray Duncan
// PC Magazine * Ziff Davis Publishing
#include "windows.h"
#include "stdio.h"
#include "process.h"
#include "stdlib.h"
#include "string.h"
#include "ntshell.h"
//
// This table associates "intrinsic" commands with the
// routines that carry them out.
//
struct decodeCmd commands[] = {
"CLS", doCls,
"DOS", doDos,
"EXIT", doExit, };
char comspec[MAXEXENAMESIZE]; // pathname of CMD.EXE
char msg1[] = "\nCan't run CMD.EXE.\n"; // misc. error messages
char msg2[] = "\nCMD.EXE couldn't execute command.\n";
char msg3[] = "\nNo COMSPEC in environment.\n";
HANDLE hConIn; // console input handle
HANDLE hConOut; // console output handle
VOID main(int argc, char *argv[])
{
char buffer[INPUTSIZE]; // keyboard input buffer
FreeConsole(); // discard inherited console
if(!AllocConsole()) // and create a new one
exit(TRUE); // allocation failed, exit
// open handles for console input and output
hConIn = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
hConOut = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
// bail out if we can't get console I/O handles
if((hConIn == (HANDLE) -1) || (hConOut == (HANDLE) -1))
exit(TRUE);
getComspec(comspec); // get pathname for CMD.EXE
while(TRUE) // main interpreter loop
{
getCommand(buffer); // get command from user
if(!intrinsic(buffer)) // if intrinsic, run worker
extrinsic(buffer); // else pass to CMD.EXE
}
}
//
// intrinsic() -- try and match user's command with intrinsic
// command table. If a match is found, run the associated routine
// and return TRUE, else return FALSE.
//
UINT intrinsic(char *input)
{
int i; // scratch variable
char token[64]; // scratch buffer
// discard leading blanks from user's input
while(*input == '\x20') input++ ;
i = strcspn(input, " ;/,-"); // search for delimiter
memset(token, 0, sizeof(token)); // zero out token buffer
strncpy(token, input, i); // copy first input token
strupr(token); // fold token to upper case
for(i=0; i < dim(commands); i++) // search command table
{
if(!strcmp(commands[i].name, token))
{
(*commands[i].fxn)(input); // if match, run routine
return(TRUE); // and return true
}
}
return(FALSE); // no match, return false
}
//
// extrinsic() -- process an unrecognized command by passing
// it to a child instance of CMD.EXE.
//
VOID extrinsic(char *input)
{
if(system(input)) // run child CMD.EXE
putMsg(msg2); // error message if failed
}
//
// getCommand() - issue prompt, get user's command from console,
// and make it ASCIIZ.
//
VOID getCommand(char *buffer)
{
DWORD count;
putMsg("\nntshell: "); // display prompt
ReadFile(hConIn, buffer, INPUTSIZE, &count, NULL);
buffer[count-2] = 0; // clip off CR-LF
strupr(buffer); // fold to upper case
}
//
// getComspec() -- get the full pathname for CMD.EXE
// from the "COMSPEC=" variable in the environment.
//
VOID getComspec(char *buffer)
{
strcpy(buffer, getenv("COMSPEC")); // get COMSPEC variable
// from environment
if(!buffer[0])
{ // if no such variable,
putMsg(msg3); // display error message
exit(1); // and exit
}
}
//
// putMsg() -- display a string on the console.
//
VOID putMsg(char *string)
{
DWORD count;
WriteFile(hConOut, string, strlen(string), &count, NULL);
}
//
// These are the subroutines for NTSHELL's intrinsic commands.
//
VOID doCls(char *input) // CLS command =
{ // erase the window
DWORD count;
COORD coord;
CONSOLE_SCREEN_BUFFER_INFO si;
GetConsoleScreenBufferInfo(hConOut, &si); // get screen dimensions
coord.X = 0; // buffer coordinates for
coord.Y = 0; // start of blanking = (0,0)
// fill screen with blanks, set cursor at upper left corner
FillConsoleOutputCharacter(hConOut, ' ', si.dwSize.X * si.dwSize.Y,
coord, &count);
SetConsoleCursorPosition(hConOut, coord);
}
VOID doDos(char *input) // DOS command = start
{ // child copy of CMD.EXE
if(spawnlp(P_WAIT, comspec, comspec, NULL))
putMsg(msg1); // error message if failed
}
VOID doExit(char *input) // EXIT command =
{ // terminate NTSHELL
exit(FALSE); // with success status
}