diff options
Diffstat (limited to 'private/mvdm/wow16/toolhelp/int1.c')
-rw-r--r-- | private/mvdm/wow16/toolhelp/int1.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/private/mvdm/wow16/toolhelp/int1.c b/private/mvdm/wow16/toolhelp/int1.c new file mode 100644 index 000000000..3acd50307 --- /dev/null +++ b/private/mvdm/wow16/toolhelp/int1.c @@ -0,0 +1,153 @@ +/************************************************************************** + * INT1.C + * + * Routines used to implement the interrupt trapping API in + * TOOLHELP.DLL + * + **************************************************************************/ + +#include <string.h> +#include "toolpriv.h" + +/* ----- Global variables ----- */ + WORD wIntInstalled; + INTERRUPT NEAR *npIntHead; + +/* InterruptRegister + * Registers an interrupt callback. + */ + +BOOL TOOLHELPAPI InterruptRegister( + HANDLE hTask, + FARPROC lpfnCallback) +{ + INTERRUPT *pInt; + INTERRUPT *pTemp; + + /* Make sure TOOLHELP.DLL is installed */ + if (!wLibInstalled) + return FALSE; + + /* If the interrupt hook has not yet been installed, install it */ + if (!wIntInstalled) + { + /* Make sure we can hook! */ + if (!InterruptInit()) + return FALSE; + wIntInstalled = TRUE; + } + + /* NULL hTask means current task */ + if (!hTask) + hTask = GetCurrentTask(); + + /* Register a death signal handler for this task (does nothing if one + * is already installed. + */ + SignalRegister(hTask); + + /* Check to see if this task is already registered */ + for (pInt = npIntHead ; pInt ; pInt = pInt->pNext) + if (pInt->hTask == hTask) + return FALSE; + + /* Allocate a new INTERRUPT structure */ + pInt = (INTERRUPT *)LocalAlloc(LMEM_FIXED, sizeof (INTERRUPT)); + if (!pInt) + return FALSE; + + /* Fill in the useful fields */ + pInt->hTask = hTask; + pInt->lpfn = lpfnCallback; + + /* If this is the only handler, just insert it */ + if (!npIntHead) + { + pInt->pNext = npIntHead; + npIntHead = pInt; + } + + /* Otherwise, insert at the end of the list */ + else + { + for (pTemp = npIntHead ; pTemp->pNext ; pTemp = pTemp->pNext) + ; + pInt->pNext = pTemp->pNext; + pTemp->pNext = pInt; + } + + return TRUE; +} + + +/* InterruptUnRegister + * Called by an app whose callback is no longer to be used. + * NULL hTask uses current task. + */ + +BOOL TOOLHELPAPI InterruptUnRegister( + HANDLE hTask) +{ + INTERRUPT *pInt; + INTERRUPT *pBefore; + + /* Make sure we have interrupt installed and that TOOLHELP is OK */ + if (!wLibInstalled || !wIntInstalled) + return FALSE; + + /* NULL hTask means current task */ + if (!hTask) + hTask = GetCurrentTask(); + + /* First try to find the task */ + pBefore = NULL; + for (pInt = npIntHead ; pInt ; pInt = pInt->pNext) + if (pInt->hTask == hTask) + break; + else + pBefore = pInt; + if (!pInt) + return FALSE; + + /* Unhook the death signal proc only if there is no interrupt handler */ + if (!NotifyIsHooked(hTask)) + SignalUnRegister(hTask); + + /* Remove it from the list */ + if (!pBefore) + npIntHead = pInt->pNext; + else + pBefore->pNext = pInt->pNext; + + /* Free the structure */ + LocalFree((HANDLE)pInt); + + /* If there are no more handlers, unhook the callback */ + if (!npIntHead) + { + InterruptUnInit(); + wIntInstalled = FALSE; + } + + return TRUE; +} + +/* ----- Helper functions ----- */ + +/* InterruptIsHooked + * Returns TRUE iff the parameter task already has a interrupt hook. + */ + +BOOL PASCAL InterruptIsHooked( + HANDLE hTask) +{ + INTERRUPT *pInt; + + /* Loop thorugh all interrupts */ + for (pInt = npIntHead ; pInt ; pInt = pInt->pNext) + if (pInt->hTask == hTask) + break; + + /* Return found/not found */ + return (BOOL)pInt; +} |