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.
|
|
/**************************************************************************
* NOTIFY1.C * * Routines used to implement the Debugger Notification API in * TOOLHELP.DLL * **************************************************************************/
#include <string.h>
#include "toolpriv.h"
/* ----- Global variables ----- */ WORD wNotifyInstalled; NOTIFYSTRUCT NEAR *npNotifyHead; NOTIFYSTRUCT NEAR *npNotifyNext;
/* NotifyRegister
* Registers a debugger notification callback. This callback will * be called whenever KERNEL has a notification to be sent. * The format of the call to the callback function is documented * elsewhere. */
BOOL TOOLHELPAPI NotifyRegister( HANDLE hTask, LPFNNOTIFYCALLBACK lpfn, WORD wFlags) { NOTIFYSTRUCT *pInfo; NOTIFYSTRUCT *pTemp;
/* Make sure TOOLHELP.DLL is installed */ if (!wLibInstalled) return FALSE;
/* If the notification hook has not yet been installed, install it */ if (!wNotifyInstalled) { /* Make sure we can get a hook! */ if (!NotifyInit()) return FALSE; wNotifyInstalled = 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 (pInfo = npNotifyHead ; pInfo ; pInfo = pInfo->pNext) if (pInfo->hTask == hTask) return FALSE;
/* Allocate a new NOTIFYSTRUCT structure */ pInfo = (NOTIFYSTRUCT *)LocalAlloc(LMEM_FIXED, sizeof (NOTIFYSTRUCT)); if (!pInfo) return FALSE;
/* Fill in the useful fields */ pInfo->hTask = hTask; pInfo->wFlags = wFlags; pInfo->lpfn = lpfn;
/* If this is the only handler, just insert it */ if (!npNotifyHead) { pInfo->pNext = npNotifyHead; npNotifyHead = pInfo; }
/* Otherwise, insert at the end of the list */ else { for (pTemp = npNotifyHead ; pTemp->pNext ; pTemp = pTemp->pNext) ; pInfo->pNext = pTemp->pNext; pTemp->pNext = pInfo; }
return TRUE; }
/* NotifyUnRegister
* Called by an app whose callback is no longer to be used. * NULL hTask uses current task. */
BOOL TOOLHELPAPI NotifyUnRegister( HANDLE hTask) { NOTIFYSTRUCT *pNotify; NOTIFYSTRUCT *pBefore;
/* Make sure we have notifications installed and that TOOLHELP is OK */ if (!wLibInstalled || !wNotifyInstalled) return FALSE;
/* NULL hTask means current task */ if (!hTask) hTask = GetCurrentTask();
/* First try to find the task */ pBefore = NULL; for (pNotify = npNotifyHead ; pNotify ; pNotify = pNotify->pNext) if (pNotify->hTask == hTask) break; else pBefore = pNotify; if (!pNotify) return FALSE;
/* Unhook the death signal proc only if there is no interrupt handler */ if (!InterruptIsHooked(hTask)) SignalUnRegister(hTask);
/* Check to see if the notification handler is about to use this entry.
* If it is, we point it to the next one, if any. */ if (npNotifyNext == pNotify) npNotifyNext = pNotify->pNext;
/* Remove it from the list */ if (!pBefore) npNotifyHead = pNotify->pNext; else pBefore->pNext = pNotify->pNext;
/* Free the structure */ LocalFree((HANDLE)pNotify);
/* If there are no more handlers, unhook the callback */ if (!npNotifyHead) { NotifyUnInit(); wNotifyInstalled = FALSE; }
return TRUE; }
/* ----- Helper functions ----- */
/* NotifyIsHooked
* Returns TRUE iff the parameter task already has a notification hook. */
BOOL PASCAL NotifyIsHooked( HANDLE hTask) { NOTIFYSTRUCT *pNotify;
/* Loop thorugh all notifications */ for (pNotify = npNotifyHead ; pNotify ; pNotify = pNotify->pNext) if (pNotify->hTask == hTask) break;
/* Return found/not found */ return (BOOL)pNotify; }
|