|
PKDPC GainExclusivity()
{
NTSTATUS ns;
ULONG u_currentCPU;
CCHAR i;
PKDPC pkdpc, temp_pkdpc;
if (KeGetCurrentIrql() != DISPATCH_LEVEL)
return NULL;
InterlockedAnd(&AllCPURaised, 0);
InterlockedAnd(&NumberOfRaisedCPU, 0);
temp_pkdpc = (PKDPC) ExAllocatePool(NonPagedPool, KeNumberProcessors *
sizeof(KDPC));
if (temp_pkdpc == NULL)
return NULL;
u_currentCPU = KeGetCurrentProcessorNumber();
pkdpc = temp_pkdpc;
for (i = 0; i < KeNumberProcessors; i++, *temp_pkdpc++)
{
if (i != u_currentCPU)
{
KeInitializeDpc(temp_pkdpc,
RaiseCPUIrqlAndWait,
NULL);
KeSetTargetProcessorDpc(temp_pkdpc, i);
KeInsertQueueDpc(temp_pkdpc, NULL, NULL);
}
}
while(InterlockedCompareExchange(&NumberOfRaisedCPU,
KeNumberProcessors-1, KeNumberProcessors-1) !=
KeNumberProcessors-1)
{
__asm nop;
}
return pkdpc;
}
VOID RaiseCPUIrqlAndWait(IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
{
InterlockedIncrement(&NumberOfRaisedCPU);
while(!InterlockedCompareExchange(&AllCPURaised, 1, 1))
{
__asm nop;
}
InterlockedDecrement(&NumberOfRaisedCPU);
}
NTSTATUS ReleaseExclusivity(PVOID pkdpc)
{
InterlockedIncrement(&AllCPURaised);
while(InterlockedCompareExchange(&NumberOfRaisedCPU, 0, 0))
{
__asm nop;
}
if (pkdpc != NULL)
{
ExFreePool(pkdpc);
pkdpc = NULL;
}
return STATUS_SUCCESS;
} |
|