| 100 | } |
| 101 | |
| 102 | void QueueDpc(bool(*Callback)(void* Arg), void* Arg, unsigned char ProcessorNumber) |
| 103 | { |
| 104 | struct DPC_DATA |
| 105 | { |
| 106 | KDPC Dpc; |
| 107 | decltype(Callback) Callback; |
| 108 | void* Arg; |
| 109 | }; |
| 110 | |
| 111 | constexpr ULONG DpcTag = 'CPDK'; |
| 112 | DPC_DATA* DpcData = reinterpret_cast<DPC_DATA*>(ExAllocatePoolWithTag(NonPagedPool, sizeof(*DpcData), DpcTag)); |
| 113 | memset(DpcData, 0, sizeof(*DpcData)); |
| 114 | DpcData->Callback = Callback; |
| 115 | DpcData->Arg = Arg; |
| 116 | |
| 117 | KeInitializeDpc(&DpcData->Dpc, [](PKDPC Dpc, PVOID Arg, PVOID SystemArgument1, PVOID SystemArgument2) |
| 118 | { |
| 119 | UNREFERENCED_PARAMETER(Dpc); |
| 120 | UNREFERENCED_PARAMETER(SystemArgument1); |
| 121 | UNREFERENCED_PARAMETER(SystemArgument2); |
| 122 | DPC_DATA* DpcData = reinterpret_cast<DPC_DATA*>(Arg); |
| 123 | DpcData->Callback(DpcData->Arg); |
| 124 | ExFreePoolWithTag(Dpc, DpcTag); |
| 125 | }, DpcData); |
| 126 | |
| 127 | KeSetImportanceDpc(&DpcData->Dpc, HighImportance); |
| 128 | KeSetTargetProcessorDpc(&DpcData->Dpc, ProcessorNumber); |
| 129 | |
| 130 | KeInsertQueueDpc(&DpcData->Dpc, NULL, NULL); |
| 131 | } |
| 132 | |
| 133 | void QueueWaitDpc(bool(*Callback)(void* Arg), void* Arg, unsigned char ProcessorNumber) |
| 134 | { |
nothing calls this directly
no outgoing calls
no test coverage detected