Sunday 20 November 2011

How do you disable Ctrl-Break? in C programming

How do you disable Ctrl-Break?

There are several ways to disable the Ctrl-Break function. I will discuss two popular techniques for accomplishing this task.

The first technique is to use DOS to disable Ctrl-Break. DOS interrupt 0x21, function 0x33 enables you to get and set the Ctrl-Break check flag, that is, the flag that tells DOS whether to process the Ctrl-Break keys when they are pressed. The following example illustrates this method:

#include <stdio.h>
#include <dos.h>
void main(int argc, char ** argv)
{
union REGS regs;
int ctrlBreakFlag;
/* find out the current state of the flag */
regs.x.ax = 0x3300; /* subfunction 0 gets flag state */
int86(0x21, &regs, &regs);
ctrlBreakFlag = regs.h.dl; /* save flag value from DL */
/* set the state of the flag to disable Ctrl-Break */
regs.x.ax = 0x3301;
regs.h.dl = 0; /* disable checking */
int86(0x21, &regs, &regs); /* subfunction 1 sets flag state */
}

In the preceding example, DOS was called to query the current state of the Ctrl-Break check flag, which was
saved into ctrlBreakFlag. The return value from the DOS call, found in DL, will be 0 if Ctrl-Break checking is disabled, and 1 if checking is enabled. Next, the code clears DL and calls the DOS Set Ctrl-Break flag function to disable Ctrl-Break checking. This will be true until it is reset again by another call to this function. Not shown in the preceding example is subfunction 02 (AX = 0x3302), which simultaneously gets and sets the state of the Ctrl-Break flag. To perform this task, put 0x3302 into AX, put the desired Ctrl-Break state  in DL, do the interrupt, and save the previous state from DL into ctrlBreakFlag. 

The second major method is to use a signal. A signal is a carryover from the old UNIX days (hey, I’m not that old!). The purpose of the signal function is to allow the programmer to be called when certain events occur. One of these events is the user interruption, or Ctrl-Break in DOS-land. The next example demonstrates how to use the Microsoft signal() function to trap and act on the Ctrl-Break event (assume that Ctrl-Break checking is enabled):

#include <stdio.h>
#include <signal.h>
int exitHandler(void);
int main(int argc, char ** argv)
{
int quitFlag = 0;
/* Trap all Ctrl-Breaks */
signal(SIGINT, (void (__cdecl *)(int))exitHandler);
/* Sit in infinite loop until user presses Ctrl-Break */
while(quitFlag == 0)
printf(“%s\n”, (argc > 1) ? argv[1] : “Waiting for Ctrl-Break”);
}
/* Ctrl-Break event handler function */
int exitHandler()
{
char ch;
/* Disable Ctrl-Break handling while inside the handler */
signal(SIGINT, SIG_IGN);
/* Since it was an “interrupt,” clear keyboard input buffer */
fflush( stdin );
/* Ask if user really wants to quit program */
printf(“\nCtrl-Break occurred. Do you wish to exit this program?
å(Y or N) “);
/* Flush output buffer as well */
fflush(stdout);
/* Get input from user, print character and newline */
ch = getche();
printf(“\n”);
/* If user said yes, leave program */
if(toupper(ch) == ‘Y’)
exit(0);
/* Reenable Ctrl-Break handling */
signal(SIGINT, (void (__cdecl *)(int))exitHandler);
return(0);
}

The beauty of this example is that you have a function that gets called every time Ctrl-Break is pressed. This means you have the choice of what you want to do. You can ignore the event, which is essentially “disabling”
Ctrl-Break. Or you can act on it in any way you want. Another advantage to this method is that when your program exits, normal operation of Ctrl-Break resumes without manual intervention.

Cross Reference:

XX.17: Can you disable warm boots (Ctrl-Alt-Delete)?

No comments:

Post a Comment