|
|
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.