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

📄 miniport.c

📁 James Antognini和Tom Divine提供的PASSTHRU的编成实例。
💻 C
📖 第 1 页 / 共 5 页
字号:
    pStatus - Place to return final status

Return Value:

    None.

--*/

{
    PNDIS_PNP_CAPABILITIES           pPNPCapabilities;
    PNDIS_PM_WAKE_UP_CAPABILITIES    pPMstruct;

    if (pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof(NDIS_PNP_CAPABILITIES))
    {
        pPNPCapabilities = (PNDIS_PNP_CAPABILITIES)(pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer);

        //
        // The following fields must be overwritten by an IM driver.
        //
        pPMstruct= & pPNPCapabilities->WakeUpCapabilities;
        pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
        pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;
        pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
        *pAdapt->BytesReadOrWritten = sizeof(NDIS_PNP_CAPABILITIES);
        *pAdapt->BytesNeeded = 0;


        //
        // Setting our internal flags
        // Default, device is ON
        //
        pAdapt->MPDeviceState = NdisDeviceStateD0;
        pAdapt->PTDeviceState = NdisDeviceStateD0;

        *pStatus = NDIS_STATUS_SUCCESS;
    }
    else
    {
        *pAdapt->BytesNeeded= sizeof(NDIS_PNP_CAPABILITIES);
        *pStatus = NDIS_STATUS_RESOURCES;
    }
}


NDIS_STATUS
MPSetInformation(
    IN NDIS_HANDLE             MiniportAdapterContext,
    IN NDIS_OID                Oid,
    IN PVOID                   InformationBuffer,
    IN ULONG                   InformationBufferLength,
    OUT PULONG                 BytesRead,
    OUT PULONG                 BytesNeeded
    )
/*++

Routine Description:

    Miniport SetInfo handler.

    In the case of OID_PNP_SET_POWER, record the power state and return the OID.    
    Do not pass below
    If the device is suspended, do not block the SET_POWER_OID 
    as it is used to reactivate the Passthru miniport

    
    PM- If the MP is not ON (DeviceState > D0) return immediately  (except for 'query power' and 'set power')
         If MP is ON, but the PT is not at D0, then queue the queue the request for later processing

    Requests to miniports are always serialized


Arguments:

    MiniportAdapterContext    Pointer to the adapter structure
    Oid                       Oid for this query
    InformationBuffer         Buffer for information
    InformationBufferLength   Size of this buffer
    BytesRead                 Specifies how much info is read
    BytesNeeded               In case the buffer is smaller than what we need, tell them how much is needed

Return Value:

    Return code from the NdisRequest below.

--*/
{
    PADAPT        pAdapt = (PADAPT)MiniportAdapterContext;
    NDIS_STATUS   Status;

    Status = NDIS_STATUS_FAILURE;

    do
    {
        //
        // The Set Power should not be sent to the miniport below the Passthru, but is handled internally
        //
        if (Oid == OID_PNP_SET_POWER)
        {
            MPProcessSetPowerOid(&Status, 
                                 pAdapt, 
                                 InformationBuffer, 
                                 InformationBufferLength, 
                                 BytesRead, 
                                 BytesNeeded);
            break;

        }

        //
        // If the miniport below is unbinding, fail the request
        //
        NdisAcquireSpinLock(&pAdapt->Lock);     
        if (pAdapt->UnbindingInProcess == TRUE)
        {
            NdisReleaseSpinLock(&pAdapt->Lock);
            Status = NDIS_STATUS_FAILURE;
            break;
        }
        NdisReleaseSpinLock(&pAdapt->Lock);
        //
        // All other Set Information requests are failed, if the miniport is
        // not at D0 or is transitioning to a device state greater than D0.
        //
        if (pAdapt->MPDeviceState > NdisDeviceStateD0)
        {
            Status = NDIS_STATUS_FAILURE;
            break;
        }

        if (OID_CUSTOM_ARRAY==Oid)                    // Set custom array?  ja, 28.09.2003.
          {
           // The input data are a 4-byte word given the number of elements, followed by
           // that number of 4-byte elements.

           PPassthruIPAddrArray pInArr =              // Point to incoming buffer.
             (PPassthruIPAddrArray)InformationBuffer;
           NDIS_STATUS lclStatus;
              
//         DBGPRINT(("MPSetInformation():  For adapter at 0x%08x, Oid = OID_CUSTOM_ARRAY\n",
//                   pAdapt));

           lclStatus =
             PassthruWMISetAddrArray(
                                     pAdapt,
                                     pInArr->NumberElements,
                                     pInArr
                                    );

           if (NDIS_STATUS_SUCCESS!=lclStatus)
             {
              DBGPRINT(("MPSetInformation():  Failed in PassthruWMISetAddrArray(), status 0x%08x!\n", lclStatus));
              Status = lclStatus;
              *BytesRead = 0;
              *BytesNeeded = 0;
              break;
             }

           *BytesRead = InformationBufferLength;
           Status = NDIS_STATUS_SUCCESS;
           break;
          }

        // Set up the Request and return the result
        pAdapt->Request.RequestType = NdisRequestSetInformation;
        pAdapt->Request.DATA.SET_INFORMATION.Oid = Oid;
        pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
        pAdapt->Request.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
        pAdapt->BytesNeeded = BytesNeeded;
        pAdapt->BytesReadOrWritten = BytesRead;

        //
        // If the miniport below is unbinding, fail the request
        //
        NdisAcquireSpinLock(&pAdapt->Lock);     
        if (pAdapt->UnbindingInProcess == TRUE)
        {
            NdisReleaseSpinLock(&pAdapt->Lock);
            Status = NDIS_STATUS_FAILURE;
            break;
        }
            
        //
        // If the device below is at a low power state, we cannot send it the
        // request now, and must pend it.
        //
        if ((pAdapt->PTDeviceState > NdisDeviceStateD0) 
                && (pAdapt->StandingBy == FALSE))
        {
            pAdapt->QueuedRequest = TRUE;
            NdisReleaseSpinLock(&pAdapt->Lock);
            Status = NDIS_STATUS_PENDING;
            break;
        }
        //
        // This is in the process of powering down the system, always fail the request
        // 
        if (pAdapt->StandingBy == TRUE)
        {
            NdisReleaseSpinLock(&pAdapt->Lock);
            Status = NDIS_STATUS_FAILURE;
            break;
        }
        pAdapt->OutstandingRequests = TRUE;
        
        NdisReleaseSpinLock(&pAdapt->Lock);
        //
        // Forward the request to the device below.
        //
        NdisRequest(&Status,
                    pAdapt->BindingHandle,
                    &pAdapt->Request);

        if (Status != NDIS_STATUS_PENDING)
        {
            *BytesRead = pAdapt->Request.DATA.SET_INFORMATION.BytesRead;
            *BytesNeeded = pAdapt->Request.DATA.SET_INFORMATION.BytesNeeded;
            pAdapt->OutstandingRequests = FALSE;
        }

    } while (FALSE);

    return(Status);
}


