| 56 | } |
| 57 | |
| 58 | bool ForEachCpu(bool(*Callback)(void* Arg, unsigned int ProcessorNumber), void* Arg) |
| 59 | { |
| 60 | ULONG ProcessorsCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); |
| 61 | for (ULONG i = 0; i < ProcessorsCount; i++) |
| 62 | { |
| 63 | PROCESSOR_NUMBER ProcessorNumber = {}; |
| 64 | KeGetProcessorNumberFromIndex(i, &ProcessorNumber); |
| 65 | |
| 66 | GROUP_AFFINITY Affinity = {}, PreviousAffinity = {}; |
| 67 | Affinity.Group = ProcessorNumber.Group; |
| 68 | Affinity.Mask = 1LL << ProcessorNumber.Number; |
| 69 | KeSetSystemGroupAffinityThread(&Affinity, &PreviousAffinity); |
| 70 | |
| 71 | ZwYieldExecution(); // Perform the context switch to apply the affinity |
| 72 | |
| 73 | bool Status = Callback(Arg, i); |
| 74 | |
| 75 | KeRevertToUserGroupAffinityThread(&PreviousAffinity); |
| 76 | |
| 77 | if (!Status) return false; |
| 78 | } |
| 79 | return true; |
| 80 | } |
| 81 | |
| 82 | void DpcOnEachCpu(void(*Callback)(void* Arg), void* Arg) |
| 83 | { |
no outgoing calls
no test coverage detected