Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ctrlc.c File Reference

#include "precomp.h"

Go to the source code of this file.

Defines

#define LIST_INCREMENT   2
#define INITIAL_LIST_SIZE   1
#define NUMBER_OF_CTRL_EVENTS   7
#define SYSTEM_CLOSE_EVENT   4
#define IGNORE_CTRL_C   0x01

Functions

BOOL DefaultHandler (IN ULONG CtrlType)
NTSTATUS InitializeCtrlHandling (VOID)
DWORD CtrlRoutine (IN LPVOID lpThreadParameter)
VOID APIENTRY SetLastConsoleEventActiveInternal (VOID)
 defined(BUILD_WOW64)

VOID APIENTRY SetLastConsoleEventActive (VOID)
 defined(BUILD_WOW6432)

BOOL SetCtrlHandler (IN PHANDLER_ROUTINE HandlerRoutine)
BOOL RemoveCtrlHandler (IN PHANDLER_ROUTINE HandlerRoutine)
BOOL APIENTRY SetConsoleCtrlHandler (IN PHANDLER_ROUTINE HandlerRoutine, IN BOOL Add)

Variables

PHANDLER_ROUTINE SingleHandler [INITIAL_LIST_SIZE]
ULONG HandlerListLength
ULONG AllocatedHandlerListLength
PHANDLER_ROUTINE * HandlerList
BOOL LastConsoleEventActive


Define Documentation

#define IGNORE_CTRL_C   0x01
 

Definition at line 37 of file ctrlc.c.

Referenced by CtrlRoutine(), and SetCtrlHandler().

#define INITIAL_LIST_SIZE   1
 

Definition at line 27 of file ctrlc.c.

Referenced by InitializeCtrlHandling().

#define LIST_INCREMENT   2
 

Definition at line 26 of file ctrlc.c.

Referenced by SetCtrlHandler().

#define NUMBER_OF_CTRL_EVENTS   7
 

Definition at line 34 of file ctrlc.c.

Referenced by CtrlRoutine().

#define SYSTEM_CLOSE_EVENT   4
 

Definition at line 35 of file ctrlc.c.

Referenced by CtrlRoutine().


Function Documentation

DWORD CtrlRoutine IN LPVOID  lpThreadParameter  ) 
 

Definition at line 93 of file ctrlc.c.

References ASSERT, DefaultHandler(), DWORD, EXCEPTION_EXECUTE_HANDLER, HandlerList, HandlerListLength, IGNORE_CTRL_C, LastConsoleEventActive, LockDll, NULL, NUMBER_OF_CTRL_EVENTS, RtlRaiseException(), SYSTEM_CLOSE_EVENT, and UnlockDll.

