111 lines
2.7 KiB
C
111 lines
2.7 KiB
C
|
/**************************************************************************
|
||
|
* SIGNAL.C
|
||
|
*
|
||
|
* Routines used to clean up on a forced KERNEL termination of a
|
||
|
* TOOLHELP using app.
|
||
|
*
|
||
|
**************************************************************************/
|
||
|
|
||
|
#include <string.h>
|
||
|
#include "toolpriv.h"
|
||
|
|
||
|
/* ----- Global variables ----- */
|
||
|
WORD wSignalInstalled;
|
||
|
SIGNAL NEAR *npSignalHead;
|
||
|
|
||
|
/* SignalRegister
|
||
|
* Registers a default signal proc to a task. This signal proc is
|
||
|
* called when the task is about to be terminated and is called before
|
||
|
* the USER signal proc is called. The registered callback is
|
||
|
* called HelperSignalProc() [HELPER.ASM] and chains to the USER signal
|
||
|
* proc (if any) instead of returning.
|
||
|
*/
|
||
|
|
||
|
BOOL PASCAL SignalRegister(
|
||
|
HANDLE hTask)
|
||
|
{
|
||
|
SIGNAL *pSig;
|
||
|
SIGNAL *pTemp;
|
||
|
|
||
|
/* NULL hTask means current task */
|
||
|
if (!hTask)
|
||
|
hTask = GetCurrentTask();
|
||
|
|
||
|
/* Check to see if this task is already registered */
|
||
|
for (pSig = npSignalHead ; pSig ; pSig = pSig->pNext)
|
||
|
if (pSig->hTask == hTask)
|
||
|
return FALSE;
|
||
|
|
||
|
/* Allocate a new SIGNAL structure */
|
||
|
pSig = (SIGNAL *)LocalAlloc(LMEM_FIXED, sizeof (SIGNAL));
|
||
|
if (!pSig)
|
||
|
return FALSE;
|
||
|
|
||
|
/* Fill in the useful fields */
|
||
|
pSig->hTask = hTask;
|
||
|
pSig->lpfn = (LPFNCALLBACK)HelperSignalProc;
|
||
|
pSig->lpfnOld = (LPFNCALLBACK)
|
||
|
HelperSetSignalProc(hTask, (DWORD)HelperSignalProc);
|
||
|
|
||
|
/* If this is the only handler, just insert it */
|
||
|
if (!npSignalHead)
|
||
|
{
|
||
|
pSig->pNext = npSignalHead;
|
||
|
npSignalHead = pSig;
|
||
|
}
|
||
|
|
||
|
/* Otherwise, insert at the end of the list */
|
||
|
else
|
||
|
{
|
||
|
for (pTemp = npSignalHead ; pTemp->pNext ; pTemp = pTemp->pNext)
|
||
|
;
|
||
|
pSig->pNext = pTemp->pNext;
|
||
|
pTemp->pNext = pSig;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* SignalUnRegister
|
||
|
* Called by an app whose callback is no longer to be used.
|
||
|
* NULL hTask uses current task.
|
||
|
*/
|
||
|
|
||
|
BOOL PASCAL SignalUnRegister(
|
||
|
HANDLE hTask)
|
||
|
{
|
||
|
SIGNAL *pSig;
|
||
|
SIGNAL *pBefore;
|
||
|
|
||
|
/* NULL hTask means current task */
|
||
|
if (!hTask)
|
||
|
hTask = GetCurrentTask();
|
||
|
|
||
|
/* First try to find the task */
|
||
|
pBefore = NULL;
|
||
|
for (pSig = npSignalHead ; pSig ; pSig = pSig->pNext)
|
||
|
if (pSig->hTask == hTask)
|
||
|
break;
|
||
|
else
|
||
|
pBefore = pSig;
|
||
|
if (!pSig)
|
||
|
return FALSE;
|
||
|
|
||
|
/* Remove it from the list */
|
||
|
if (!pBefore)
|
||
|
npSignalHead = pSig->pNext;
|
||
|
else
|
||
|
pBefore->pNext = pSig->pNext;
|
||
|
|
||
|
/* Replace the old signal proc */
|
||
|
HelperSetSignalProc(hTask, (DWORD)pSig->lpfnOld);
|
||
|
|
||
|
/* Free the structure */
|
||
|
LocalFree((HANDLE)pSig);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|