[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

svn path=/trunk/; revision=69337
This commit is contained in:
Hermès Bélusca-Maïto 2015-09-23 23:52:03 +00:00
parent f44942d42f
commit f5c0c9408e

View file

@ -28,8 +28,10 @@ ULONG KeBugCheckCount = 1;
ULONG KiHardwareTrigger; ULONG KiHardwareTrigger;
PUNICODE_STRING KiBugCheckDriver; PUNICODE_STRING KiBugCheckDriver;
ULONG_PTR KiBugCheckData[5]; ULONG_PTR KiBugCheckData[5];
PKNMI_HANDLER_CALLBACK KiNmiCallbackListHead;
PKNMI_HANDLER_CALLBACK KiNmiCallbackListHead = NULL;
KSPIN_LOCK KiNmiCallbackListLock; KSPIN_LOCK KiNmiCallbackListLock;
#define TAG_KNMI 'IMNK'
/* Bugzilla Reporting */ /* Bugzilla Reporting */
UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion; UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion;
@ -1374,9 +1376,7 @@ KeRegisterNmiCallback(IN PNMI_CALLBACK CallbackRoutine,
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Allocate NMI callback data */ /* Allocate NMI callback data */
NmiData = ExAllocatePoolWithTag(NonPagedPool, NmiData = ExAllocatePoolWithTag(NonPagedPool, sizeof(*NmiData), TAG_KNMI);
sizeof(KNMI_HANDLER_CALLBACK),
'IMNK');
if (!NmiData) return NULL; if (!NmiData) return NULL;
/* Fill in the information */ /* Fill in the information */
@ -1402,10 +1402,42 @@ KeRegisterNmiCallback(IN PNMI_CALLBACK CallbackRoutine,
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
KeDeregisterNmiCallback(PVOID Handle) KeDeregisterNmiCallback(IN PVOID Handle)
{ {
UNIMPLEMENTED; KIRQL OldIrql;
return STATUS_UNSUCCESSFUL; 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;
} }
/* /*