|
|
1.1 root 1: /* 1.1.1.2 ! root 2: * Example of DosMonOpen, DosGetInfoSeg, DosMonReg, ! 3: * DosMonRead, DosMonWrite, DosMonClose usage. 1.1 root 4: * 5: * Shows how to: 6: * 7: * Obtain a keyboard monitor handle, get the handle of the 8: * current foreground screen group, register a pair of i/o 9: * buffers for the current screen group, move data through 10: * the i/o buffers, and finally close connection with the keyboard. 11: * 12: * Notes: 13: * 14: * This program will issue a popup every time the F10 key is pressed. 15: * Pressing escape will terminate the program. 16: * While it is not particularly useful, it does demonstrate a use of 17: * monitors, and proper use of associated monitor calls and structures. 18: * 19: * The first 16 bytes of a monitor buffer are devoted to the 20: * header, as described by the MonBuff structure below. Prior to 21: * registering, the first word (bufflen) must be set to the size 22: * of the entire buffer itself. The entire buffer includes the 23: * header (16 bytes) and room for at least one data record (16 bytes 24: * in the case of the keyboard device driver), so the minimum size 25: * for this example would be 32 bytes (see MINBUFFSIZE above); 26: * however, some drivers may have slightly different requirements, 27: * in which case you should use the method described next, rather than 28: * assuming some fixed length. 29: * 30: * If you wish to monitor a device driver whose data record size 1.1.1.2 ! root 31: * is unknown, pick a convenient size and attempt a call to DosMonReg. 1.1 root 32: * If it fails due to ERROR_NOT_ENOUGH_MEMORY, examine the 2nd word 33: * of your buffer, since it will now contain the size of the driver's 34: * buffer (ddbufflen in the example). Allocate buffer(s) which can 35: * hold a data record of that size (in addition to the 16-byte header) 36: * and re-register your buffer(s). If the same error occurs, then 37: * there is simply insufficient resources to support another monitor. 38: * 39: * Note the MonBuff header structure does not define the monitor buffer 40: * beyond the header, because data records (KeyPackets in this example) 1.1.1.2 ! root 41: * are transferred to and from the buffers by DosMonRead and DosMonWrite. 1.1 root 42: * You should not attempt to read or write that area directly, nor should 1.1.1.2 ! root 43: * you modify any part of the header after a successful DosMonReg. 1.1 root 44: * 45: * To maintain a rapid flow of data through any chain of monitors, 1.1.1.2 ! root 46: * DosMonRead and DosMonWrite operations should be done without any 1.1 root 47: * intervening slow operations or system calls. If necessary, dedicate 48: * a thread to the monitor stream, and raise its priority. 49: * 50: * Makefile: 51: * 52: * LIB=\lib 53: * INC=\include 54: * OPT=-AL -G2 -Zi -Lp -Ox -Zp -I$(INC) 55: * 56: * monitors.exe: monitors.c monitors 57: * cl $(OPT) monitors.c 58: * 59: * 60: * To Run: 61: * detach monitors 62: * 1.1.1.2 ! root 63: * ! 64: * Created by Microsoft Corp. 1988 1.1 root 65: */ 66: 1.1.1.2 ! root 67: #define INCL_DOSPROCESS ! 68: #define INCL_SUB ! 69: #define INCL_DOSMONITORS ! 70: #define INCL_DOSINFOSEG ! 71: 1.1 root 72: #include <malloc.h> /* for malloc() declaration */ 1.1.1.2 ! root 73: #include <os2def.h> ! 74: #include <bse.h> 1.1 root 75: 76: 77: #define CON 0 /* Handle for the console device */ 78: 1.1.1.2 ! root 79: #define NOPREFERENCE 0 /* DosMonReg constants - */ 1.1 root 80: #define FRONT 1 /* where in the monitor chain */ 81: #define BACK 2 /* do we want to be installed? */ 82: 83: 1.1.1.2 ! root 84: #define NOERROR 0 /* DOSEXIT constants - */ 1.1 root 85: #define ERROR 1 /* what to return for error code? */ 86: 87: #define ESCAPE 27 /* ASCII constant */ 88: #define F10 68 /* SCAN code constant */ 89: 90: #define RELEASE 0x40 /* bit mask to distinguish */ 91: /* key press from key release */ 92: 93: #define MINBUFFSIZE 64 /* size for monitor buffers */ 94: /* 64 is minimum, 128 recommended */ 95: 96: 97: struct KeyPacket { /* KBD monitor data record */ 1.1.1.2 ! root 98: unsigned mnflags; ! 99: KBDKEYINFO cp; ! 100: unsigned ddflags; 1.1 root 101: }; 102: 103: struct MonBuff { /* generic monitor buffer header */ 104: unsigned bufflen; 105: unsigned ddbufflen; 106: unsigned char dispatch[12]; 107: }; 108: 109: 1.1.1.2 ! root 110: HKBD KBDHandle; /* keyboard handle from monitor open */ 1.1 root 111: 112: struct MonBuff *InBuff, *OutBuff; /* buffers for monitor read/writes */ 113: 114: 115: /* message strings */ 116: char *startMsg[] = { 117: "�������������������������������������������������������Ŀ", 118: "� �", 119: "� Example Monitor installed �", 120: "� �", 121: "� press Esc to terminate �", 122: "� �", 123: "���������������������������������������������������������", 124: 0}; 125: 126: char *intMsg[] = { 127: "�������������������������������������������������������Ŀ", 128: "� �", 129: "� <<< The F10 key has been struck >>> �", 130: "� �", 131: "� press any key to continue �", 132: "� �", 133: "���������������������������������������������������������", 134: 0}; 135: 136: 137: main() 138: { 139: struct KeyPacket keybuff; 1.1.1.2 ! root 140: PGINFOSEG gdt; ! 141: KBDKEYINFO dummy; 1.1 root 142: 1.1.1.2 ! root 143: USHORT count; /* chars in monitor read/write buffer */ ! 144: SEL gdt_descriptor, ldt_descriptor; /* infoseg descriptors */ 1.1 root 145: unsigned waitflag = 1; /* flag for popups */ 1.1.1.2 ! root 146: USHORT row, col = 3; /* where to draw popup box */ ! 147: USHORT length; /* length of lines in popup box */ 1.1 root 148: char **msg; /* to display messages */ 149: char *pc; /* to test characters */ 150: 151: 152: /* initialize this value */ 153: for ( length = 0, pc = *intMsg; *pc; pc++, length++) 154: ; 155: 156: /* allocate space for monitor read/write buffers */ 157: InBuff = (struct MonBuff *)malloc(MINBUFFSIZE); 158: OutBuff = (struct MonBuff *)malloc(MINBUFFSIZE); 159: 160: /* prepare buffer headers for registration process */ 161: InBuff->bufflen = MINBUFFSIZE; 162: OutBuff->bufflen = MINBUFFSIZE; 163: 164: /* obtain a handle for registering buffers */ 1.1.1.2 ! root 165: DosMonOpen ( "KBD$", &KBDHandle ); 1.1 root 166: 167: /* get the descriptor of global infoseg */ 168: /* and convert to far pointer so we can */ 169: /* get ID of current foreground screen group */ 1.1.1.2 ! root 170: DosGetInfoSeg(&gdt_descriptor, &ldt_descriptor); ! 171: gdt = MAKEPGINFOSEG(gdt_descriptor); 1.1 root 172: 173: /* register the buffers to be used for monitoring */ 1.1.1.2 ! root 174: DosMonReg ( KBDHandle, (PBYTE)InBuff, (PBYTE)OutBuff, FRONT, ! 175: gdt->sgCurrent); 1.1 root 176: 177: /* Print a banner to show we've started */ 1.1.1.2 ! root 178: VioPopUp(&waitflag, CON); 1.1 root 179: for (row = 2, msg = startMsg; *msg;) 1.1.1.2 ! root 180: VioWrtCharStr(*msg++, length, row++, col, CON); ! 181: DosSleep(3000L); ! 182: VioEndPopUp(CON); 1.1 root 183: 184: 185: /* main loop - read into monitor buffer, examine and take */ 186: /* action if "interesting" key, pass on to device driver */ 1.1.1.2 ! root 187: for (keybuff.cp.chChar = 0; keybuff.cp.chChar != ESCAPE;) { 1.1 root 188: count = sizeof(keybuff); 1.1.1.2 ! root 189: DosMonRead ((PBYTE)InBuff, IO_WAIT, ! 190: (PBYTE)&keybuff, (PUSHORT)&count ); ! 191: if ( ( keybuff.cp.chChar == 0 ) && ! 192: ( keybuff.cp.chScan == F10 ) && 1.1 root 193: ( ! ( keybuff.ddflags & RELEASE ) ) ) { 1.1.1.2 ! root 194: VioPopUp(&waitflag, CON); 1.1 root 195: for (row = 2, msg = intMsg; *msg;) 1.1.1.2 ! root 196: VioWrtCharStr(*msg++, length, row++, col, CON); ! 197: KbdCharIn( &dummy, IO_WAIT, CON); ! 198: VioEndPopUp(CON); 1.1 root 199: } 200: 1.1.1.2 ! root 201: DosMonWrite ( (PBYTE)OutBuff, ! 202: (PBYTE)&keybuff, count ); 1.1 root 203: } 204: 205: /* close connection with keyboard */ 1.1.1.2 ! root 206: DosMonClose ( KBDHandle ); 1.1 root 207: 1.1.1.2 ! root 208: DosExit ( EXIT_PROCESS, NOERROR ); 1.1 root 209: 210: 211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.