⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nic_pm.c

📁 ddk开发pci范例,使用9054芯片
💻 C
📖 第 1 页 / 共 4 页
字号:
        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 + -