void CParaNdisTX::NBLMappingDone(CNBL *NBLHolder)
{
    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);

    if (NBLHolder->MappingSuceeded())
    {
        DoWithTXLock([NBLHolder, this](){ m_SendList.PushBack(NBLHolder); });
        DoPendingTasks(false);
    }
    else
    {
        NBLHolder->SetStatus(NDIS_STATUS_FAILURE);
        NBLHolder->Release();
    }
}
bool CParaNdisTX::Pause()
{
    PNET_BUFFER_LIST NBL = nullptr;
    bool res;

    DoWithTXLock([this, &NBL, &res]()
                 {
                     NBL = RemoveAllNonWaitingNBLs();
                     res = (!m_VirtQueue.HasPacketsInHW() && m_WaitingList.IsEmpty());
                 });

    if(NBL != nullptr)
    {
        NdisMSendNetBufferListsComplete(m_Context->MiniportHandle, NBL, 0);
    }

    return res;
}
bool CParaNdisTX::DoPendingTasks(bool IsInterrupt)
{
    PNET_BUFFER_LIST pNBLReturnNow = nullptr;
    bool bDoKick = false;

    DoWithTXLock([&] ()
                 {
                    m_VirtQueue.ProcessTXCompletions();
                    bDoKick = SendMapped(IsInterrupt);
                    pNBLReturnNow = ProcessWaitingList();
                 });

    if (pNBLReturnNow)
    {
        CompleteOutstandingNBLChain(pNBLReturnNow, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
    }
#pragma warning(pop)

    return bDoKick;
}
bool CParaNdisTX::DoPendingTasks(bool IsInterrupt)
{
    ONPAUSECOMPLETEPROC CallbackToCall = nullptr;
    PNET_BUFFER_LIST pNBLFailNow = nullptr;
    PNET_BUFFER_LIST pNBLReturnNow = nullptr;
    bool bDoKick = false;

    DoWithTXLock([&] ()
                 {
                    m_VirtQueue.ProcessTXCompletions();
                    bDoKick = SendMapped(IsInterrupt, pNBLFailNow);
                    pNBLReturnNow = ProcessWaitingList();

                    if (!m_VirtQueue.HasPacketsInHW() && m_Context->SendState == srsPausing)
                    {
                        CallbackToCall = m_Context->SendPauseCompletionProc;
                        m_Context->SendPauseCompletionProc = nullptr;
                        m_Context->SendState = srsDisabled;
                    }
                 });

    if (pNBLFailNow)
    {
        NdisMSendNetBufferListsComplete(m_Context->MiniportHandle, pNBLFailNow,
                                        NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
    }

    if (pNBLReturnNow)
    {
        NdisMSendNetBufferListsComplete(m_Context->MiniportHandle, pNBLReturnNow,
                                        NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
    }

    if (CallbackToCall != nullptr)
    {
        CallbackToCall(m_Context);
    }

    return bDoKick;
}