|
|
1.1 ! root 1: /* ! 2: * Example of DOSMONOPEN, DOSGETINFOSEG, DOSMONREG, ! 3: * DOSMONREAD, DOSMONWRITE, DOSMONCLOSE usage. ! 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 ! 31: * is unknown, pick a convenient size and attempt a call to DOSMONREG. ! 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) ! 41: * are transferred to and from the buffers by DOSMONREAD and DOSMONWRITE. ! 42: * You should not attempt to read or write that area directly, nor should ! 43: * you modify any part of the header after a successful DOSMONREG. ! 44: * ! 45: * To maintain a rapid flow of data through any chain of monitors, ! 46: * DOSMONREAD and DOSMONWRITE operations should be done without any ! 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: * ! 63: */ ! 64: ! 65: #include <malloc.h> /* for malloc() declaration */ ! 66: #include <doscalls.h> ! 67: #include <subcalls.h> ! 68: ! 69: ! 70: #define CON 0 /* Handle for the console device */ ! 71: ! 72: #define NOPREFERENCE 0 /* DOSMONREG constants - */ ! 73: #define FRONT 1 /* where in the monitor chain */ ! 74: #define BACK 2 /* do we want to be installed? */ ! 75: ! 76: #define WAIT 0 /* DOSMONREAD and KBDCHARIN constants - */ ! 77: #define NOWAIT 1 /* should we wait for a key? */ ! 78: ! 79: #define THISTHREADONLY 0 /* DOSEXIT constants - */ ! 80: #define ALLTHREADS 1 /* who gets terminated? */ ! 81: ! 82: #define NOERROR 0 /* More DOSEXIT constants - */ ! 83: #define ERROR 1 /* what to return for error code? */ ! 84: ! 85: #define ESCAPE 27 /* ASCII constant */ ! 86: #define F10 68 /* SCAN code constant */ ! 87: ! 88: #define RELEASE 0x40 /* bit mask to distinguish */ ! 89: /* key press from key release */ ! 90: ! 91: #define MINBUFFSIZE 64 /* size for monitor buffers */ ! 92: /* 64 is minimum, 128 recommended */ ! 93: ! 94: struct GDTInfoArea{ /* structure for global infoseg */ ! 95: unsigned long time; ! 96: unsigned long milliseconds; ! 97: unsigned char hours; ! 98: unsigned char minutes; ! 99: unsigned char seconds; ! 100: unsigned char hundreths; ! 101: unsigned timezone; ! 102: unsigned timer_interval; ! 103: unsigned char day; ! 104: unsigned char month; ! 105: unsigned year; ! 106: unsigned char day_of_week; ! 107: unsigned char major_version; ! 108: unsigned char minor_version; ! 109: unsigned char revision_number; ! 110: unsigned char current_screen_group; ! 111: unsigned char max_num_of_screengrps; ! 112: unsigned char huge_selector_shift_count; ! 113: unsigned char protect_mode_indicator; ! 114: unsigned foreground_process_id; ! 115: unsigned char dynamic_variation_flag; ! 116: unsigned char maxwait; ! 117: unsigned minimum_timeslice; ! 118: unsigned maximum_timeslice; ! 119: unsigned boot_drive; ! 120: unsigned char reserved[32]; ! 121: }; ! 122: ! 123: struct CharPacket { /* substructure of KeyPacket */ ! 124: unsigned char asc; ! 125: unsigned char scan; ! 126: unsigned char status; ! 127: unsigned char dshift; ! 128: unsigned shift; ! 129: unsigned long time; ! 130: }; ! 131: ! 132: struct KeyPacket { /* KBD monitor data record */ ! 133: unsigned mnflags; ! 134: struct CharPacket cp; ! 135: unsigned ddflags; ! 136: }; ! 137: ! 138: struct MonBuff { /* generic monitor buffer header */ ! 139: unsigned bufflen; ! 140: unsigned ddbufflen; ! 141: unsigned char dispatch[12]; ! 142: }; ! 143: ! 144: ! 145: unsigned KBDHandle; /* keyboard handle from monitor open */ ! 146: ! 147: struct MonBuff *InBuff, *OutBuff; /* buffers for monitor read/writes */ ! 148: ! 149: ! 150: /* message strings */ ! 151: char *startMsg[] = { ! 152: "�������������������������������������������������������Ŀ", ! 153: "� �", ! 154: "� Example Monitor installed �", ! 155: "� �", ! 156: "� press Esc to terminate �", ! 157: "� �", ! 158: "���������������������������������������������������������", ! 159: 0}; ! 160: ! 161: char *intMsg[] = { ! 162: "�������������������������������������������������������Ŀ", ! 163: "� �", ! 164: "� <<< The F10 key has been struck >>> �", ! 165: "� �", ! 166: "� press any key to continue �", ! 167: "� �", ! 168: "���������������������������������������������������������", ! 169: 0}; ! 170: ! 171: ! 172: main() ! 173: { ! 174: struct KeyPacket keybuff; ! 175: struct GDTInfoArea *gdt; ! 176: struct KeyData dummy; ! 177: ! 178: unsigned short count; /* chars in monitor read/write buffer */ ! 179: unsigned gdt_descriptor, ldt_descriptor; /* infoseg descriptors */ ! 180: unsigned waitflag = 1; /* flag for popups */ ! 181: unsigned short row, col = 3; /* where to draw popup box */ ! 182: unsigned short length; /* length of lines in popup box */ ! 183: char **msg; /* to display messages */ ! 184: char *pc; /* to test characters */ ! 185: ! 186: ! 187: /* initialize this value */ ! 188: for ( length = 0, pc = *intMsg; *pc; pc++, length++) ! 189: ; ! 190: ! 191: /* allocate space for monitor read/write buffers */ ! 192: InBuff = (struct MonBuff *)malloc(MINBUFFSIZE); ! 193: OutBuff = (struct MonBuff *)malloc(MINBUFFSIZE); ! 194: ! 195: /* prepare buffer headers for registration process */ ! 196: InBuff->bufflen = MINBUFFSIZE; ! 197: OutBuff->bufflen = MINBUFFSIZE; ! 198: ! 199: /* obtain a handle for registering buffers */ ! 200: DOSMONOPEN ( "KBD$", &KBDHandle ); ! 201: ! 202: /* get the descriptor of global infoseg */ ! 203: /* and convert to far pointer so we can */ ! 204: /* get ID of current foreground screen group */ ! 205: DOSGETINFOSEG(&gdt_descriptor, &ldt_descriptor); ! 206: gdt = (struct GDTInfoArea *)((long)gdt_descriptor << 16); ! 207: ! 208: /* register the buffers to be used for monitoring */ ! 209: DOSMONREG ( KBDHandle, ! 210: (unsigned char *)InBuff, ! 211: (unsigned char *)OutBuff, FRONT, ! 212: gdt->current_screen_group ); ! 213: ! 214: /* Print a banner to show we've started */ ! 215: VIOPOPUP(&waitflag, CON); ! 216: for (row = 2, msg = startMsg; *msg;) ! 217: VIOWRTCHARSTR(*msg++, length, row++, col, CON); ! 218: DOSSLEEP((long)3000); ! 219: VIOENDPOPUP(CON); ! 220: ! 221: ! 222: /* main loop - read into monitor buffer, examine and take */ ! 223: /* action if "interesting" key, pass on to device driver */ ! 224: for (keybuff.cp.asc = 0; keybuff.cp.asc != ESCAPE;) { ! 225: count = sizeof(keybuff); ! 226: DOSMONREAD ( (unsigned char *)InBuff, WAIT, ! 227: (unsigned char *)&keybuff, (unsigned far *)&count ); ! 228: if ( ( keybuff.cp.asc == 0 ) && ! 229: ( keybuff.cp.scan == F10 ) && ! 230: ( ! ( keybuff.ddflags & RELEASE ) ) ) { ! 231: VIOPOPUP(&waitflag, CON); ! 232: for (row = 2, msg = intMsg; *msg;) ! 233: VIOWRTCHARSTR(*msg++, length, row++, col, CON); ! 234: KBDCHARIN( &dummy, WAIT, CON); ! 235: VIOENDPOPUP(CON); ! 236: } ! 237: ! 238: DOSMONWRITE ( (unsigned char *)OutBuff, ! 239: (unsigned char *)&keybuff, count ); ! 240: } ! 241: ! 242: /* close connection with keyboard */ ! 243: DOSMONCLOSE ( KBDHandle ); ! 244: ! 245: DOSEXIT ( ALLTHREADS, NOERROR ); ! 246: ! 247: ! 248: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.