читать на ядре 0 в Kernel Force
От: v0zxw  
Дата: 10.12.23 01:01
Оценка:
это правильный подход?

class TSingleProcessorMode2
{
    volatile LONG Hub;
    KDPC DpcArray[MAXIMUM_PROCESSORS];
    static void DpcRoutine(KDPC* pDpc, void* pContext, void* pArg1, void* pArg2);
public:
    void Initialize();
    void Execute(void(__fastcall* Routine)(void*), void* pContext);
};



void TSingleProcessorMode2::Initialize()
{
    RtlZeroMemory(this, sizeof(TSingleProcessorMode2));
    if (KeQueryActiveProcessorCount(nullptr) > 1)
        for (int i = 0; i < MAXIMUM_PROCESSORS; i++)
        {
            KeInitializeDpc(&DpcArray[i], DpcRoutine, this);
            KeSetTargetProcessorDpc(&DpcArray[i], (CCHAR)i);
            KeSetImportanceDpc(&DpcArray[i], HighImportance);
        }
}

void TSingleProcessorMode2::DpcRoutine(KDPC* pDpc, void* pContext, void* pArg1, void* pArg2)
{
    TSingleProcessorMode2* pThis = (TSingleProcessorMode2*)pContext;

#if _WIN32_WINNT < 0x0502
    KeRaiseIrqlToSynchLevel();
#else
    //KIRQL DummyIrql;
    //KeRaiseIrql(12, &DummyIrql);
    KeRaiseIrqlToSynchLevel();
#endif

    while (true)
    {

        KIRQL DummyIrql;
        KeRaiseIrql(HIGH_LEVEL, &DummyIrql);
        LONG probe, level = InterlockedDecrement(&pThis->Hub) << 8;
        if (level == 0)
        {
            ((void(__fastcall*)(void*))pArg1)(pArg2);
            InterlockedExchange(&pThis->Hub, -1);
        exit:
            KeLowerIrql(DISPATCH_LEVEL);
            return;
        }

        do
        {
            PERFORMANCE_AUTO_COUNT;
            __nop();
            probe = pThis->Hub;
            if (probe < 0)
                goto exit;
        } while (probe == 0 || --level >= 0
            || InterlockedCompareExchange(&pThis->Hub, probe + 1, probe) != probe);
        KeLowerIrql(12);
        PERFORMANCE_AUTO_COUNT;
        __nop();
    }
}




void TSingleProcessorMode2::Execute(void(__fastcall* pRoutine)(void*), void* pContext)
{
    KeEnterCriticalRegion();
    KeFlushQueuedDpcs();

    if (KeQueryActiveProcessorCount(nullptr) > 1)
    {
        KAFFINITY ActiveProcessors = KeQueryActiveProcessors();
        KIRQL Irql;
        KeRaiseIrql(DISPATCH_LEVEL, &Irql);

        KAFFINITY Mask = 1ul << 0; // Mask for core 0
        if ((ActiveProcessors & Mask) != 0 && KeGetCurrentProcessorNumber() != 0)
        {
            ActiveProcessors &= ~Mask; // Clear the bit for core 0 first
            KeInsertQueueDpc(&DpcArray[0], pRoutine, pContext); // Queue DPC for core 0
        }

        KeLowerIrql(Irql);
    }
    else
    {
        KIRQL DummyIrql;
        KeRaiseIrql(HIGH_LEVEL, &DummyIrql);
        pRoutine(pContext);
        KeLowerIrql(DummyIrql);
    }

    KeFlushQueuedDpcs();
    KeLeaveCriticalRegion();
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.