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);
}