📄 nic_pm.c
字号:
MPSetPowerD0 (FdoData);
}
else
{
DebugPrint(TRACE, DBG_POWER, "Entering a deeper sleep state\n");
status = MPSetPowerLow (FdoData, PowerState);
}
return status;
}
NTSTATUS
NICAddWakeUpPattern(
IN PFDO_DATA FdoData,
IN PVOID InformationBuffer,
IN UINT InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
/*++
Routine Description:
This routine will allocate a local memory structure, copy the pattern,
insert the pattern into a linked list and return success
We are gauranteed that we wll get only one request at a time, so this is implemented
without locks.
Arguments:
FdoData FdoData structure
InformationBuffer Wake up Pattern
InformationBufferLength Wake Up Pattern Length
Return Value:
STATUS_Success - if successful.
STATUS_UNSUCCESSFUL - if memory allocation fails.
--*/
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PMP_WAKE_PATTERN pWakeUpPattern = NULL;
UINT AllocationLength = 0;
PNDIS_PM_PACKET_PATTERN pPmPattern = NULL;
ULONG Signature = 0;
ULONG CopyLength = 0;
DebugPrint(TRACE, DBG_POWER, "--> NICAddWakeUpPattern\n");
do
{
pPmPattern = (PNDIS_PM_PACKET_PATTERN) InformationBuffer;
if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN))
{
status = STATUS_BUFFER_TOO_SMALL;
*BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN);
break;
}
if (InformationBufferLength < pPmPattern->PatternOffset + pPmPattern->PatternSize)
{
status = STATUS_BUFFER_TOO_SMALL;
*BytesNeeded = pPmPattern->PatternOffset + pPmPattern->PatternSize;
break;
}
*BytesRead = pPmPattern->PatternOffset + pPmPattern->PatternSize;
//
// Calculate the e100 signature
//
status = MPCalculateE100PatternForFilter (
(PUCHAR)pPmPattern+ pPmPattern->PatternOffset,
pPmPattern->PatternSize,
(PUCHAR)pPmPattern +sizeof(NDIS_PM_PACKET_PATTERN),
pPmPattern->MaskSize,
&Signature );
if ( status != STATUS_SUCCESS)
{
break;
}
CopyLength = pPmPattern->PatternOffset + pPmPattern->PatternSize;
//
// Allocate the memory to hold the WakeUp Pattern
//
AllocationLength = sizeof (MP_WAKE_PATTERN) + CopyLength;
pWakeUpPattern = ExAllocatePoolWithTag(NonPagedPool, AllocationLength, PCIDRV_POOL_TAG);
if (!pWakeUpPattern)
{
break;
}
//
// Initialize pWakeUpPattern
//
RtlZeroMemory (pWakeUpPattern, AllocationLength);
pWakeUpPattern->AllocationSize = AllocationLength;
pWakeUpPattern->Signature = Signature;
//
// Copy the pattern into local memory
//
RtlMoveMemory (&pWakeUpPattern->Pattern[0], InformationBuffer, CopyLength);
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
//
// Insert the pattern into the list
//
ExInterlockedInsertHeadList (&FdoData->PoMgmt.PatternList,
&pWakeUpPattern->linkListEntry,
&FdoData->Lock);
status = STATUS_SUCCESS;
} while (FALSE);
DebugPrint(TRACE, DBG_POWER, "<-- NICAddWakeUpPattern\n");
return status;
}
NTSTATUS
NICRemoveWakeUpPattern(
IN PFDO_DATA FdoData,
IN PVOID InformationBuffer,
IN UINT InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
/*++
Routine Description:
This routine will walk the list of wake up pattern and attempt to match the wake up pattern.
If it finds a copy , it will remove that WakeUpPattern
Arguments:
FdoData FdoData structure
InformationBuffer Wake up Pattern
InformationBufferLength Wake Up Pattern Length
Return Value:
Success - if successful.
STATUS_UNSUCCESSFUL - if memory allocation fails.
--*/
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PNDIS_PM_PACKET_PATTERN pReqPattern = (PNDIS_PM_PACKET_PATTERN)InformationBuffer;
PLIST_ENTRY pPatternEntry = ListNext(&FdoData->PoMgmt.PatternList) ;
DebugPrint(TRACE, DBG_POWER, "--> NICRemoveWakeUpPattern\n");
do
{
if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN))
{
status = STATUS_BUFFER_TOO_SMALL;
*BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN);
break;
}
if (InformationBufferLength < pReqPattern->PatternOffset + pReqPattern->PatternSize)
{
status = STATUS_BUFFER_TOO_SMALL;
*BytesNeeded = pReqPattern->PatternOffset + pReqPattern->PatternSize;
break;
}
*BytesRead = pReqPattern->PatternOffset + pReqPattern->PatternSize;
while (pPatternEntry != (&FdoData->PoMgmt.PatternList))
{
BOOLEAN bIsThisThePattern = FALSE;
PMP_WAKE_PATTERN pWakeUpPattern = NULL;
PNDIS_PM_PACKET_PATTERN pCurrPattern = NULL;;
//
// initialize local variables
//
pWakeUpPattern = CONTAINING_RECORD(pPatternEntry, MP_WAKE_PATTERN, linkListEntry);
pCurrPattern = (PNDIS_PM_PACKET_PATTERN)&pWakeUpPattern->Pattern[0];
//
// increment the iterator
//
pPatternEntry = ListNext (pPatternEntry);
//
// Begin Check : Is (pCurrPattern == pReqPattern)
//
bIsThisThePattern = MPAreTwoPatternsEqual(pReqPattern, pCurrPattern);
if (bIsThisThePattern == TRUE)
{
//
// we have a match - remove the entry
//
RemoveEntryList (&pWakeUpPattern->linkListEntry);
//
// Free the entry
//
ExFreePoolWithTag(pWakeUpPattern, PCIDRV_POOL_TAG);
status = STATUS_SUCCESS;
break;
}
}
}
while (FALSE);
DebugPrint(TRACE, DBG_POWER, "<-- NICRemoveWakeUpPattern\n");
return status;
}
VOID
NICRemoveAllWakeUpPatterns(
PFDO_DATA FdoData
)
/*++
Routine Description:
This routine will walk the list of wake up pattern and free it
Arguments:
FdoData FdoData structure
Return Value:
Success - if successful.
--*/
{
PLIST_ENTRY pPatternEntry = ListNext(&FdoData->PoMgmt.PatternList) ;
DebugPrint(TRACE, DBG_POWER, "--> NICRemoveAllWakeUpPatterns\n");
while (pPatternEntry != (&FdoData->PoMgmt.PatternList))
{
PMP_WAKE_PATTERN pWakeUpPattern = NULL;
//
// initialize local variables
//
pWakeUpPattern = CONTAINING_RECORD(pPatternEntry, MP_WAKE_PATTERN,linkListEntry);
//
// increment the iterator
//
pPatternEntry = ListNext (pPatternEntry);
//
// Remove the entry from the list
//
RemoveEntryList (&pWakeUpPattern->linkListEntry);
//
// Free the memory
//
ExFreePoolWithTag(pWakeUpPattern, PCIDRV_POOL_TAG);
}
DebugPrint(TRACE, DBG_POWER, "<-- NICRemoveAllWakeUpPatterns\n");
}
NTSTATUS
NICConfigureForWakeUp(
IN PFDO_DATA FdoData,
IN BOOLEAN AddPattern
)
/*++
Routine Description:
Arguments:
FdoData FdoData structure
Return Value:
Success - if successful.
--*/
{
#define MAX_WAKEUP_PATTERN_LENGTH 128
UCHAR Buffer[sizeof(NDIS_PM_PACKET_PATTERN) +
MAX_WAKEUP_PATTERN_LENGTH];
PCHAR patternBuffer, nextMask, nextPattern;
ULONG maskLen;
PNDIS_PM_PACKET_PATTERN ndisPattern;
ULONG bufLen;
NTSTATUS status;
ULONG unUsed;
CHAR wakePattern[]={0xff,0xff,0xff,0xff,0xff,0xff}; //broadcast address
patternBuffer = (PCHAR)&Buffer[0];
ndisPattern = (PNDIS_PM_PACKET_PATTERN)patternBuffer;
RtlZeroMemory(ndisPattern, sizeof(NDIS_PM_PACKET_PATTERN));
ndisPattern->PatternSize = sizeof(wakePattern);
maskLen = (ndisPattern->PatternSize-1)/8 + 1;
nextMask = (PCHAR)patternBuffer + sizeof(NDIS_PM_PACKET_PATTERN);
nextPattern = nextMask + maskLen;
*nextMask = 0x3f;
ndisPattern->MaskSize = maskLen;
ndisPattern->PatternOffset = (ULONG) ((ULONG_PTR) nextPattern - (ULONG_PTR) patternBuffer);
bufLen = sizeof(NDIS_PM_PACKET_PATTERN) + maskLen + ndisPattern->PatternSize;
RtlCopyMemory(nextPattern, FdoData->CurrentAddress, ETHERNET_ADDRESS_LENGTH);
if(AddPattern){
status = NICAddWakeUpPattern(FdoData, Buffer, bufLen, &unUsed, &unUsed);
if(!NT_SUCCESS(status)){
DebugPrint(TRACE, DBG_POWER, "NICAddWakeupPattern failed %x\n", status);
}
}else{
status = NICRemoveWakeUpPattern(FdoData, Buffer, bufLen, &unUsed, &unUsed);
if(!NT_SUCCESS(status)){
DebugPrint(TRACE, DBG_POWER, "NICRemoveWakeUpPattern failed %x\n", status);
}
}
return status;
}
#if 0
NTSTATUS
NICConfigureForWakeUp(
IN PFDO_DATA FdoData,
IN BOOLEAN AddPattern
)
{
#define MAX_WAKEUP_PATTERN_LENGTH 128
#define ETHER_IP_ICMP_HEADER_SIZE 14+20+8
UCHAR Buffer[sizeof(NDIS_PM_PACKET_PATTERN) +
MAX_WAKEUP_PATTERN_LENGTH];
PCHAR patternBuffer, nextMask, nextPattern;
ULONG maskLen;
PNDIS_PM_PACKET_PATTERN ndisPattern;
ULONG bufLen;
NTSTATUS status;
ULONG unUsed;
CHAR pingPattern[]={'a','b','c','d','e','f','g','h'};
patternBuffer = (PCHAR)&Buffer[0];
ndisPattern = (PNDIS_PM_PACKET_PATTERN)patternBuffer;
RtlZeroMemory(ndisPattern, sizeof(NDIS_PM_PACKET_PATTERN));
ndisPattern->PatternSize = ETHER_IP_ICMP_HEADER_SIZE + sizeof(pingPattern);
maskLen = (ndisPattern->PatternSize-1)/8 + 1;
nextMask = (PCHAR)patternBuffer + sizeof(NDIS_PM_PACKET_PATTERN);
nextPattern = nextMask + maskLen;
*nextMask = 0x0;nextMask++;
*nextMask = 0x0;nextMask++;
*nextMask = 0x0;nextMask++;
*nextMask = 0x0;nextMask++;
*nextMask = 0x0;nextMask++;
*nextMask = 0x3f;nextMask++;
*nextMask = 0x0C;
ndisPattern->MaskSize = maskLen;
ndisPattern->PatternOffset = (ULONG) ((ULONG_PTR) nextPattern - (ULONG_PTR) patternBuffer);
bufLen = sizeof(NDIS_PM_PACKET_PATTERN) + maskLen + ndisPattern->PatternSize;
RtlZeroMemory(nextPattern, ETHER_IP_ICMP_HEADER_SIZE);
nextPattern += ETHER_IP_ICMP_HEADER_SIZE;
RtlCopyMemory(nextPattern, pingPattern, sizeof(pingPattern));
if(AddPattern){
status = MPAddWakeUpPattern(FdoData, Buffer, bufLen, &unUsed, &unUsed);
if(!NT_SUCCESS(status)){
DebugPrint(TRACE, DBG_POWER, "MpAddWakeupPattern failed %x\n", status);
}
}else{
status = MPRemoveWakeUpPattern(FdoData, Buffer, bufLen, &unUsed, &unUsed);
if(!NT_SUCCESS(status)){
DebugPrint(TRACE, DBG_POWER, "MPRemoveWakeUpPattern failed %x\n", status);
}
}
return status;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -