void NxAdapter::ReportWakeReasonPacket()

in netcx/adapter/nxadapter.cpp [4055:4137]


void NxAdapter::ReportWakeReasonPacket(
    const NET_ADAPTER_WAKE_REASON_PACKET * Reason
) const
{
    Verifier_VerifyNetPowerUpTransition(GetPrivateGlobals(), GetNxDeviceFromHandle(m_device));

    if (Reason->PatternId == NetAdapterWakeFilterPatternId)
    {
        LogInfo(FLAG_POWER,
            "NETADAPTER %p reported wake. Reason: Packet matched receive filter",
                GetFxObject());
    }
    else if (Reason->PatternId == NetAdapterWakeMagicPatternId)
    {
        LogInfo(FLAG_POWER,
            "NETADAPTER %p reported wake. Reason: Magic Packet",
                GetFxObject());
    }
    else if (Reason->PatternId == NetAdapterWakeEapolPatternId)
    {
        LogInfo(FLAG_POWER,
            "NETADAPTER %p reported wake. Reason: EAPOL Packet",
                GetFxObject());
    }
    else
    {
        LogInfo(FLAG_POWER,
            "NETADAPTER %p reported wake. Reason: Packet matched a bitmap pattern (%u)",
                GetFxObject(),
                Reason->PatternId);
    }

    if (Reason->WakePacket == WDF_NO_HANDLE)
    {
        LogWarning(FLAG_POWER,
            "NETADAPTER %p reported wake reason packet without payload",
                GetFxObject());

        return;
    }

    size_t savedPacketSize;
    auto wakePacketBuffer = WdfMemoryGetBuffer(Reason->WakePacket, &savedPacketSize);
    if (savedPacketSize > MAX_ETHERNET_PACKET_SIZE)
    {
        savedPacketSize = MAX_ETHERNET_PACKET_SIZE;
    }
    auto const wakePacketSize = RTL_NUM_ALIGN_UP(NDIS_SIZEOF_PM_WAKE_PACKET_REVISION_1, 8) + RTL_NUM_ALIGN_UP(savedPacketSize, 8);
    auto const wakeReasonSize =
        RTL_NUM_ALIGN_UP(NDIS_SIZEOF_PM_WAKE_REASON_REVISION_1, 8) +
        wakePacketSize;

    NT_FRE_ASSERT(wakePacketSize <= ULONG_MAX);
    NT_FRE_ASSERT(wakeReasonSize <= ULONG_MAX);

    size_t reservedWakeReasonSize;
    auto wakeReason = static_cast<PNDIS_PM_WAKE_REASON>(WdfMemoryGetBuffer(m_wakeReasonMemory, &reservedWakeReasonSize));
    RtlZeroMemory(wakeReason, reservedWakeReasonSize);
    wakeReason->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
    wakeReason->Header.Revision = NDIS_PM_WAKE_REASON_REVISION_1;
    wakeReason->Header.Size = NDIS_SIZEOF_PM_WAKE_REASON_REVISION_1;
    wakeReason->WakeReason = NdisWakeReasonPacket;
    wakeReason->InfoBufferOffset = RTL_NUM_ALIGN_UP(NDIS_SIZEOF_PM_WAKE_REASON_REVISION_1, 8);
    wakeReason->InfoBufferSize = static_cast<ULONG>(wakePacketSize);

    auto wakePacket = reinterpret_cast<PNDIS_PM_WAKE_PACKET>((PUCHAR)wakeReason + RTL_NUM_ALIGN_UP(NDIS_SIZEOF_PM_WAKE_REASON_REVISION_1, 8));
    wakePacket->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
    wakePacket->Header.Revision = NDIS_PM_WAKE_PACKET_REVISION_1;
    wakePacket->Header.Size = NDIS_SIZEOF_PM_WAKE_PACKET_REVISION_1;
    wakePacket->PatternId = Reason->PatternId;
    wakePacket->OriginalPacketSize = Reason->OriginalPacketSize;
    wakePacket->SavedPacketSize = static_cast<ULONG>(savedPacketSize);
    wakePacket->SavedPacketOffset = RTL_NUM_ALIGN_UP(NDIS_SIZEOF_PM_WAKE_PACKET_REVISION_1, 8);

    PUCHAR data = (PUCHAR)wakePacket + RTL_NUM_ALIGN_UP(NDIS_SIZEOF_PM_WAKE_PACKET_REVISION_1, 8);
    RtlCopyMemory(data, wakePacketBuffer, savedPacketSize);

    auto wakeIndication = MakeNdisStatusIndication(
        m_ndisAdapterHandle, NDIS_STATUS_PM_WAKE_REASON, *wakeReason);
    wakeIndication.StatusBufferSize = static_cast<ULONG>(wakeReasonSize);

    NdisMIndicateStatusEx(m_ndisAdapterHandle, &wakeIndication);
}