VOID
MPProcessSetPowerOid(
    IN OUT PNDIS_STATUS          pNdisStatus,
    IN PADAPT                    pAdapt,
    IN PVOID                     InformationBuffer,
    IN ULONG                     InformationBufferLength,
    OUT PULONG                   BytesRead,
    OUT PULONG                   BytesNeeded
    )
/*++

Routine Description:
    This routine does all the procssing for a request with a SetPower Oid
    The miniport shoud accept  the Set Power and transition to the new state

    The Set Power should not be passed to the miniport below

    If the IM miniport is going into a low power state, then there is no guarantee if it will ever
    be asked go back to D0, before getting halted. No requests should be pended or queued.

    
Arguments:
    pNdisStatus           - Status of the operation
    pAdapt                - The Adapter structure
    InformationBuffer     - The New DeviceState
    InformationBufferLength
    BytesRead             - No of bytes read
    BytesNeeded           -  No of bytes needed


Return Value:
    Status  - NDIS_STATUS_SUCCESS if all the wait events succeed.

--*/
{

    
    NDIS_DEVICE_POWER_STATE NewDeviceState;

    DBGPRINT(("==>MPProcessSetPowerOid: Adapt %p\n", pAdapt)); 

    ASSERT (InformationBuffer != NULL);

    *pNdisStatus = NDIS_STATUS_FAILURE;

    do 
    {
        //
        // Check for invalid length
        //
        if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))
        {
            *pNdisStatus = NDIS_STATUS_INVALID_LENGTH;
            break;
        }

        NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);

        //
        // Check for invalid device state
        //
        if ((pAdapt->MPDeviceState > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0))
        {
            //
            // If the miniport is in a non-D0 state, the miniport can only receive a Set Power to D0
            //
            ASSERT (!(pAdapt->MPDeviceState > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0));

            *pNdisStatus = NDIS_STATUS_FAILURE;
            break;
        }    

        //
        // Is the miniport transitioning from an On (D0) state to an Low Power State (>D0)
        // If so, then set the StandingBy Flag - (Block all incoming requests)
        //
        if (pAdapt->MPDeviceState == NdisDeviceStateD0 && NewDeviceState > NdisDeviceStateD0)
        {
            pAdapt->StandingBy = TRUE;
        }

        //
        // If the miniport is transitioning from a low power state to ON (D0), then clear the StandingBy flag
        // All incoming requests will be pended until the physical miniport turns ON.
        //
        if (pAdapt->MPDeviceState > NdisDeviceStateD0 &&  NewDeviceState == NdisDeviceStateD0)
        {
            pAdapt->StandingBy = FALSE;
        }
        
        //
        // Now update the state in the pAdapt structure;
        //
        pAdapt->MPDeviceState = NewDeviceState;
        
        *pNdisStatus = NDIS_STATUS_SUCCESS;
    

    } while (FALSE);    
        
    if (*pNdisStatus == NDIS_STATUS_SUCCESS)
    {
        //
        // The miniport resume from low power state
        // 
        if (pAdapt->StandingBy == FALSE)
        {
            //
            // If we need to indicate the media connect state
            // 
            if (pAdapt->LastIndicatedStatus != pAdapt->LatestUnIndicateStatus)
            {
               NdisMIndicateStatus(pAdapt->MiniportHandle,
                                        pAdapt->LatestUnIndicateStatus,
                                        (PVOID)NULL,
                                        0);
               NdisMIndicateStatusComplete(pAdapt->MiniportHandle);
               pAdapt->LastIndicatedStatus = pAdapt->LatestUnIndicateStatus;
            }
        }
        else
        {
            //
            // Initialize LatestUnIndicatedStatus
            //
            pAdapt->LatestUnIndicateStatus = pAdapt->LastIndicatedStatus;
        }
        *BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
        *BytesNeeded = 0;
    }
    else
    {
        *BytesRead = 0;
        *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -