Author: hbelusca Date: Wed Sep 23 23:52:03 2015 New Revision: 69337
URL: http://svn.reactos.org/svn/reactos?rev=69337&view=rev Log: [NTOS]: Implement KeDeregisterNmiCallback.
Aside question: we have a "nmidebug" driver in \drivers\base. In it is a NMI callback "NmiDbgCallback". I was wondering what "((void(*)())&KiBugCheckData[4])();" should do, according to the surrounding code, since in some conditions this code path is actually run: http://i.imgur.com/TUsEr5p.jpg
Modified: trunk/reactos/ntoskrnl/ke/bug.c
Modified: trunk/reactos/ntoskrnl/ke/bug.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/bug.c?rev=69337... ============================================================================== --- trunk/reactos/ntoskrnl/ke/bug.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/bug.c [iso-8859-1] Wed Sep 23 23:52:03 2015 @@ -28,8 +28,10 @@ ULONG KiHardwareTrigger; PUNICODE_STRING KiBugCheckDriver; ULONG_PTR KiBugCheckData[5]; -PKNMI_HANDLER_CALLBACK KiNmiCallbackListHead; + +PKNMI_HANDLER_CALLBACK KiNmiCallbackListHead = NULL; KSPIN_LOCK KiNmiCallbackListLock; +#define TAG_KNMI 'IMNK'
/* Bugzilla Reporting */ UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion; @@ -1374,9 +1376,7 @@ ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Allocate NMI callback data */ - NmiData = ExAllocatePoolWithTag(NonPagedPool, - sizeof(KNMI_HANDLER_CALLBACK), - 'IMNK'); + NmiData = ExAllocatePoolWithTag(NonPagedPool, sizeof(*NmiData), TAG_KNMI); if (!NmiData) return NULL;
/* Fill in the information */ @@ -1402,10 +1402,42 @@ */ NTSTATUS NTAPI -KeDeregisterNmiCallback(PVOID Handle) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; +KeDeregisterNmiCallback(IN PVOID Handle) +{ + KIRQL OldIrql; + PKNMI_HANDLER_CALLBACK NmiData, Previous; + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Find in the list the NMI callback corresponding to the handle */ + KiAcquireNmiListLock(&OldIrql); + Previous = &KiNmiCallbackListHead; + NmiData = *Previous; + while (NmiData) + { + if (NmiData->Handle == Handle) + { + /* The handle is the pointer to the callback itself */ + ASSERT(Handle == NmiData); + + /* Found it, remove from the list */ + *Previous = NmiData->Next; + break; + } + + /* Not found; try again */ + Previous = &NmiData->Next; + NmiData = *Previous; + } + KiReleaseNmiListLock(OldIrql); + + /* If we have found the entry, free it */ + if (NmiData) + { + ExFreePoolWithTag(NmiData, TAG_KNMI); + return STATUS_SUCCESS; + } + + return STATUS_INVALID_HANDLE; }
/*