home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Plus SuperCD 45
/
SuperCD45.iso
/
talleres
/
vayuda
/
helpscrn
/
script
/
SCRIPT.C
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-20
|
60KB
|
1,591 lines
/****************************************************************************
This offer void where prohibited, batteries not included, this product is sold as is
without warranty either express or implied, no claims of merchantabilty have been made
with regard to this product, end user assumes all liability with regard to the use of
this product and no claims of injury, either fiduciary or personal, may be issued against
the manufacturer. Use at your own risk, caveat emptor. The programmer has been certified
virus free.
This software is hereby released to the public domain; you break it, you fix it. Bug fixes,
patches and feature recommendations gladly accepted (responses tempered to the attitude
of the corespondent). Send intelligent discourse to grumble@compuserve.com, drivel to /dev/null.
PROGRAM: script.c
PURPOSE: Windows program control
FUNCTIONS:
WinMain() - calls initialization function, processes message loop
InitApplication() - initializes window data and registers window
InitInstance() - saves instance handle and creates main window
MainWndProc() - processes messages
HISTORY:
1.0 Initial release 12/17/97
1.1 Added command struct 01/08/98
1.2 Fixed small memory leak when 01/15/98
last line doesn't end with CR
Changed onexist to use FindFirstFile
1.3 Added wildcard matches to the 01/19/98
while, send, and wait functions
Fixed control character translation
Added .script file extension
Added additional error checking
Fixed wait bug related to uninitialize
waitcount
Fixed string compare bug
Fixed file size > 1024 bug
2.0 Structural rewrite 01/29/98
Create malloc'd structures containing
functions and command strings. Create
malloc'd structure containing labels and
pointers.
Use SW_SHOWMINNOACTIVE to start
minimized windows so they don't
interfere with open windows
Save and restore top window
Save and restore caps lock mode
2.1 Added shift function to special chars 04/15/98
Added return code to msgbox
Added start directory to start command
Fixed kbd arrow direction screwup
Added escaped space (for leading blanks)
2.1.1 Fixed arg count for start and while 06/03/98
2.1.2 Added norm to start options 8/18/98
Added activate command
Added escape to list of characters
Changed return to VK_RETURN
Added space to list of characters
2.1.3 Added home,end,pageup, pagedown 9/9/98
Reduced timer to .1 sec increments
2.1.4 Fixed string compare routine to 10/8/98
allow a match if the second string
terminates in * wildcard.
2.1.5 Changed memory allocation to Windows 2/24/99
functions GlobalAlloc, GlobalLock
2.1.6 Added delete character 3/22/99
2.1.7 Added file create/delete and variables 12/7/99
2.1.8 Fixed while bug with waitcount 01/20/00
thanks to Maurice van der Pot <griffn26@yahoo.com>
****************************************************************************/
#include <stdio.h>
#include <dos.h>
#include <ctype.h>
#include <string.h>
#include <windows.h>
#include <windowsx.h>
#include <time.h>
#include <conio.h>
#include <errno.h>
#include "script.h"
HANDLE hInst;
MSG msg;
HWND hWnd;
UCHAR szAppName[20], szClassName[20];
UCHAR cmdbuf[_MAX_PATH + _MAX_FNAME + _MAX_EXT];
UCHAR errbuf[160];
struct cl {
char command[10];
int nargs;
int function;
int attr;
} cl[] = {
{ "send", NARG2, IDM_SEND, TRUE },
{ "goto", NARG1, IDM_GOTO, FALSE },
{ "wait", NARG1 | NARG2, IDM_WAIT, FALSE },
{ "while", NARG1 | NARG2, IDM_WHILE, FALSE },
{ "start", NARG1 | NARG2 | NARG3, IDM_START, FALSE },
{ "msgbox", NARG1 | NARG2, IDM_MSGBOX, FALSE },
{ "delay", NARG1, IDM_DELAY, FALSE },
{ "onerror", NARG1, IDM_ONERR, FALSE },
{ "onexist", NARG2, IDM_EXIST, FALSE },
{ "onmsgrtn", NARG2, IDM_ONMSG, FALSE },
{ "activate", NARG1, IDM_ACTIVATE, FALSE },
{ "set", NARG2, IDM_SETVAR, FALSE },
{ "dec", NARG1, IDM_DECVAR, FALSE },
{ "onzero", NARG2, IDM_VARZERO, FALSE },
{ "create", NARG1, IDM_CREATE, FALSE },
{ "delete", NARG1, IDM_DELETE, FALSE },
{ "", 0, 0 }
};
CMD *cmdstart;
LABEL *labelstart;
VAR *varstart;
#define BLOCKSIZE 1024
/*
* This routine does a string compare of s1 to s
* it differs from the standard library lookup
* in that it supports wildcard characters (?, *)
* and it returns a boolean result, not a magnitude.
* ? is a single character wildcard and will match
* any character in the same position.
* * is a 0-n character wildcard
*/
BOOL gstrscn(unsigned char *s, unsigned char *s1, WORD *s2, int first)
{
while (*s && (*s1 != 0xff || *s1))
{
if (*s1 == MUWC && *s2 == KSPECIAL)
{
s1++;
s2++;
if (*s1)
return gstrscn(s, s1, s2, TRUE);
else
return TRUE;
}
else
if (first)
{
if (*s == *s1 || (*s1 == SIWC && *s2 == KSPECIAL))
{
first = FALSE;
s1++;
s2++;
}
}
else
if (*s != *s1 && (*s1 != SIWC && *s2 != KSPECIAL))
return FALSE;
else
{
s1++;
s2++;
}
s++;
}
if (!*s && *s1 == MUWC && *s2 == KSPECIAL)
return TRUE;
if (*s || (*s1 != 0xff && *s1))
return FALSE;
return TRUE;
}
/*
* Routine to convert hex character to int
*/
int HexToInt(char i)
{
i -= '0';
if (i > 0x30)
i -= 0x27;
else
if (i > 0x10)
i -= 0x7;
return (int)(i);
}
/****************************************************************************
FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
PURPOSE: calls initialization function, processes message loop
****************************************************************************/
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdline, int nCmdShow)
{
WIN32_FIND_DATA wf;
HANDLE fh;
lstrcpy(szAppName, "Script");
lstrcpy(szClassName, "ScriptClass");
strcpy(cmdbuf, cmdline);
if (strstr(cmdbuf, ".") == NULL) // no extension supplied, try it as .scr first
strcat(cmdbuf, ".scr");
if ((fh = FindFirstFile(cmdbuf, &wf)) == INVALID_HANDLE_VALUE)
{
strcat(cmdbuf, "ipt"); // not found, try it as .script
if ((fh = FindFirstFile(cmdbuf, &wf)) == INVALID_HANDLE_VALUE)
strcpy(cmdbuf, cmdline); // not found, no extension
}
if (fh != INVALID_HANDLE_VALUE)
FindClose(fh);
if (!InitApplication(hInstance))
return (FALSE);
varstart = NULL;
if ((fh = OpenScriptFile(cmdbuf)) == NULL)
return (FALSE);
if (!FileProc(fh))
{
FreeCMD(cmdstart);
FreeLabel(labelstart);
FreeVar(varstart);
CloseHandle(fh);
return (FALSE);
}
CloseHandle(fh);
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
SetTimer(hWnd, 1, 100, NULL); // set timer to .1 seconds
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
/****************************************************************************
FUNCTION: InitApplication(HANDLE)
PURPOSE: Initializes window data and registers window class
****************************************************************************/
BOOL InitApplication(hInstance)
HANDLE hInstance;
{
WNDCLASS wc;
HBRUSH hbr;
hbr = CreateSolidBrush(RGB(192, 192, 192));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
wc.hbrBackground = hbr;
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
return (RegisterClass(&wc));
}
/****************************************************************************
FUNCTION: InitInstance(HANDLE, int)
PURPOSE: Saves instance handle and creates main window
****************************************************************************/
BOOL InitInstance(HANDLE hInstance, int nCmdShow)
{
HDC hDC;
hInst = hInstance;
hWnd = CreateWindow(
szClassName,
szAppName,
WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZE,
0,
0,
0,
0,
HWND_DESKTOP,
0,
hInstance,
NULL
);
if (!hWnd)
return (FALSE);
hDC = GetDC(hWnd);
if (!hDC)
return (FALSE);
ReleaseDC(hWnd,hDC);
return (TRUE);
}
/****************************************************************************
FUNCTION: OpenScriptFile(char *filename)
PURPOSE: Reads file into buffer
****************************************************************************/
HANDLE OpenScriptFile(char *filename)
{
OPENFILENAME ofn;
HANDLE fh;
if (!strlen(filename))
{
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWnd;
ofn.hInstance = NULL;
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.lpstrFilter = "Script files\0*.scr\0*.script\0";
ofn.nFilterIndex = 1;
ofn.lpstrFile = (LPSTR)filename;
ofn.nMaxFile = _MAX_PATH + _MAX_FNAME + _MAX_EXT;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrTitle = NULL;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lCustData = 0L;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
ofn.lpstrDefExt = "scr";
if (!GetOpenFileName((OPENFILENAME FAR *)&ofn))
return NULL;
}
if ((fh = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
{
sprintf(errbuf, "Unable to open %s for input", cmdbuf);
MessageBox(hWnd, errbuf, "File error", MB_ICONSTOP | MB_SYSTEMMODAL);
return NULL;
}
return fh;
}
/****************************************************************************
FUNCTION: ReadBlock(HANDLE FileHandle, unsigned char *buf)
PURPOSE: Reads file into buffer
****************************************************************************/
int ReadBlock(HANDLE fh, unsigned char *buf, DWORD *rc)
{
if (!ReadFile(fh, buf, BLOCKSIZE, rc, NULL))
{
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
errbuf, sizeof(errbuf), NULL);
MessageBox(hWnd, errbuf, "Read Error", MB_OK | MB_SYSTEMMODAL);
return (FALSE);
}
if (!*rc)
CloseHandle(fh);
return TRUE;
}
/****************************************************************************
FUNCTION: FileProc(HANDLE fh)
PURPOSE: Reads file into buffer and processes contents
****************************************************************************/
BOOL FileProc(HANDLE fh)
{
UCHAR seqchar;
int comma = 0;
int brseq;
DWORD rc;
unsigned char *p;
int badesc;
int badfunc;
UCHAR buf[BLOCKSIZE];
UCHAR cbuf[256];
UCHAR *cmd;
WORD attrbuf[256];
UCHAR *cmdptr;
WORD *atrptr;
int atrflag;
int func;
int i;
UCHAR *s;
LABEL *curlabel, *tmplabel;
CMD *curcmd, *tmpcmd;
int firstlabel = TRUE;
int firstcmd = TRUE;
int newlabel = FALSE;
int curmessage;
HGLOBAL mAlloc;
cmdptr = cbuf;
atrflag = FALSE;
atrptr = attrbuf;
*atrptr = 0;
brseq = 0;
badesc = FALSE;
badfunc = FALSE;
curcmd = cmdstart;
curlabel = labelstart;
if (!ReadBlock(fh, buf, &rc))
return (FALSE);
p = buf;
for (;;)
{
if ((p - buf) == sizeof(buf))
{
if (!ReadBlock(fh, buf, &rc))
return (FALSE);
p = buf;
atrflag = FALSE;
}
if ((DWORD)(p - buf) >= rc) // end of file (I think)
return (TRUE);
while (*p != 0xd && *p != 0xa && ((DWORD)(p - buf) < rc))
{
if (!brseq && (*p == '\\' || *p == '$' || *p == '#')) // handle multiple sequences
{
seqchar = *p;
p++;
if (seqchar == '$' || seqchar == '#')
brseq = 2;
else
brseq = 1;
}
else
{
if (brseq)
{
brseq--;
switch (seqchar) {
case '\\':
switch (*p) {
case 'n':
*(cmdptr++) = RETURN;
// *(cmdptr++) = 0x0d;
// atrptr++;
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
// atrflag = TRUE;
break;
case ',':
*(cmdptr++) = ',';
atrptr++;
*atrptr = 0;
break;
case 't':
*(cmdptr++) = (UCHAR)KTAB; // escaped tabs are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
break;
case '>':
*(cmdptr++) = (UCHAR)RTAR; // escaped arrows are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
atrflag = TRUE;
break;
case '<':
*(cmdptr++) = (UCHAR)LFAR; // escaped arrows are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
atrflag = TRUE;
break;
case '^':
*(cmdptr++) = (UCHAR)UPAR; // escaped arrows are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
atrflag = TRUE;
break;
case 'v':
*(cmdptr++) = (UCHAR)DNAR; // escaped arrows are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
atrflag = TRUE;
break;
case 'u':
*(cmdptr++) = (UCHAR)PGUP; // escaped arrows are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
atrflag = TRUE;
break;
case 'd':
*(cmdptr++) = (UCHAR)PGDN; // escaped arrows are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
atrflag = TRUE;
break;
case 'h':
*(cmdptr++) = (UCHAR)HOME; // escaped arrows are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
atrflag = TRUE;
break;
case 'o':
*(cmdptr++) = (UCHAR)LEND; // escaped arrows are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
atrflag = TRUE;
break;
case 'e':
*(cmdptr++) = (UCHAR)ESCAPE; // escaped E are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
break;
case 's':
*(cmdptr++) = (UCHAR)SPACE; // escaped S are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
break;
case '\\':
*(cmdptr++) = '\\'; // escaped \ are special
atrptr++;
*atrptr = 0;
break;
case '?':
*(cmdptr++) = '?'; // escaped ? are special
atrptr++;
*atrptr = 0;
break;
case '*':
*(cmdptr++) = '*'; // escaped * are special
atrptr++;
*atrptr = 0;
break;
case '$':
*(cmdptr++) = '$'; // escaped $ are special
atrptr++;
*atrptr = 0;
break;
case '#':
*(cmdptr++) = '#'; // escaped # are special
atrptr++;
*atrptr = 0;
break;
case '!':
*(cmdptr++) = '!'; // escaped ! are special
atrptr++;
*atrptr = 0;
break;
case ' ':
*(cmdptr++) = ' '; // escaped spaces are special
atrptr++;
*atrptr = 0;
break;
case 'x':
*(cmdptr++) = KDELETE; // escaped x are special
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
break;
default:
*(cmdptr++) = '\\'; // bad sequence
*(cmdptr++) = *p;
atrptr++;
*atrptr = 0;
badesc = TRUE;
}
break;
case '$': // function keys
if (*p >= '0' && *p <= '9')
{
if (brseq)
func = (*p - '0') * 10;
else
{
func += (*p - '0');
*(cmdptr++) = F0 - func;
*(atrptr++) |= KSPECIAL;
*atrptr = 0;
atrflag = TRUE;
}
}
else
badfunc = TRUE;
break;
case '#': // hex character sequences
if ((*p >= '0' && *p <= '9') || (*p >= 'A' && *p <= 'F') || (*p >= 'a' && *p <= 'f'))
{
if (brseq)
func = HexToInt(*p) << 4;
else
{
func += HexToInt(*p);
*(cmdptr++) = func;
atrptr++;
*atrptr = 0;
atrflag = TRUE;
}
}
else
badfunc = TRUE;
break;
}
}
else
switch (*p) {
case ',': // convert nonescaped commas to separator characters
*(cmdptr++) = (UCHAR)SEP;
comma++; // inc comma count
atrptr++;
*atrptr = 0;
break;
case '?':
*(cmdptr++) = (UCHAR)SIWC;
*atrptr |= KSPECIAL;
atrptr++;
*atrptr = 0;
break;
case '*':
*(cmdptr++) = (UCHAR)MUWC;
*atrptr |= KSPECIAL;
atrptr++;
*atrptr = 0;
break;
case '%':
*atrptr |= KALT;
atrflag = TRUE;
break;
case '^':
*atrptr |= KCONTROL;
atrflag = TRUE;
break;
case '!':
*atrptr |= KSHIFT;
atrflag = TRUE;
break;
default:
*(cmdptr++) = *p;
atrptr++;
*atrptr = 0;
}
p++;
}
if ((p - buf) == sizeof(buf))
{
if (!ReadBlock(fh, buf, &rc))
return (FALSE);
p = buf;
}
}
*cmdptr = 0;
p++;
if (badfunc)
{
for (i = 0; cbuf[i]; i++)
if (cbuf[i] == SEP)
cbuf[i] = ',';
sprintf(errbuf, "Invalid function key\n%s", cbuf);
MessageBox(hWnd, errbuf, "Command Error", MB_ICONSTOP | MB_SYSTEMMODAL);
return (FALSE);
}
if (badesc) // exit expand case
{
for (i = 0; cbuf[i]; i++)
if (cbuf[i] == SEP)
cbuf[i] = ',';
sprintf(errbuf, "Invalid escape sequence\n%s", cbuf);
MessageBox(hWnd, errbuf, "Command Error", MB_ICONSTOP | MB_SYSTEMMODAL);
return (FALSE);
}
// expand the string, figure out if a token or comment or blank
// save the string and start processing (curmessage)
// anything not recognized is assumed to be a syntax error
if (strlen(cbuf))
{
s = cbuf;
while (*s == 0x20 || *s == 0x9)
s++; // skip whitespace
if (*s != ';') // line is a comment
{
if (*s == ':') // handle label
{
s++;
if ((mAlloc = GlobalAlloc(GMEM_MOVEABLE, sizeof(struct label))) == NULL)
{
sprintf(errbuf, "Insufficient memory for allocation\n%s,%s", s, cmd);
MessageBox(hWnd, errbuf, "Memory Error", MB_ICONSTOP | MB_SYSTEMMODAL);
return (FALSE);
}
tmplabel = (LABEL *)GlobalLock(mAlloc);
GlobalUnlock(mAlloc);
if (firstlabel)
{
firstlabel = FALSE;
labelstart = tmplabel;
}
else
curlabel->next = tmplabel;
curlabel = tmplabel;
if ((mAlloc = GlobalAlloc(GMEM_MOVEABLE, strlen(s) + 1)) == NULL)
{
sprintf(errbuf, "Insufficient memory for allocation\n%s,%s", s, cmd);
MessageBox(hWnd, errbuf, "Memory Error", MB_ICONSTOP | MB_SYSTEMMODAL);
return (FALSE);
}
curlabel->labeltext = (char *)GlobalLock(mAlloc);
strcpy(curlabel->labeltext, s);
curlabel->next = NULL;
curlabel->line = NULL;
newlabel = TRUE;
GlobalUnlock(mAlloc);
}
else
if ((cmd = strstr(cbuf, "\377")) != NULL)
{
*(cmd++) = 0;
while (*cmd == 0x20 || *cmd == 0x9) // strip out whitespace
cmd++;
i = 0;
curmessage = 0;
while (strlen(cl[i].command))
{
if (!stricmp(s, cl[i].command))
{
if (atrflag && !cl[i].attr)
curmessage = BADSPEC;
else
if ((1 << comma) & cl[i].nargs)
{
if ((mAlloc = GlobalAlloc(GMEM_MOVEABLE, sizeof(struct cmd))) == NULL)
{
sprintf(errbuf, "Insufficient memory for allocation\n%s,%s", s, cmd);
MessageBox(hWnd, errbuf, "Memory Error", MB_ICONSTOP | MB_SYSTEMMODAL);
return (FALSE);
}
tmpcmd = (CMD *)GlobalLock(mAlloc);
GlobalUnlock(mAlloc);
if (firstcmd)
{
firstcmd = FALSE;
cmdstart = tmpcmd;
}
else
curcmd->next = tmpcmd;
curcmd = tmpcmd;
curcmd->function = cl[i].function;
if ((mAlloc = GlobalAlloc(GMEM_MOVEABLE, strlen(cmd) + 1)) == NULL)
{
sprintf(errbuf, "Insufficient memory for allocation\n%s,%s", s, cmd);
MessageBox(hWnd, errbuf, "Memory Error", MB_ICONSTOP | MB_SYSTEMMODAL);
return (FALSE);
}
curcmd->cmdstring = (char *)GlobalLock(mAlloc);
strcpy(curcmd->cmdstring, cmd);
GlobalUnlock(mAlloc);
if ((mAlloc = GlobalAlloc(GMEM_MOVEABLE, strlen(cmd) * sizeof(WORD))) == NULL)
{
sprintf(errbuf, "Insufficient memory for allocation\n%s,%s", s, cmd);
MessageBox(hWnd, errbuf, "Memory Error", MB_ICONSTOP | MB_SYSTEMMODAL);
return (FALSE);
}
curcmd->attrbuf = (WORD *)GlobalLock(mAlloc);
memcpy(curcmd->attrbuf, &attrbuf[cmd - cbuf], strlen(cmd) * sizeof(WORD));
curcmd->next = NULL;
if (newlabel)
{
curlabel->line = curcmd;
newlabel = FALSE;
}
curmessage = GOODCMD;
}
else
curmessage = PARMS;
GlobalUnlock(mAlloc);
break;
}
i++;
}
if (!curmessage)
curmessage = SYNTAX;
}
else
{
curmessage = SYNTAX;
cmd = "";
}
if (curmessage < 0)
{
if (curmessage == BADSPEC)
sprintf(errbuf, "Control or Alt sequence not allowed with this command\n%s,%s", s, cmd);
if (curmessage == PARMS)
{
for (i = 0; cmd[i]; i++)
if (cmd[i] == SEP)
cmd[i] = ',';
sprintf(errbuf, "Invalid number of command parameters\n%s,%s", s, cmd);
}
if (curmessage == SYNTAX)
sprintf(errbuf, "Syntax error\n%s,%s", s, cmd);
MessageBox(hWnd, errbuf, "Command Error", MB_ICONSTOP | MB_SYSTEMMODAL);
return (FALSE);
}
}
}
cmdptr = cbuf;
atrflag = FALSE;
atrptr = attrbuf;
*atrptr = 0;
comma = 0;
}
}
/****************************************************************************
FUNCTION: FindLabel(char *)
PURPOSE: Reads file into buffer and processes contents
****************************************************************************/
CMD *FindLabel(char *label)
{
LABEL *curlabel;
curlabel = labelstart;
while (curlabel != NULL)
if (!strcmp(label, curlabel->labeltext))
return (curlabel->line);
else
curlabel = curlabel->next;
return ((CMD *)-1);
}
/****************************************************************************
FUNCTION: FreeLabel(label *)
PURPOSE: Free up memory used by label structures
****************************************************************************/
void FreeLabel(LABEL *label)
{
HGLOBAL mAlloc;
if (label == NULL)
return;
FreeLabel(label->next);
mAlloc = GlobalHandle(label->labeltext);
GlobalFree(mAlloc);
// free(label->labeltext);
mAlloc = GlobalHandle(label);
GlobalFree(mAlloc);
// free(label);
}
/****************************************************************************
FUNCTION: FreeCMD(CMD *)
PURPOSE: Free up memory used by command structures
****************************************************************************/
void FreeCMD(CMD *command)
{
HGLOBAL mAlloc;
if (command == NULL)
return;
FreeCMD(command->next);
mAlloc = GlobalHandle(command->cmdstring);
GlobalFree(mAlloc);
// free(command->cmdstring);
mAlloc = GlobalHandle(command->attrbuf);
GlobalFree(mAlloc);
// free(command->attrbuf);
mAlloc = GlobalHandle(command);
GlobalFree(mAlloc);
// free(command);
}
/****************************************************************************
FUNCTION: FreeVar(VAR *)
PURPOSE: Free up memory used by variables
****************************************************************************/
void FreeVar(VAR *curvar)
{
if (!curvar)
return;
FreeVar(curvar->next);
free(curvar->varname);
free(curvar);
}
/****************************************************************************
FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM)
PURPOSE: Processes messages
MESSAGES:
WM_COMMAND - application menu (About dialog box)
WM_CREATE - create window and objects
WM_PAINT - update window, draw objects
WM_DESTROY - destroy window
COMMENTS:
Handles to the objects you will use are obtained when the WM_CREATE
message is received, and deleted when the WM_DESTROY message is
received. The actual drawing is done whenever a WM_PAINT message is
received.
****************************************************************************/
long FAR PASCAL MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
UCHAR module[128];
STARTUPINFO si;
PROCESS_INFORMATION pi;
int j, flags, ks;
UCHAR *s, *p;
WORD *s1;
HWND GlobalhWnd, tmphWnd;
HANDLE ftmp;
WIN32_FIND_DATA fdata;
UCHAR cmd[256];
time_t t;
FILE *fh;
VAR *curvar;
static delay = 0;
static int errlevel = 0;
static int mboxrtn = 0;
static int waitcount = 0;
static UCHAR labelqry[80];
static CMD *curcmd;
static CMD *nextcmd;
static int stop = FALSE;
switch (message) {
case WM_COMMAND:
switch (wParam) {
/* wait for a program to exit */
case IDM_WHILE:
errlevel = 0;
if ((s = strstr(curcmd->cmdstring, "\377")) != NULL) // find separator character
{
if (!waitcount)
{
s++;
while (*s == 0x20 || *s == 0x9)
s++;
sscanf(s, "%d", &waitcount);
}
}
else
waitcount = -1;
if ((GlobalhWnd = GetTopWindow(NULL)) != NULL)
{
do {
if (GetWindowText(GlobalhWnd, module, sizeof(module)))
if (gstrscn(module, curcmd->cmdstring, curcmd->attrbuf, FALSE))
{
if (waitcount)
{
waitcount--;
if (!waitcount)
{
errlevel = TRUE;
break;
}
nextcmd = curcmd; // branch back here
}
break;
}
} while ((GlobalhWnd = GetNextWindow(GlobalhWnd, GW_HWNDNEXT)) != NULL);
waitcount = 0; // window not found, clear waitcount
}
break;
/* wait for specified delay (in 1/1000's of a second ) */
case IDM_DELAY:
if (delay == 0)
{
sscanf(curcmd->cmdstring, "%d", &delay);
nextcmd = curcmd;
}
else
{
delay--;
if (delay != 0)
nextcmd = curcmd;
}
break;
/* activate a dormant window */
case IDM_ACTIVATE:
if ((GlobalhWnd = GetTopWindow(NULL)) != NULL)
do {
if (GetWindowText(GlobalhWnd, module, sizeof(module)))
if (gstrscn(module, curcmd->cmdstring, curcmd->attrbuf, FALSE))
SetForegroundWindow(GlobalhWnd);
} while ((GlobalhWnd = GetNextWindow(GlobalhWnd, GW_HWNDNEXT)) != NULL);
break;
/* send keys to window */
case IDM_SEND:
stop = TRUE;
if ((s = strstr(curcmd->cmdstring, "\377")) != NULL) // find separator character
{
s++;
s1 = &curcmd->attrbuf[s - curcmd->cmdstring];
while ((*s == 0x20 || *s == 0x9) && !*s1)
{
s++;
s1++;
}
if ((GlobalhWnd = GetTopWindow(NULL)) != NULL)
do {
if (GetWindowText(GlobalhWnd, module, sizeof(module)))
if (gstrscn(module, curcmd->cmdstring, curcmd->attrbuf, FALSE))
{
tmphWnd = GetForegroundWindow();
if ((ks = GetKeyState(VK_CAPITAL))) // toggle caps lock if on
{
keybd_event(VK_CAPITAL, 0, 0L, 0x10001L);
keybd_event(VK_CAPITAL, 0, KEYEVENTF_KEYUP, 0xc0000001L);
}
while (*s) // send keystrokes
{
SetForegroundWindow(GlobalhWnd);
if (!(*s1 & KSPECIAL))
j = VkKeyScan(*s) | *s1;
else
{
switch (*s) {
case RTAR: // right arrow
j = VK_RIGHT;
break;
case LFAR: // left arrow
j = VK_LEFT;
break;
case UPAR: // up arrow
j = VK_UP;
break;
case DNAR: // down arrow
j = VK_DOWN;
break;
case KTAB:
j = VkKeyScan(0x9);
break;
case F1:
j = VK_F1;
break;
case F2:
j = VK_F2;
break;
case F3:
j = VK_F3;
break;
case F4:
j = VK_F4;
break;
case F5:
j = VK_F5;
break;
case F6:
j = VK_F6;
break;
case F7:
j = VK_F7;
break;
case F8:
j = VK_F8;
break;
case F9:
j = VK_F9;
break;
case F10:
j = VK_F10;
break;
case F11:
j = VK_F11;
break;
case F12:
j = VK_F12;
break;
case ESCAPE:
j = VK_ESCAPE;
break;
case RETURN:
j = VK_RETURN;
break;
case SPACE:
j = VK_SPACE;
break;
case PGDN:
j = VK_NEXT;
break;
case PGUP:
j = VK_PRIOR;
break;
case HOME:
j = VK_HOME;
break;
case LEND:
j = VK_END;
break;
case KDELETE:
j = VK_DELETE;
break;
}
j |= *s1;
}
if (j & KALT)
keybd_event(VK_MENU, 0, 0L, 0x10001L);
if (j & KCONTROL)
keybd_event(VK_CONTROL, 0, 0L, 1L);
if (j & KSHIFT)
keybd_event(VK_SHIFT, 0, 0L, 1L);
keybd_event((char)(j & 0xff), 0, 0L, 1L);
keybd_event((char)(j & 0xff), 0, KEYEVENTF_KEYUP, 0xc0000001L);
if (j & KSHIFT)
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0xc0000001L);
if (j & KCONTROL)
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0xc0000001L);
if (j & KALT)
keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0xc0000001L);
s++;
s1++;
}
SetForegroundWindow(tmphWnd);
if (ks) // toggle caps lock if on
{
keybd_event(VK_CAPITAL, 0, 0L, 0x10001L);
keybd_event(VK_CAPITAL, 0, KEYEVENTF_KEYUP, 0xc0000001L);
}
break;
}
} while ((GlobalhWnd = GetNextWindow(GlobalhWnd, GW_HWNDNEXT)) != NULL);
}
else
{
stop = TRUE;
sprintf(errbuf, "Send error: Missing text in line");
MessageBox(hWnd, errbuf, "Command Error", MB_ICONSTOP | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
}
stop = FALSE;
break;
/* start program in file after start token */
case IDM_START:
strcpy(cmd, curcmd->cmdstring);
p = NULL;
si.wShowWindow = SW_SHOWNORMAL;
if ((s = strstr(cmd, "\377")) != NULL)
{
*(s++) = 0;
if ((p = strstr(s, "\377")) != NULL) // check for startup directory
*(p++) = 0;
if (!stricmp(s, "min"))
// si.wShowWindow = SW_SHOWMINIMIZED;
si.wShowWindow = SW_SHOWMINNOACTIVE;
else
if (!stricmp(s, "max"))
si.wShowWindow = SW_SHOWMAXIMIZED;
else
if (stricmp(s, "norm"))
{
stop = TRUE;
sprintf(errbuf, "Syntax error\nstart,%s,%s", cmd, s);
MessageBox(hWnd, errbuf, "Command Error", MB_ICONSTOP | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
break;
}
}
si.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL;
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwFlags = STARTF_USESHOWWINDOW;
si.cbReserved2 = 0;
si.lpReserved2 = NULL;
errlevel = 0;
if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, p, &si, &pi))
errlevel = GetLastError();
break;
/* wait for a window with the appropriate text to appear */
case IDM_WAIT:
errlevel = 0;
if ((s = strstr(curcmd->cmdstring, "\377")) != NULL) // find separator character
{
if (!waitcount)
{
s++;
while (*s == 0x20 || *s == 0x9)
s++;
sscanf(s, "%d", &waitcount);
}
}
else
waitcount = -1;
if ((GlobalhWnd = GetTopWindow(NULL)) != NULL)
do {
if (GetWindowText(GlobalhWnd, module, sizeof(module)))
if (gstrscn(module, curcmd->cmdstring, curcmd->attrbuf, FALSE))
{
waitcount = 0;
break;
}
} while ((GlobalhWnd = GetNextWindow(GlobalhWnd, GW_HWNDNEXT)) != NULL);
if (waitcount)
{
waitcount--;
if (!waitcount)
{
errlevel = TRUE;
break;
}
nextcmd = curcmd; // branch back here
}
break;
/* check for file existence, branch if true */
case IDM_EXIST:
strcpy(cmd, curcmd->cmdstring);
s = strstr(cmd, "\377");
*(s++) = 0;
if ((ftmp = FindFirstFile(cmd, &fdata)) == INVALID_HANDLE_VALUE)
break;
FindClose(ftmp);
if ((nextcmd = FindLabel(s)) == (CMD *)-1)
{
stop = TRUE;
sprintf(errbuf, "Label \"%s\" not found", s);
MessageBox(hWnd, errbuf, "Command Error", MB_OK | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
}
break;
case IDM_CREATE:
if ((fh = fopen(curcmd->cmdstring, "w")) == NULL)
{
stop = TRUE;
sprintf(errbuf, "Unable to create file \"%s\"", curcmd->cmdstring);
MessageBox(hWnd, errbuf, "Command Error", MB_OK | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
}
time(&t);
fprintf(fh, "%s", asctime(localtime(&t)));
fclose(fh);
break;
case IDM_DELETE:
unlink(curcmd->cmdstring);
break;
/* branch on the msgbox return value */
case IDM_ONMSG:
strcpy(cmd, curcmd->cmdstring);
s = strstr(cmd, "\377");
*(s++) = 0;
if (!stricmp(cmd, "ABORT"))
{
if (mboxrtn != IDABORT)
break;
}
else
if (!stricmp(cmd, "CANCEL"))
{
if (mboxrtn != IDCANCEL)
break;
}
else
if (!stricmp(cmd, "IGNORE"))
{
if (mboxrtn != IDIGNORE)
break;
}
else
if (!stricmp(cmd, "NO"))
{
if (mboxrtn != IDNO)
break;
}
else
if (!stricmp(cmd, "OK"))
{
if (mboxrtn != IDOK)
break;
}
else
if (!stricmp(cmd, "RETRY"))
{
if (mboxrtn != IDRETRY)
break;
}
else
if (!stricmp(cmd, "YES"))
{
if (mboxrtn != IDYES)
break;
}
else
{
stop = TRUE;
sprintf(errbuf, "Syntax error\nonmsgrtn,%s,%s", cmd, s);
MessageBox(hWnd, errbuf, "Command Error", MB_ICONSTOP | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
break;
}
if ((nextcmd = FindLabel(s)) == (CMD *)-1)
{
stop = TRUE;
sprintf(errbuf, "Label \"%s\" not found", s);
MessageBox(hWnd, errbuf, "Command Error", MB_OK | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
}
break;
/* onerror processing, if errlevel is false skip, else find label */
case IDM_ONERR:
if (!errlevel)
break;
/* goto processing, branch to label */
case IDM_GOTO:
if ((nextcmd = FindLabel(curcmd->cmdstring)) == (CMD *)-1)
{
stop = TRUE;
MessageBox(hWnd, "Label not found", "Command Error", MB_OK | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
}
break;
/* generate a message box containing the given text */
case IDM_MSGBOX:
stop = TRUE;
strcpy(cmd, curcmd->cmdstring);
if ((s = strstr(cmd, "\377")) != NULL)
{
*(s++) = 0;
sscanf(s, "%d", &flags);
}
else
flags = MB_OK | MB_SYSTEMMODAL;
if (!strcmp(cmd, "$syserr"))
{
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errlevel,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
errbuf, sizeof(errbuf), NULL);
mboxrtn = MessageBox(hWnd, errbuf, "Error", MB_OK | MB_SYSTEMMODAL);
}
else
mboxrtn = MessageBox(hWnd, cmd, "Script message", flags);
stop = FALSE;
break;
// initialize a variable, create it if it doesn't exist
case IDM_SETVAR:
strcpy(cmd, curcmd->cmdstring);
s = strstr(cmd, "\377");
*(s++) = 0;
if (!varstart) // no variables have been defined, create it
{
varstart = (VAR *)malloc(sizeof(struct var));
varstart->next = NULL;
varstart->varname = (char *)malloc(strlen(cmd) + 1);
strcpy(varstart->varname, cmd);
sscanf(s, "%d", &varstart->rhs);
}
else // first search existing variable list
{
curvar = varstart;
while (curvar)
{
if (!stricmp(cmd, curvar->varname))
break;
curvar = curvar->next;
}
if (curvar) // var was found
sscanf(s, "%d", &curvar->rhs);
else
{
// malloc space for new curvar, then copy data
curvar = (VAR *)malloc(sizeof(struct var));
curvar->next = NULL;
curvar->varname = (char *)malloc(strlen(cmd) + 1);
strcpy(curvar->varname, cmd);
sscanf(s, "%d", &curvar->rhs);
}
}
break;
// decrement a variable, error if it doesn't exist
case IDM_DECVAR:
curvar = varstart;
while (curvar)
{
if (!stricmp(curcmd->cmdstring, curvar->varname))
break;
curvar = curvar->next;
}
if (!curvar)
{
stop = TRUE;
sprintf(errbuf, "Variable \"%s\" not found", curcmd->cmdstring);
MessageBox(hWnd, errbuf, "Command Error", MB_OK | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
}
else
curvar->rhs--;
break;
/* branch on variable = 0 processing, branch to label, error if it doesn't exist */
case IDM_VARZERO:
strcpy(cmd, curcmd->cmdstring);
s = strstr(cmd, "\377");
*(s++) = 0;
curvar = varstart;
while (curvar)
{
if (!stricmp(cmd, curvar->varname))
break;
curvar = curvar->next;
}
if (!curvar)
{
stop = TRUE;
sprintf(errbuf, "Variable \"%s\" not found", cmd);
MessageBox(hWnd, errbuf, "Command Error", MB_OK | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
}
else
if (!curvar->rhs)
if ((nextcmd = FindLabel(s)) == (CMD *)-1)
{
stop = TRUE;
MessageBox(hWnd, "Label not found", "Command Error", MB_OK | MB_SYSTEMMODAL);
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
}
break;
case IDM_QUIT:
PostMessage(hWnd, WM_DESTROY, 0, 0L);
break;
}
break;
case WM_DESTROY:
KillTimer(hWnd, 1);
FreeCMD(cmdstart);
FreeLabel(labelstart);
FreeVar(varstart);
PostQuitMessage(0);
break;
case WM_PAINT:
BeginPaint (hWnd, &ps);
EndPaint (hWnd, &ps);
break;
case WM_CREATE:
nextcmd = cmdstart;
break;
case WM_TIMER:
if (stop)
break;
curcmd = nextcmd;
if (curcmd != NULL)
{
nextcmd = curcmd->next;
PostMessage(hWnd, WM_COMMAND, (WPARAM)curcmd->function, 0L);
}
else
PostMessage(hWnd, WM_COMMAND, (WPARAM)IDM_QUIT, 0L);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return ((long)NULL);
}