Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
3.5 KiB

  1. /**************************************************************************
  2. * INT1.C
  3. *
  4. * Routines used to implement the interrupt trapping API in
  5. * TOOLHELP.DLL
  6. *
  7. **************************************************************************/
  8. #include <string.h>
  9. #include "toolpriv.h"
  10. /* ----- Global variables ----- */
  11. WORD wIntInstalled;
  12. INTERRUPT NEAR *npIntHead;
  13. /* InterruptRegister
  14. * Registers an interrupt callback.
  15. */
  16. BOOL TOOLHELPAPI InterruptRegister(
  17. HANDLE hTask,
  18. FARPROC lpfnCallback)
  19. {
  20. INTERRUPT *pInt;
  21. INTERRUPT *pTemp;
  22. /* Make sure TOOLHELP.DLL is installed */
  23. if (!wLibInstalled)
  24. return FALSE;
  25. /* If the interrupt hook has not yet been installed, install it */
  26. if (!wIntInstalled)
  27. {
  28. /* Make sure we can hook! */
  29. if (!InterruptInit())
  30. return FALSE;
  31. wIntInstalled = TRUE;
  32. }
  33. /* NULL hTask means current task */
  34. if (!hTask)
  35. hTask = GetCurrentTask();
  36. /* Register a death signal handler for this task (does nothing if one
  37. * is already installed.
  38. */
  39. SignalRegister(hTask);
  40. /* Check to see if this task is already registered */
  41. for (pInt = npIntHead ; pInt ; pInt = pInt->pNext)
  42. if (pInt->hTask == hTask)
  43. return FALSE;
  44. /* Allocate a new INTERRUPT structure */
  45. pInt = (INTERRUPT *)LocalAlloc(LMEM_FIXED, sizeof (INTERRUPT));
  46. if (!pInt)
  47. return FALSE;
  48. /* Fill in the useful fields */
  49. pInt->hTask = hTask;
  50. pInt->lpfn = (LPFNCALLBACK) lpfnCallback;
  51. /* If this is the only handler, just insert it */
  52. if (!npIntHead)
  53. {
  54. pInt->pNext = npIntHead;
  55. npIntHead = pInt;
  56. }
  57. /* Otherwise, insert at the end of the list */
  58. else
  59. {
  60. for (pTemp = npIntHead ; pTemp->pNext ; pTemp = pTemp->pNext)
  61. ;
  62. pInt->pNext = pTemp->pNext;
  63. pTemp->pNext = pInt;
  64. }
  65. return TRUE;
  66. }
  67. /* InterruptUnRegister
  68. * Called by an app whose callback is no longer to be used.
  69. * NULL hTask uses current task.
  70. */
  71. BOOL TOOLHELPAPI InterruptUnRegister(
  72. HANDLE hTask)
  73. {
  74. INTERRUPT *pInt;
  75. INTERRUPT *pBefore;
  76. /* Make sure we have interrupt installed and that TOOLHELP is OK */
  77. if (!wLibInstalled || !wIntInstalled)
  78. return FALSE;
  79. /* NULL hTask means current task */
  80. if (!hTask)
  81. hTask = GetCurrentTask();
  82. /* First try to find the task */
  83. pBefore = NULL;
  84. for (pInt = npIntHead ; pInt ; pInt = pInt->pNext)
  85. if (pInt->hTask == hTask)
  86. break;
  87. else
  88. pBefore = pInt;
  89. if (!pInt)
  90. return FALSE;
  91. /* Unhook the death signal proc only if there is no interrupt handler */
  92. if (!NotifyIsHooked(hTask))
  93. SignalUnRegister(hTask);
  94. /* Remove it from the list */
  95. if (!pBefore)
  96. npIntHead = pInt->pNext;
  97. else
  98. pBefore->pNext = pInt->pNext;
  99. /* Free the structure */
  100. LocalFree((HANDLE)pInt);
  101. /* If there are no more handlers, unhook the callback */
  102. if (!npIntHead)
  103. {
  104. InterruptUnInit();
  105. wIntInstalled = FALSE;
  106. }
  107. return TRUE;
  108. }
  109. /* ----- Helper functions ----- */
  110. /* InterruptIsHooked
  111. * Returns TRUE iff the parameter task already has a interrupt hook.
  112. */
  113. BOOL PASCAL InterruptIsHooked(
  114. HANDLE hTask)
  115. {
  116. INTERRUPT *pInt;
  117. /* Loop thorugh all interrupts */
  118. for (pInt = npIntHead ; pInt ; pInt = pInt->pNext)
  119. if (pInt->hTask == hTask)
  120. break;
  121. /* Return found/not found */
  122. return (BOOL)pInt;
  123. }