home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / CALLBOX.ZIP / CALLBOX.C < prev    next >
C/C++ Source or Header  |  1989-10-22  |  11KB  |  288 lines

  1. #define INCL_NOPM
  2. #define INCL_BASE
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <malloc.h>  
  7. #include <os2.h>
  8. #include "dostalk.h"
  9.  
  10. #define DOM (PIPE_ACCESS_DUPLEX | PIPE_NOWRITEBEHIND | PIPE_NOINHERIT)
  11. #define POM ( 1 | PIPE_WAIT | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE )
  12.  
  13. extern  void Task_Manager(void );
  14. extern  void startbox(void );
  15. extern  void Task_Switch(void );
  16. extern  void far MonChain(void );
  17. extern  void main(int argc, char **argv);
  18. extern  void makepipe(char *dos_command);
  19.  
  20. #define THREAD_STK_SIZE 2048            /* Monitor Thread Stack Size */
  21.  
  22. #define NOPREFERENCE    0               /* DosMonReg constants - */
  23. #define FRONT           1               /* where in the monitor chain */
  24. #define BACK            2               /* do we want to be installed? */
  25.  
  26. #define WAIT            0               /* DOSMONREAD and KBDCHARIN constants - */
  27. #define NOWAIT          1                /* should we wait for a key? */
  28.  
  29. #define NOERROR         0               /* DOSEXIT constants - */
  30. #define ERROR           1               /* what to return for error code? */
  31.  
  32.  
  33. #define MINBUFFSIZE     64              /* size for monitor buffers */
  34.                                         /* 64 is minimum, 128 recommended */
  35.  
  36.  
  37. struct KeyPacket {              /* KBD monitor data record */
  38.         unsigned       mnflags;
  39.         KBDKEYINFO     cp;
  40.         unsigned       ddflags;
  41. };
  42.  
  43. struct MonBuff {                        /* generic monitor buffer header */
  44.         unsigned        bufflen;
  45.         unsigned        ddbufflen;
  46.         unsigned char   dispatch[12];
  47. };
  48.  
  49.  
  50. HKBD    KBDHandle;           /* keyboard handle from monitor open */
  51.  
  52. struct MonBuff  *InBuff, *OutBuff;     /* buffers for monitor read/writes */
  53.  
  54. /*                                MonFlag S.C.  Char  Shift NLSSh State   Time Stamp  DDFlag */
  55. struct KeyPacket Alt_Down     = { 0x3800, 0x00, 0x00, 0x40, 0x00, 0x0208, 0x00000000, 0x0007 };
  56. struct KeyPacket Alt_Up       = { 0xb800, 0x00, 0x00, 0x40, 0x00, 0x0000, 0x00000000, 0x0047 };
  57. struct KeyPacket Ctl_Down     = { 0x1d00, 0x00, 0x00, 0x40, 0x00, 0x0104, 0x00000000, 0x0007 };
  58. struct KeyPacket Ctl_Up       = { 0x9d00, 0x00, 0x00, 0x40, 0x00, 0x0000, 0x00000000, 0x0047 };
  59. struct KeyPacket ESC_Down_Alt = { 0x0100, 0x00, 0x01, 0x40, 0x00, 0x0208, 0x00000000, 0x003f };
  60. struct KeyPacket ESC_Up_Alt   = { 0x8100, 0x00, 0x01, 0x40, 0x00, 0x0208, 0x00000000, 0x004c };
  61. struct KeyPacket ESC_Down_Ctl = { 0x0100, 0x00, 0x01, 0x40, 0x00, 0x0104, 0x00000000, 0x003f };
  62. struct KeyPacket ESC_Up_Ctl   = { 0x8100, 0x00, 0x01, 0x40, 0x00, 0x0104, 0x00000000, 0x004c };
  63.  
  64. struct KeyPacket home1        = { 0xe080, 0x00, 0x00, 0x40, 0x00, 0x0080, 0x00000000, 0x0002 };
  65. struct KeyPacket home2        = { 0x4780, 0x47, 0xe0, 0x40, 0x00, 0x0080, 0x00000000, 0x0080 };
  66. struct KeyPacket home3        = { 0xe080, 0x00, 0x00, 0x40, 0x00, 0x0080, 0x00000000, 0x0002 };
  67. struct KeyPacket home4        = { 0xc780, 0x47, 0xe0, 0x40, 0x00, 0x0080, 0x00000000, 0x00c0 };
  68.  
  69. struct KeyPacket enter1       = { 0x1c80, 0x1c, 0x0d, 0x40, 0x00, 0x0000, 0x00000000, 0x0000 };
  70. struct KeyPacket enter2       = { 0x9c80, 0x1c, 0x0d, 0x40, 0x00, 0x0000, 0x00000000, 0x0040 };
  71.  
  72.  
  73. unsigned short  BuffLength;     /* chars in monitor read/write buffer */
  74. unsigned long    sem;           /* ram semaphore */
  75.  
  76.  
  77. void Task_Manager()
  78. {
  79.         DosSemRequest( &sem,SEM_INDEFINITE_WAIT);  /* Sem Block to make sure */
  80.                                                    /* that block goes out    */
  81.                                                    /* uninterrupted          */
  82.  
  83.         DosMonWrite ( (PBYTE)OutBuff,              /* Depress the Ctl Key */
  84.                       (PBYTE)&Ctl_Down, BuffLength );
  85.  
  86.         DosMonWrite ( (PBYTE)OutBuff,              /* Depress the ESC Key */
  87.                       (PBYTE)&ESC_Down_Ctl, BuffLength );
  88.  
  89.         DosMonWrite ( (PBYTE)OutBuff,              /* Release the ESC Key */
  90.                       (PBYTE)&ESC_Up_Ctl, BuffLength );
  91.  
  92.         DosMonWrite ( (PBYTE)OutBuff,              /* Release the Ctl Key */
  93.                       (PBYTE)&Ctl_Up, BuffLength );
  94.  
  95.  
  96.         DosSemClear( &sem);
  97.         DosSleep(100L);
  98. }
  99.  
  100. void startbox(void)
  101. {
  102.         DosSemRequest( &sem,SEM_INDEFINITE_WAIT);
  103.  
  104.         DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&home1, BuffLength );
  105.         DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&home2, BuffLength );
  106.         DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&home3, BuffLength );
  107.         DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&home4, BuffLength );
  108.  
  109.         DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&enter1, BuffLength );
  110.         DosMonWrite ( (PBYTE)OutBuff, (PBYTE)&enter2, BuffLength );
  111.  
  112.         DosSemClear( &sem);
  113.         DosSleep(100L);
  114. }
  115.  
  116. void Task_Switch()
  117. {
  118.         DosSemRequest( &sem,SEM_INDEFINITE_WAIT);  /* Sem Block to make sure */
  119.                                                    /* that block goes out    */
  120.                                                    /* uninterrupted          */
  121.  
  122.         DosMonWrite ( (PBYTE)OutBuff,           /* Depress the Alt Key */
  123.                       (PBYTE)&Alt_Down, BuffLength );
  124.  
  125.         DosMonWrite ( (PBYTE)OutBuff,           /* Depress the ESC Key */
  126.                       (PBYTE)&ESC_Down_Alt, BuffLength );
  127.  
  128.         DosMonWrite ( (PBYTE)OutBuff,           /* Release the ESC Key */
  129.                       (PBYTE)&ESC_Up_Alt, BuffLength );
  130.  
  131.         DosMonWrite ( (PBYTE)OutBuff,           /* Release the Alt Key */
  132.                       (PBYTE)&Alt_Up, BuffLength );
  133.  
  134.         DosSemClear( &sem);
  135.         DosSleep(200L);
  136. }
  137.  
  138. void far MonChain(void)
  139. {
  140.         struct KeyPacket keybuff;   /* struct to read a write Kbd monitor data */
  141.         unsigned short  count;      /* chars in monitor read/write buffer */
  142.  
  143.  
  144.         count = sizeof(keybuff);    /* get the size of the KBD Monitor Struct */
  145.  
  146.         for (;;) {                   /* repeat ad noseum */
  147.  
  148.  
  149.  
  150.            DosMonRead ( (unsigned char *)InBuff, WAIT, /* Wait for any Mon input */
  151.                         (unsigned char *)&keybuff, &count );
  152.  
  153.            DosSemRequest( &sem, SEM_INDEFINITE_WAIT);  /* yes - block the Mon Out */
  154.  
  155.            DosMonWrite ( (unsigned char *)OutBuff,     /* Pass Mon Packet as is   */
  156.                          (unsigned char *)&keybuff, count );
  157.  
  158.            DosSemClear( &sem);                          /* re-enable task/session switch */
  159.  
  160. //         DosSleep(100L);                              /* Allow Task Switch */
  161.         }
  162. }
  163.  
  164. void main(int argc, char **argv)
  165. {
  166.         struct KeyPacket  keybuff;
  167.         char far *MonChainStack;        /* far pointer to Monitor Chain Loop stack */
  168.         TID      MonChainID;            /* thread ID */
  169.         unsigned rc;                    /* return code */
  170.         static char cmd[256];
  171.         int i;
  172.  
  173.  
  174.         if( argc < 2 ){
  175.             printf("Usage CALLBOX  <command>\n");
  176.             printf("If BOXMON.EXE is running in the DOSBOX, <command> will be sent to it.\n");
  177.             return;
  178.         }
  179.         /* allocate space for monitor read/write buffers */
  180.         InBuff = (struct MonBuff *)malloc(MINBUFFSIZE);
  181.         OutBuff = (struct MonBuff *)malloc(MINBUFFSIZE);
  182.  
  183.         if ((InBuff == NULL) || (OutBuff == NULL))
  184.             DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
  185.  
  186.         /* prepare buffer headers for registration process */
  187.         InBuff->bufflen = MINBUFFSIZE;
  188.         OutBuff->bufflen = MINBUFFSIZE;
  189.  
  190.         /* obtain a handle for registering buffers */
  191.         rc = DosMonOpen ( "KBD$", &KBDHandle );
  192.         if (rc != NOERROR)
  193.             DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
  194.  
  195.         /* NOTE that the screen group is hard coded at '1'. This is the PM
  196.          * screen group. This may not work in future versions of os/2!
  197.          */
  198.         rc = DosMonReg ( KBDHandle, (PBYTE)InBuff, (PBYTE)OutBuff, FRONT, 1);
  199.         if (rc != NOERROR)
  200.             DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
  201.  
  202.         BuffLength = sizeof(keybuff);
  203.  
  204.         /* Monitor Loop Thread setup */
  205.         /* Monitors are part of the data flow path through a device */
  206.         /* driver. Monitors should be written so that a thread actually */
  207.         /* performs rapid I/O and passes the data flowing into the */
  208.         /* monitor chain back into this same chain. This imperative so that */
  209.         /* monitor control characters (if not processed by all monitors) are */
  210.         /* available through the monitor chain. */
  211.  
  212.         sem = 0L;                       /* init semaphore */
  213.  
  214.         /* allocate stack space for MonChain thread */
  215.         /* since this is written in C, DOSALLOCSEG cannot be used here */
  216.  
  217.         if ((MonChainStack = malloc(THREAD_STK_SIZE)) == NULL) {
  218.  
  219.                 DosMonClose ( KBDHandle );       /* Close KBD Monitor */
  220.                 DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
  221.  
  222.         }
  223.         MonChainStack += THREAD_STK_SIZE;        /* since stack grows down */
  224.  
  225.         /* start another thread */
  226.         if (rc = DosCreateThread( MonChain, &MonChainID,
  227.                                   MonChainStack ))  {
  228.  
  229.                 DosMonClose ( KBDHandle );       /* Close KBD Monitor */
  230.                 DosExit ( EXIT_PROCESS, ERROR ); /*terminate all threads and return error */
  231.  
  232.         }
  233.  
  234.         cmd[0] = '\0';
  235.         for(i=1; i<argc; i++){
  236.             strcat(cmd, argv[i]);
  237.             if( i != (argc-1) )
  238.                 strcat(cmd, " ");
  239.         }
  240.         makepipe(cmd);
  241.         Task_Switch();
  242.  
  243.         /* close connection with keyboard */
  244.         DosMonClose ( KBDHandle );
  245.         DosExit ( EXIT_PROCESS, NOERROR );
  246. }
  247.  
  248.  
  249. void makepipe(char *dos_command)
  250. {
  251.     USHORT rc, bytes;
  252.     HPIPE hpipe;
  253.     static char buf[256];
  254.  
  255.     if(rc = DosMakeNmPipe( pipe, &hpipe, DOM, POM, 256, 256, -1L)){
  256.         printf("Couldn't make %s, error %04x\n", pipe, rc);
  257.         exit(3);
  258.     }
  259.     else{
  260.         DosSleep(100L);
  261.         Task_Manager();             /* Call Task Manager              */
  262.         startbox();
  263.         printf("Waiting for connection...");
  264.         if(rc = DosConnectNmPipe(hpipe)){
  265.             printf("Error %04x\n", rc);
  266.             return;
  267.         }
  268.         else{
  269.             printf("Ok.\n");
  270.             rc = DosRead(hpipe, buf, sizeof(buf), &bytes);
  271.             if(!rc && bytes == sizeof(ackmsg1)){
  272.                 printf("%s\n", buf);
  273.                 DosWrite(hpipe, dos_command, strlen(dos_command), &bytes);
  274.                 /* We have sent the command to BOXMON. Now wait for
  275.                  * it to finish.
  276.                  */
  277.                 rc = DosRead(hpipe, buf, sizeof(buf), &bytes);
  278.                 if(!rc && bytes == sizeof(ackmsg2)){
  279.                     printf("%s\n", buf);
  280.                 }
  281.             }
  282.         }
  283.         DosClose(hpipe);
  284.         DosSleep(100L);
  285.     }
  286. }
  287.  
  288.