00099 : 00100 00101 This thread is created when ctrl-c or ctrl-break is entered, 00102 or when close is selected. it calls the appropriate handlers. 00103 00104 Arguments: 00105 00106 lpThreadParameter - what type of event happened. 00107 00108 Return Value: 00109 00110 STATUS_SUCCESS 00111 00112 --*/ 00113 00114 { 00115 ULONG i; 00116 ULONG EventNumber,OriginalEventNumber; 00117 DWORD fNoExit; 00118 DWORD dwExitCode; 00119 EXCEPTION_RECORD ExceptionRecord; 00120 00121 SetThreadPriority(NtCurrentThread(), THREAD_PRIORITY_HIGHEST); 00122 OriginalEventNumber = EventNumber = PtrToUlong(lpThreadParameter); 00123 00124 // 00125 // If this bit is set, it means we don't want to cause this process 00126 // to exit itself if it is a logoff or shutdown event. 00127 // 00128 fNoExit = 0x80000000 & EventNumber; 00129 EventNumber &= ~0x80000000; 00130 00131 // 00132 // the ctrl_close event is set when the user selects the window 00133 // close option from the system menu, or EndTask, or Settings-Terminate. 00134 // the system close event is used when another ctrl-thread times out. 00135 // 00136 00137 switch (EventNumber) { 00138 default: 00139 ASSERT (EventNumber < NUMBER_OF_CTRL_EVENTS); 00140 if (EventNumber >= NUMBER_OF_CTRL_EVENTS) 00141 return (DWORD)STATUS_UNSUCCESSFUL; 00142 break; 00143 00144 case CTRL_C_EVENT: 00145 case CTRL_BREAK_EVENT: 00146 // 00147 // If the process is being debugged, give the debugger 00148 // a shot. If the debugger handles the exception, then 00149 // go back and wait. 00150 // 00151 00152 if (!IsDebuggerPresent()) 00153 break; 00154 00155 if ( EventNumber == CTRL_C_EVENT ) { 00156 ExceptionRecord.ExceptionCode = DBG_CONTROL_C; 00157 } 00158 else { 00159 ExceptionRecord.ExceptionCode = DBG_CONTROL_BREAK; 00160 } 00161 ExceptionRecord.ExceptionFlags = 0; 00162 ExceptionRecord.ExceptionRecord = NULL; 00163 ExceptionRecord.ExceptionAddress = (PVOID)DefaultHandler; 00164 ExceptionRecord.NumberParameters = 0; 00165 00166 try { 00167 RtlRaiseException(&ExceptionRecord); 00168 } except (EXCEPTION_EXECUTE_HANDLER) { 00169 LockDll(); 00170 try { 00171 if (EventNumber != CTRL_C_EVENT || 00172 NtCurrentPeb()->ProcessParameters->ConsoleFlags != IGNORE_CTRL_C) { 00173 for (i=HandlerListLength;i>0;i--) { 00174 if ((HandlerList[i-1])(EventNumber)) { 00175 break; 00176 } 00177 } 00178 } 00179 } finally { 00180 UnlockDll(); 00181 } 00182 } 00183 ExitThread(0); 00184 break; 00185 00186 case SYSTEM_CLOSE_EVENT: 00187 ExitProcess((DWORD)CONTROL_C_EXIT); 00188 break; 00189 00190 case SYSTEM_ROOT_CONSOLE_EVENT: 00191 if (!LastConsoleEventActive) 00192 ExitThread(0); 00193 break; 00194 00195 case CTRL_CLOSE_EVENT: 00196 case CTRL_LOGOFF_EVENT: 00197 case CTRL_SHUTDOWN_EVENT: 00198 //if (LastConsoleEventActive) 00199 //EventNumber = SYSTEM_ROOT_CONSOLE_EVENT; 00200 break; 00201 } 00202 00203 LockDll(); 00204 dwExitCode = 0; 00205 try { 00206 if (EventNumber != CTRL_C_EVENT || 00207 NtCurrentPeb()->ProcessParameters->ConsoleFlags != IGNORE_CTRL_C) { 00208 for (i=HandlerListLength;i>0;i--) { 00209 00210 // 00211 // Don't call the last handler (the default one which calls 00212 // ExitProcess() if this process isn't supposed to exit (system 00213 // process are not supposed to exit because of shutdown or 00214 // logoff event notification). 00215 // 00216 00217 if ((i-1) == 0 && fNoExit) { 00218 if (EventNumber == CTRL_LOGOFF_EVENT || 00219 EventNumber == CTRL_SHUTDOWN_EVENT) { 00220 break; 00221 } 00222 } 00223 00224 if ((HandlerList[i-1])(EventNumber)) { 00225 switch (EventNumber) { 00226 case CTRL_CLOSE_EVENT: 00227 case CTRL_LOGOFF_EVENT: 00228 case CTRL_SHUTDOWN_EVENT: 00229 case SYSTEM_ROOT_CONSOLE_EVENT: 00230 dwExitCode = OriginalEventNumber; 00231 break; 00232 } 00233 break; 00234 } 00235 } 00236 } 00237 } finally { 00238 UnlockDll(); 00239 } 00240 ExitThread(dwExitCode); 00241 return STATUS_SUCCESS; 00242 }

BOOL DefaultHandler IN ULONG  CtrlType  ) 
 

Definition at line 43 of file ctrlc.c.

References DWORD, and TRUE.

Referenced by CtrlRoutine(), and InitializeCtrlHandling().

00051 : 00052 00053 CtrlType - type of ctrl event (ctrl-c, ctrl-break). 00054 00055 Return Value: 00056 00057 none. 00058 00059 --*/ 00060 00061 { 00062 ExitProcess((DWORD)CONTROL_C_EXIT); 00063 return TRUE; 00064 UNREFERENCED_PARAMETER(CtrlType); 00065 }

