Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!mit-eddie!interlan!backman From: backman@interlan.UUCP (Larry Backman) Newsgroups: comp.sys.ibm.pc Subject: Re: Finding the address of functions in MSC, and the ^C interupt Message-ID: <130@interlan.UUCP> Date: Fri, 1-May-87 07:52:13 EDT Article-I.D.: interlan.130 Posted: Fri May 1 07:52:13 1987 Date-Received: Sat, 2-May-87 15:01:15 EDT References: <2042@hoptoad.uucp> Reply-To: backman@interlan.UUCP (1014-Larry Backman) Organization: MICOM-Interlan, Boxborough, MA Lines: 140 In article <2042@hoptoad.uucp> pozar@hoptoad.UUCP (Tim Pozar) writes: > > I was wondering how one finds the address of a function and would >apply it to setting a vector interupt with it. This is the code that >I came up with. It compiles with one error (see below). If anyone >has any insite on how this could be better done, I would like to >hear it. > Tim Pozar > > * > * This programme will push the "DOS CONTROL-C Exit Address" vector > * and set it to the "bye()" function. bye() should pop the old > * address and then executes the users code. The old vector should > * be restored if the programme ends through the remaped vector or before > * a standard exit(). bye() should also come before the retrival of the > * function's address with the way MSC is set up. > *... > ... > * I would guess you could make this function return back into the > * programme by having it call a assembly function that would pop an > * appropiate number off the stack and then execute an "iret". (messy) > * > * BUGS: > * Because we don't disable the interupts, if an interupt occurs while > * the programme is in the middle of stuffing the new or old address, your > * up the creek. > * Also do not change the vector to the BIOS ^C vector (1Ah). It seems > * that DOS has a go at the keyboard break first and so it exits leaving > * the modified vector unrestored. > * > * This source is complier dependent. It was written for the Microsoft > * C Compiler 4.0. And it goes without saying, it is VERY DOS dependent. > * > * At this point there is a complie waring at "funcp = bye;" in the > * main function. But everything works perfectly. Has anyone any ideas > * on how to make this compile cleanly? > * > >main() >{ >char far *funcp; >unsigned int off; >unsigned int seg; > > funcp = bye; > off = FP_OFF(funcp); > seg = FP_SEG(funcp); > > set_int(CNTLBK,seg,off); > > printf("bye() is located at %04X:%04X.\n",seg,off); > printf("The breakint was located at %04X:%04X.\n",pvseg,pvoff); > > sleep(20); > printf("No keyboard break. Exiting normally.\n"); > bye(); >} First off, I suspect that our program would compile correctl if you declare your function as: char far *funcp(); Secondly, while you really shouldn't have to disable interrupts while swapping interrupt vectors, I'm the nervous type that believes that its safer. Typically, you sway vectors at program initialization or termination, at this time who cares if interrupts are off for a few hundred instructions. Third, if you are doing communications, NETBIOS as an example, ou may get a CTL-C or CTL-Break while in the middle of issueing a request. NETBIOS commands that wait do not return control to you until the have completed, this may be a 1 second delay on a LAN. In my situations, using NETBIOS over a WAN TCP network, a NETBIOS command can block for up to one minute in some circumstances. This is a long time to wait for Control C/Break. In this situation, or other lie it, you absolutely have to intercept INT 9 (KBD), test for various nasty keystrokes, (CTL-C/BREAK, or CTL-ALT-DEL), and if one of those keystrokes is seen, do some immediate housecleaning, BUT GET YOURSELF BACK TO YOUR CODE THAT WAS EXECUTING BEFORE THE INTERRUPT OCCURRED!!!!! The UNIX setjmp/longjmp game does not work properly in DOS communications programs. My code looks something like this: main() { open a NETBIOS connection; while (1) { if (break_flag) break; send_data(); receive_data(); if (done) break; } close NETBIOS connection(); } and my keyboard interrupt handler. (Written in assembly in reality) int_9_handler() { test_for_ctl_c() test_for_ctl_alt_del() if (ctl_c || ctl_break) { send_netbios_cancel(); break_flag = TRUE; } else if( ctl_alt_del) { send_netbios_cnacel(); } push flags call far old_int_9_handler(); iret; } The important thing in these lousy little fragments is the concept of cleaning up after yourself, not just in your machine, but in your LAN or WAN environment. If you don't do your communications cleanup correctly, you leave hung sockets, ports, sessions, or whatever on the other end of your communication line. Larry Backman Micom - Interlan, Inc.