| 197 | } |
| 198 | |
| 199 | void QueueWaitThreadedDpc(bool(*Callback)(void* Arg), void* Arg, unsigned char ProcessorNumber) |
| 200 | { |
| 201 | struct DPC_DATA |
| 202 | { |
| 203 | decltype(Callback) Callback; |
| 204 | void* Arg; |
| 205 | volatile LONG Finished; |
| 206 | }; |
| 207 | |
| 208 | DPC_DATA DpcData = { Callback, Arg, 0 }; |
| 209 | |
| 210 | constexpr ULONG DpcTag = 'CPDT'; // TDPC = Threaded DPC |
| 211 | |
| 212 | KDPC Dpc; |
| 213 | KeInitializeThreadedDpc(&Dpc, [](PKDPC Dpc, PVOID Arg, PVOID SystemArgument1, PVOID SystemArgument2) |
| 214 | { |
| 215 | UNREFERENCED_PARAMETER(Dpc); |
| 216 | UNREFERENCED_PARAMETER(SystemArgument1); |
| 217 | UNREFERENCED_PARAMETER(SystemArgument2); |
| 218 | DPC_DATA* DpcData = reinterpret_cast<DPC_DATA*>(Arg); |
| 219 | DpcData->Callback(DpcData->Arg); |
| 220 | InterlockedExchange(&DpcData->Finished, TRUE); |
| 221 | }, &DpcData); |
| 222 | |
| 223 | KeSetImportanceDpc(&Dpc, HighImportance); |
| 224 | KeSetTargetProcessorDpc(&Dpc, ProcessorNumber); |
| 225 | |
| 226 | KeInsertQueueDpc(&Dpc, NULL, NULL); |
| 227 | |
| 228 | while (InterlockedCompareExchange(&DpcData.Finished, TRUE, TRUE) != TRUE) |
| 229 | { |
| 230 | _mm_pause(); |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | struct STOP_PROCESSORS_DATA |
| 235 | { |
nothing calls this directly
no outgoing calls
no test coverage detected