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=6933…
==============================================================================
--- 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;
}
/*