NTSTATUS InitializeCtrlHandling VOID   ) 
 

Definition at line 68 of file ctrlc.c.

References AllocatedHandlerListLength, DefaultHandler(), HandlerList, HandlerListLength, INITIAL_LIST_SIZE, and SingleHandler.

Referenced by AllocConsole(), and ConDllInitialize().

00075 : 00076 00077 none. 00078 00079 Return Value: 00080 00081 none. 00082 00083 --*/ 00084 00085 { 00086 AllocatedHandlerListLength = HandlerListLength = INITIAL_LIST_SIZE; 00087 HandlerList = SingleHandler; 00088 SingleHandler[0] = DefaultHandler; 00089 return STATUS_SUCCESS; 00090 }

BOOL RemoveCtrlHandler IN PHANDLER_ROUTINE  HandlerRoutine  ) 
 

Definition at line 368 of file ctrlc.c.

References FALSE, HandlerList, HandlerListLength, SET_LAST_ERROR, and TRUE.

Referenced by SetConsoleCtrlHandler().

00374 : 00375 00376 This routine removes a ctrl handler from the process's list. 00377 00378 Arguments: 00379 00380 HandlerRoutine - pointer to ctrl handler. 00381 00382 Return Value: 00383 00384 TRUE - success. 00385 00386 --*/ 00387 00388 { 00389 ULONG i; 00390 00391 // 00392 // NULL handler routine is not stored in table. It is 00393 // used to temporarily inhibit ^C event handling. Removing 00394 // this handler allows normal processing to occur 00395 // 00396 00397 if ( !HandlerRoutine ) { 00398 NtCurrentPeb()->ProcessParameters->ConsoleFlags = 0; 00399 return TRUE; 00400 } 00401 00402 for (i=0;i<HandlerListLength;i++) { 00403 if (*(HandlerList+i) == HandlerRoutine) { 00404 if (i < (HandlerListLength-1)) { 00405 memmove(&HandlerList[i],&HandlerList[i+1],sizeof(PHANDLER_ROUTINE) * (HandlerListLength - i - 1)); 00406 } 00407 HandlerListLength -= 1; 00408 return TRUE; 00409 } 00410 } 00411 SET_LAST_ERROR(ERROR_INVALID_PARAMETER); 00412 return FALSE; 00413 }

BOOL APIENTRY SetConsoleCtrlHandler IN PHANDLER_ROUTINE  HandlerRoutine,
IN BOOL  Add
 

Definition at line 417 of file ctrlc.c.

References BOOL, LockDll, RemoveCtrlHandler(), SetCtrlHandler(), and UnlockDll.

00424 : 00425 00426 This routine adds or removes a ctrl handler from the process's list. 00427 00428 Arguments: 00429 00430 HandlerRoutine - pointer to ctrl handler. 00431 00432 Add - if TRUE, add handler. else remove. 00433 00434 Return Value: 00435 00436 TRUE - success. 00437 00438 --*/ 00439 00440 { 00441 BOOL Success; 00442 00443 LockDll(); 00444 if (Add) { 00445 Success = SetCtrlHandler(HandlerRoutine); 00446 } 00447 else { 00448 Success = RemoveCtrlHandler(HandlerRoutine); 00449 } 00450 UnlockDll(); 00451 return Success; 00452 }

BOOL SetCtrlHandler IN PHANDLER_ROUTINE  HandlerRoutine  ) 
 

Definition at line 297 of file ctrlc.c.

References AllocatedHandlerListLength, ASSERT, FALSE, HandlerList, HandlerListLength, IGNORE_CTRL_C, LIST_INCREMENT, RtlAllocateHeap, RtlFreeHeap, SET_LAST_ERROR, SingleHandler, and TRUE.

Referenced by SetConsoleCtrlHandler().

