/* monitor.c - a demonstration keyboard monitor program that runs in any full screen session. The program is an example of the C Set++ 32-bit mixed model. This monitor "encrypts" keystrokes by incrementing the ASCII code. To run this monitor: DETACH monitor > MON.TXT To terminate - press the ESCape key. compile with: ICC /Kb monitor.c */ #define INCL_BASE #include #include #include #include #define OFFSET_SESSION_ID 0x18 #define HEAD_OF_LIST 1 #define ESCAPE 27 #define FOREVER for (;;) /* The following two sets of lines would normally be contained in a .H "monitor.h" file. Instead they are embedded in this file to emphasize how the 16-bit APIs are treated within a 32-bit mixed model program. The define statements are used to create the monitor API names as they are known inside the os2386.lib file. The APIRET16... statements are the prototypes for the 16-bit monitor APIs. */ #define DosGetInfoSeg DOS16GETINFOSEG #define DosMonOpen DOS16MONOPEN #define DosMonReg DOS16MONREG #define DosMonRead DOS16MONREAD #define DosMonWrite DOS16MONWRITE APIRET16 APIENTRY16 DosGetInfoSeg ( PUSHORT, PUSHORT ); APIRET16 APIENTRY16 DosMonOpen ( PSZ, PUSHORT); APIRET16 APIENTRY16 DosMonReg ( SHANDLE, PBYTE, PBYTE, USHORT, SHORT); APIRET16 APIENTRY16 DosMonRead ( PBYTE, USHORT, PBYTE, PUSHORT); APIRET16 APIENTRY16 DosMonWrite ( PBYTE, PBYTE, USHORT); /* monbuff - structure for monitor input and output buffers */ typedef struct _monbuff { USHORT usLength; BYTE reserved [18]; BYTE data [16]; } MONBUFF, *PMONBUFF; /* workbuff - structure that monitor uses to process keystroke packets */ typedef struct _workbuff { USHORT usMonFlag; /* monitor flag word */ KBDKEYINFO keybuff; /* KdbCharIn structure */ USHORT keyddFflags; /* device driver flags */ } WORKBUFF, *PWORKBUFF; int main (void) { USHORT usGlobalSel; /* selector for global info */ USHORT usLocalSel; /* selector for local info */ PBYTE pGinfo; /* 16:16 pointer to global info */ /* variables for monitor APIs */ MONBUFF monBuffIn; /* device driver puts data here */ MONBUFF monBuffOut; /* device driver gets data from here */ WORKBUFF workBuff; /* application work area for filtering */ USHORT cbWorkLength; /* length of work buffer */ USHORT hMonitor; /* monitor handle */ APIRET16 rc; /* obtain a selector for the global information segment so we can determine the foreground full screen session ID - this 16-bit API is required since there is no corresponding 32-bit API that will accomplish this job */ rc = DosGetInfoSeg (&usGlobalSel, &usLocalSel); if (rc) { printf ("DosGetInfoSeg Error, rc = %1d\n",rc); exit (1); } /* convert 16 bit selector and offset to a 16:16 style address. MAKEP is a toolkt20 supplied macro that shifts left by 16 bits the first argument and then ORs in the second argument */ pGinfo = MAKEP (usGlobalSel, OFFSET_SESSION_ID); printf ("screen group (session ID) = %1d\n",*pGinfo); /* see if the driver supports a monitor and if so, get the handle */ rc = DosMonOpen ("KBD$",&hMonitor); if (rc) { printf ("DosMonOpen Error, rc = %1d\n",rc); exit (1); } /* initialize the input/output buffer fields */ memset (&monBuffIn, 0, sizeof (MONBUFF)); memset (&monBuffOut, 0, sizeof (MONBUFF)); monBuffIn.usLength = sizeof (MONBUFF); monBuffOut.usLength = sizeof (MONBUFF); /* register the monitor buffers into the chain and request head of the list position and register the current full screen foreground session using the session id variable found with DodGetInfoSeg */ rc = DosMonReg (hMonitor, (PBYTE)&monBuffIn, (PBYTE)&monBuffOut, (USHORT)HEAD_OF_LIST, (SHORT)*pGinfo); if (rc) { printf ("DosMonReg Error, rc = %1d\n",rc); exit (1); } /* read keystrokes until the ESCape key is pressed "encrypt" each keystroke by incrementing the ASCII code */ FOREVER { cbWorkLength = sizeof ( WORKBUFF ); rc = DosMonRead ((PBYTE)&monBuffIn, (USHORT)0, (PBYTE)&workBuff, (PUSHORT)&cbWorkLength); if (rc) { printf ("DosMonRead Error, rc = %1d\n",rc); exit (1); } if (workBuff.keybuff.chChar == ESCAPE) exit (0); workBuff.keybuff.chChar++; rc = DosMonWrite ((PBYTE)&monBuffOut, (PBYTE)&workBuff, cbWorkLength); if (rc) { printf ("DosMonWrite Error, rc = %1d\n",rc); exit (1); } } return 0; }