summaryrefslogtreecommitdiffstats
path: root/private/mvdm/wow16/toolhelp/int1.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/wow16/toolhelp/int1.c')
-rw-r--r--private/mvdm/wow16/toolhelp/int1.c153
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;
+}