00303 : 00304 00305 This routine adds a ctrl handler to the process's list. 00306 00307 Arguments: 00308 00309 HandlerRoutine - pointer to ctrl handler. 00310 00311 Return Value: 00312 00313 TRUE - success. 00314 00315 --*/ 00316 00317 { 00318 PHANDLER_ROUTINE *NewHandlerList; 00319 00320 // 00321 // NULL handler routine is not stored in table. It is 00322 // used to temporarily inhibit ^C event handling 00323 // 00324 00325 if ( !HandlerRoutine ) { 00326 NtCurrentPeb()->ProcessParameters->ConsoleFlags = IGNORE_CTRL_C; 00327 return TRUE; 00328 } 00329 00330 if (HandlerListLength == AllocatedHandlerListLength) { 00331 00332 // 00333 // grow list 00334 // 00335 00336 NewHandlerList = (PHANDLER_ROUTINE *) RtlAllocateHeap( RtlProcessHeap(), 0, 00337 sizeof(PHANDLER_ROUTINE) * (HandlerListLength + LIST_INCREMENT)); 00338 if (!NewHandlerList) { 00339 SET_LAST_ERROR(ERROR_NOT_ENOUGH_MEMORY); 00340 return FALSE; 00341 } 00342 00343 // 00344 // copy list 00345 // 00346 00347 RtlCopyMemory(NewHandlerList,HandlerList,sizeof(PHANDLER_ROUTINE) * HandlerListLength); 00348 00349 if (HandlerList != SingleHandler) { 00350 00351 // 00352 // free old list 00353 // 00354 00355 RtlFreeHeap(RtlProcessHeap(), 0, HandlerList); 00356 } 00357 HandlerList = NewHandlerList; 00358 AllocatedHandlerListLength += LIST_INCREMENT; 00359 } 00360 ASSERT (HandlerListLength < AllocatedHandlerListLength); 00361 00362 HandlerList[HandlerListLength] = HandlerRoutine; 00363 HandlerListLength++; 00364 return TRUE; 00365 }

VOID APIENTRY SetLastConsoleEventActive VOID   ) 
 

defined(BUILD_WOW6432)

Definition at line 288 of file ctrlc.c.

References LastConsoleEventActive, SetLastConsoleEventActiveInternal(), and TRUE.

00290 { 00291 00292 LastConsoleEventActive = TRUE; 00293 SetLastConsoleEventActiveInternal(); 00294 }

VOID APIENTRY SetLastConsoleEventActiveInternal VOID   ) 
 

defined(BUILD_WOW64)

Definition at line 250 of file ctrlc.c.

References _CONSOLE_NOTIFYLASTCLOSE_MSG::ConsoleHandle, ConsolepNotifyLastClose, CsrClientCallServer(), GET_CONSOLE_HANDLE, NULL, and _CONSOLE_API_MSG::u.

Referenced by SetLastConsoleEventActive().

00254 : 00255 00256 Sends a ConsolepNotifyLastClose command to the server. 00257 00258 Arguments: 00259 00260 none. 00261 00262 Return Value: 00263 00264 None. 00265 00266 --*/ 00267 00268 { 00269 CONSOLE_API_MSG m; 00270 PCONSOLE_NOTIFYLASTCLOSE_MSG a = &m.u.SetLastConsoleEventActive; 00271 00272 a->ConsoleHandle = GET_CONSOLE_HANDLE; 00273 CsrClientCallServer( (PCSR_API_MSG)&m, 00274 NULL, 00275 CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX, 00276 ConsolepNotifyLastClose 00277 ), 00278 sizeof( *a ) 00279 ); 00280 }


Variable Documentation

ULONG AllocatedHandlerListLength
 

Definition at line 31 of file ctrlc.c.

Referenced by InitializeCtrlHandling(), and SetCtrlHandler().

PHANDLER_ROUTINE* HandlerList
 

Definition at line 32 of file ctrlc.c.

Referenced by CtrlRoutine(), InitializeCtrlHandling(), Psp386InsertVdmIoHandlerBlock(), RemoveCtrlHandler(), and SetCtrlHandler().

ULONG HandlerListLength
 

Definition at line 30 of file ctrlc.c.

Referenced by CtrlRoutine(), InitializeCtrlHandling(), RemoveCtrlHandler(), and SetCtrlHandler().

BOOL LastConsoleEventActive
 

Definition at line 39 of file ctrlc.c.

Referenced by CtrlRoutine(), and SetLastConsoleEventActive().

PHANDLER_ROUTINE SingleHandler[INITIAL_LIST_SIZE]
 

Definition at line 29 of file ctrlc.c.

Referenced by InitializeCtrlHandling(), and SetCtrlHandler().


Generated on Sat May 15 19:43:21 2004 for test by doxygen 1.3.7