home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
CALLBOX.ZIP
/
CALLBOX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-10-22
|
11KB
|
288 lines
#define INCL_NOPM
#define INCL_BASE
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <os2.h>
#include "dostalk.h"
#define DOM (PIPE_ACCESS_DUPLEX | PIPE_NOWRITEBEHIND | PIPE_NOINHERIT)
#define POM ( 1 | PIPE_WAIT | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE )
extern void Task_Manager(void );
extern void startbox(void );
extern void Task_Switch(void );
extern void far MonChain(void );
extern void main(int argc, char **argv);
extern void makepipe(char *dos_command);
#define THREAD_STK_SIZE 2048 /* Monitor Thread Stack Size */
#define NOPREFERENCE 0 /* DosMonReg constants - */
#define FRONT 1 /* where in the monitor chain */
#define BACK 2 /* do we want to be installed? */
#define WAIT 0 /* DOSMONREAD and KBDCHARIN constants - */
#define NOWAIT 1 /* should we wait for a key? */
#define NOERROR 0 /* DOSEXIT constants - */
#define ERROR 1 /* what to return for error code? */
#define MINBUFFSIZE 64 /* size for monitor buffers */
/* 64 is minimum, 128 recommended */
struct KeyPacket { /* KBD monitor data record */
unsigned mnflags;
KBDKEYINFO cp;
unsigned ddflags;
};
struct MonBuff { /* generic monitor buffer header */
unsigned bufflen;
unsigned ddbufflen;
unsigned char dispatch[12];
};
HKBD KBDHandle; /* keyboard handle from monitor open */
struct MonBuff *InBuff, *OutBuff; /* buffers for monitor read/writes */
/* MonFlag S.C. Char Shift NLSSh State Time Stamp DDFlag */
struct KeyPacket Alt_Down = { 0x3800, 0x00, 0x00, 0x40, 0x00, 0x0208, 0x00000000, 0x0007 };
struct KeyPacket Alt_Up = { 0xb800, 0x00, 0x00, 0x40, 0x00, 0x0000, 0x00000000, 0x0047 };
struct KeyPacket Ctl_Down = { 0x1d00, 0x00, 0x00, 0x40, 0x00, 0x0104, 0x00000000, 0x0007 };
struct KeyPacket Ctl_Up = { 0x9d00, 0x00, 0x00, 0x40, 0x00, 0x0000, 0x00000000, 0x0047 };
struct KeyPacket ESC_Down_Alt = { 0x0100, 0x00, 0x01, 0x40, 0x00, 0x0208, 0x00000000, 0x003f };
struct KeyPacket ESC_Up_Alt = { 0x8100, 0x00, 0x01, 0x40, 0x00, 0x0208, 0x00000000, 0x004c };
struct KeyPacket ESC_Down_Ctl = { 0x0100, 0x00, 0x01, 0x40, 0x00, 0x0104, 0x00000000, 0x003f };
struct KeyPacket ESC_Up_Ctl = { 0x8100, 0x00, 0x01, 0x40, 0x00, 0x0104, 0x00000000, 0x004c };
struct KeyPacket home1 = { 0xe080, 0x00, 0x00, 0x40, 0x00, 0x0080, 0x00000000, 0x0002 };
struct KeyPacket home2 = { 0x4780, 0x47, 0xe0, 0x40, 0x00, 0x0080, 0x00000000, 0x0080 };
struct KeyPacket home3 = { 0xe080, 0x00, 0x00, 0x40, 0x00, 0x0080, 0x00000000, 0x0002 };
struct KeyPacket home4 = { 0xc780, 0x47, 0xe0, 0x40, 0x00, 0x0080, 0x00000000, 0x00c0 };
struct KeyPacket enter1 = { 0x1c80, 0x1c, 0x0d, 0x40, 0x00, 0x0000, 0x00000000, 0x0000 };
struct KeyPacket enter2 = { 0x9c80, 0x1c, 0x0d, 0x40, 0x00, 0x0000, 0x00000000, 0x0040 };
unsigned short BuffLength; /* chars in monitor read/write buffer */
unsigned long sem; /* ram semaphore */
void Task_Manager()
{
DosSemRequest( &sem,SEM_INDEFINITE_WAIT); /* Sem Block to make sure */
/* that block goes out */
/* uninterrupted */
DosMonWrite ( (PBYTE)OutBuff, /* Depress the Ctl Key */
(PBYTE)&Ctl_Down, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, /* Depress the ESC Key */
(PBYTE)&ESC_Down_Ctl, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, /* Release the ESC Key */
(PBYTE)&ESC_Up_Ctl, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, /* Release the Ctl Key */
(PBYTE)&Ctl_Up, BuffLength );
DosSemClear( &sem);
DosSleep(100L);
}
void startbox(void)
{
DosSemRequest( &sem,SEM_INDEFINITE_WAIT);
DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&home1, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&home2, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&home3, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&home4, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&enter1, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&enter2, BuffLength );
DosSemClear( &sem);
DosSleep(100L);
}
void Task_Switch()
{
DosSemRequest( &sem,SEM_INDEFINITE_WAIT); /* Sem Block to make sure */
/* that block goes out */
/* uninterrupted */
DosMonWrite ( (PBYTE)OutBuff, /* Depress the Alt Key */
(PBYTE)&Alt_Down, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, /* Depress the ESC Key */
(PBYTE)&ESC_Down_Alt, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, /* Release the ESC Key */
(PBYTE)&ESC_Up_Alt, BuffLength );
DosMonWrite ( (PBYTE)OutBuff, /* Release the Alt Key */
(PBYTE)&Alt_Up, BuffLength );
DosSemClear( &sem);
DosSleep(200L);
}
void far MonChain(void)
{
struct KeyPacket keybuff; /* struct to read a write Kbd monitor data */
unsigned short count; /* chars in monitor read/write buffer */
count = sizeof(keybuff); /* get the size of the KBD Monitor Struct */
for (;;) { /* repeat ad noseum */
DosMonRead ( (unsigned char *)InBuff, WAIT, /* Wait for any Mon input */
(unsigned char *)&keybuff, &count );
DosSemRequest( &sem, SEM_INDEFINITE_WAIT); /* yes - block the Mon Out */
DosMonWrite ( (unsigned char *)OutBuff, /* Pass Mon Packet as is */
(unsigned char *)&keybuff, count );
DosSemClear( &sem); /* re-enable task/session switch */
// DosSleep(100L); /* Allow Task Switch */
}
}
void main(int argc, char **argv)
{
struct KeyPacket keybuff;
char far *MonChainStack; /* far pointer to Monitor Chain Loop stack */
TID MonChainID; /* thread ID */
unsigned rc; /* return code */
static char cmd[256];
int i;
if( argc < 2 ){
printf("Usage CALLBOX <command>\n");
printf("If BOXMON.EXE is running in the DOSBOX, <command> will be sent to it.\n");
return;
}
/* allocate space for monitor read/write buffers */
InBuff = (struct MonBuff *)malloc(MINBUFFSIZE);
OutBuff = (struct MonBuff *)malloc(MINBUFFSIZE);
if ((InBuff == NULL) || (OutBuff == NULL))
DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
/* prepare buffer headers for registration process */
InBuff->bufflen = MINBUFFSIZE;
OutBuff->bufflen = MINBUFFSIZE;
/* obtain a handle for registering buffers */
rc = DosMonOpen ( "KBD$", &KBDHandle );
if (rc != NOERROR)
DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
/* NOTE that the screen group is hard coded at '1'. This is the PM
* screen group. This may not work in future versions of os/2!
*/
rc = DosMonReg ( KBDHandle, (PBYTE)InBuff, (PBYTE)OutBuff, FRONT, 1);
if (rc != NOERROR)
DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
BuffLength = sizeof(keybuff);
/* Monitor Loop Thread setup */
/* Monitors are part of the data flow path through a device */
/* driver. Monitors should be written so that a thread actually */
/* performs rapid I/O and passes the data flowing into the */
/* monitor chain back into this same chain. This imperative so that */
/* monitor control characters (if not processed by all monitors) are */
/* available through the monitor chain. */
sem = 0L; /* init semaphore */
/* allocate stack space for MonChain thread */
/* since this is written in C, DOSALLOCSEG cannot be used here */
if ((MonChainStack = malloc(THREAD_STK_SIZE)) == NULL) {
DosMonClose ( KBDHandle ); /* Close KBD Monitor */
DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
}
MonChainStack += THREAD_STK_SIZE; /* since stack grows down */
/* start another thread */
if (rc = DosCreateThread( MonChain, &MonChainID,
MonChainStack )) {
DosMonClose ( KBDHandle ); /* Close KBD Monitor */
DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
}
cmd[0] = '\0';
for(i=1; i<argc; i++){
strcat(cmd, argv[i]);
if( i != (argc-1) )
strcat(cmd, " ");
}
makepipe(cmd);
Task_Switch();
/* close connection with keyboard */
DosMonClose ( KBDHandle );
DosExit ( EXIT_PROCESS, NOERROR );
}
void makepipe(char *dos_command)
{
USHORT rc, bytes;
HPIPE hpipe;
static char buf[256];
if(rc = DosMakeNmPipe( pipe, &hpipe, DOM, POM, 256, 256, -1L)){
printf("Couldn't make %s, error %04x\n", pipe, rc);
exit(3);
}
else{
DosSleep(100L);
Task_Manager(); /* Call Task Manager */
startbox();
printf("Waiting for connection...");
if(rc = DosConnectNmPipe(hpipe)){
printf("Error %04x\n", rc);
return;
}
else{
printf("Ok.\n");
rc = DosRead(hpipe, buf, sizeof(buf), &bytes);
if(!rc && bytes == sizeof(ackmsg1)){
printf("%s\n", buf);
DosWrite(hpipe, dos_command, strlen(dos_command), &bytes);
/* We have sent the command to BOXMON. Now wait for
* it to finish.
*/
rc = DosRead(hpipe, buf, sizeof(buf), &bytes);
if(!rc && bytes == sizeof(ackmsg2)){
printf("%s\n", buf);
}
}
}
DosClose(hpipe);
DosSleep(100L);
}
}