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

📄 protocol.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
                                    InformationBuffer;
                pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength =
                                    InformationBufferLength;
        
                break;

            case NdisRequestSetInformation:
                pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
                pNdisRequest->DATA.SET_INFORMATION.InformationBuffer =
                                    InformationBuffer;
                pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength =
                                    InformationBufferLength;
        
                break;
            
            default:
                ASSERT(FALSE);
                break;
        }

        NdisRequest(&Status,
                    pAdapt->BindingHandle,
                    pNdisRequest);
        
        if (Status != NDIS_STATUS_PENDING)
        {
            PtRequestComplete(
                (NDIS_HANDLE)pAdapt,
                pNdisRequest,
                Status);
        }
    }
    while (FALSE);
}

            
VOID
PtUnbindAdapter(
    OUT PNDIS_STATUS            Status,
    IN  NDIS_HANDLE             ProtocolBindingContext,
    IN  NDIS_HANDLE             UnbindContext
    )
/*++

Routine Description:

    Called by NDIS when we are required to unbind to the adapter below.
    Go through all VELANs on the adapter and shut them down.

Arguments:

    Status                    Placeholder for return status
    ProtocolBindingContext    Pointer to the adapter structure
    UnbindContext             Context for NdisUnbindComplete() if this pends

Return Value:

    Status from closing the binding.

--*/
{
    PADAPT          pAdapt =(PADAPT)ProtocolBindingContext;
    PLIST_ENTRY     p;
    PVELAN          pVElan = NULL;
    LOCK_STATE      LockState;

	UNREFERENCED_PARAMETER(UnbindContext);
	
    DBGPRINT(MUX_LOUD, ("==> PtUnbindAdapter: Adapt %p\n", pAdapt));

    //
    // Stop all VELANs associated with the adapter.
    // Repeatedly find the first unprocessed VELAN on
    // the adapter, mark it, and stop it.
    //
    MUX_ACQUIRE_ADAPT_READ_LOCK(pAdapt, &LockState);

    do
    {
        for (p = pAdapt->VElanList.Flink;
             p != &pAdapt->VElanList;
             p = p->Flink)
        {
            pVElan = CONTAINING_RECORD(p, VELAN, Link);
            if (!pVElan->DeInitializing)
            {
                pVElan->DeInitializing = TRUE;
                break;
            }
        }

        if (p != &pAdapt->VElanList)
        {
            ASSERT(pVElan == CONTAINING_RECORD(p, VELAN, Link));

            //
            // Got a VELAN to stop. Add a temp ref
            // so that the VELAN won't go away when
            // we release the ADAPT lock below.
            //
            PtReferenceVElan(pVElan, (PUCHAR)"UnbindTemp");

            //
            // Release the read lock because we want to
            // run StopVElan at passive IRQL.
            //
            MUX_RELEASE_ADAPT_READ_LOCK(pAdapt, &LockState);
    
            PtStopVElan(pVElan);
    
            PtDereferenceVElan(pVElan, (PUCHAR)"UnbindTemp");

            MUX_ACQUIRE_ADAPT_READ_LOCK(pAdapt, &LockState);
        }
        else
        {
            //
            // No unmarked VELAN, so exit.
            //
            break;
        }
    }
    while (TRUE);

    //
    // Wait until all VELANs are unlinked from the adapter.
    // This is so that we don't attempt to forward down packets
    // and/or requests from VELANs after calling NdisCloseAdapter.
    //
    while (!IsListEmpty(&pAdapt->VElanList))
    {
        MUX_RELEASE_ADAPT_READ_LOCK(pAdapt, &LockState);

        DBGPRINT(MUX_INFO, ("PtUnbindAdapter: pAdapt %p, VELANlist not yet empty\n",
                    pAdapt));

        NdisMSleep(2000);

        MUX_ACQUIRE_ADAPT_READ_LOCK(pAdapt, &LockState);
    }

    MUX_RELEASE_ADAPT_READ_LOCK(pAdapt, &LockState);

    //
    // Close the binding to the lower adapter.
    //
    if (pAdapt->BindingHandle != NULL)
    {
        NdisResetEvent(&pAdapt->Event);

        NdisCloseAdapter(Status, pAdapt->BindingHandle);

        //
        // Wait for it to complete.
        //
        if (*Status == NDIS_STATUS_PENDING)
        {
             NdisWaitEvent(&pAdapt->Event, 0);
             *Status = pAdapt->Status;
        }
    }
    else
    {
        //
        // Binding Handle should not be NULL.
        //
        *Status = NDIS_STATUS_FAILURE;
        ASSERT(0);
    }

    //
    // Remove the adapter from the global AdapterList
    //
    
    MUX_ACQUIRE_MUTEX(&GlobalMutex);

    RemoveEntryList(&pAdapt->Link);

    MUX_RELEASE_MUTEX(&GlobalMutex);

    //
    // Free all the resources associated with this Adapter except the
    // ADAPT struct itself, because that will be freed by 
    // PtDereferenceAdapter call when the reference drops to zero. 
    // Note: Every VELAN associated with this Adapter takes a ref count
    // on it. So the adapter memory wouldn't be freed until all the VELANs
    // are shutdown. 
    //
    
    PtDereferenceAdapter(pAdapt, (PUCHAR)"Unbind");
    DBGPRINT(MUX_INFO, ("<== PtUnbindAdapter: Adapt %p\n", pAdapt));
}



VOID
PtCloseAdapterComplete(
    IN    NDIS_HANDLE            ProtocolBindingContext,
    IN    NDIS_STATUS            Status
    )
/*++

Routine Description:

    Completion for the CloseAdapter call.

Arguments:

    ProtocolBindingContext    Pointer to the adapter structure
    Status                    Completion status

Return Value:

    None.

--*/
{
    PADAPT      pAdapt =(PADAPT)ProtocolBindingContext;

    DBGPRINT(MUX_INFO, ("==> PtCloseAdapterComplete: Adapt %p, Status %x\n", 
                                pAdapt, Status));

    pAdapt->Status = Status;
    NdisSetEvent(&pAdapt->Event);
}


VOID
PtResetComplete(
    IN  NDIS_HANDLE            ProtocolBindingContext,
    IN  NDIS_STATUS            Status
    )
/*++

Routine Description:

    Completion for the reset.

Arguments:

    ProtocolBindingContext    Pointer to the adapter structure
    Status                    Completion status

Return Value:

    None.

--*/
{

#if DBG    
    PADAPT    pAdapt =(PADAPT)ProtocolBindingContext;
#endif

#if !DBG
    UNREFERENCED_PARAMETER(ProtocolBindingContext);
    UNREFERENCED_PARAMETER(Status);
#endif

    DBGPRINT(MUX_ERROR, ("==> PtResetComplete: Adapt %p, Status %x\n", 
                                pAdapt, Status));

    //
    // We never issue a reset, so we should not be here.
    //
    ASSERT(0);
}


VOID
PtRequestComplete(
    IN  NDIS_HANDLE                 ProtocolBindingContext,
    IN  PNDIS_REQUEST               NdisRequest,
    IN  NDIS_STATUS                 Status
    )
/*++

Routine Description:

    Completion handler for an NDIS request sent to a lower
    miniport.

Arguments:

    ProtocolBindingContext    Pointer to the adapter structure
    NdisRequest               The completed request
    Status                    Completion status

Return Value:

    None

--*/
{
    PADAPT              pAdapt = (PADAPT)ProtocolBindingContext;
    PMUX_NDIS_REQUEST   pMuxNdisRequest;

    pMuxNdisRequest = CONTAINING_RECORD(NdisRequest, MUX_NDIS_REQUEST, Request);

    ASSERT(pMuxNdisRequest->pCallback != NULL);

    //
    // Completion is handled by the callback routine:
    //
    (*pMuxNdisRequest->pCallback)(pAdapt, 
                                  pMuxNdisRequest,
                                  Status);

}


VOID
PtCompleteForwardedRequest(
    IN PADAPT                       pAdapt,
    IN PMUX_NDIS_REQUEST            pMuxNdisRequest,
    IN NDIS_STATUS                  Status
    )
/*++

Routine Description:

    Handle completion of an NDIS request that was originally
    submitted to our VELAN miniport and was forwarded down
    to the lower binding.

    We do some postprocessing, to cache the results of
    certain queries.

Arguments:

    pAdapt  - Adapter on which the request was forwarded
    pMuxNdisRequest - super-struct for request
    Status - request completion status

Return Value:

    None

--*/
{
    PVELAN              pVElan = NULL;
    PNDIS_REQUEST       pNdisRequest = &pMuxNdisRequest->Request;
    NDIS_OID            Oid = pNdisRequest->DATA.SET_INFORMATION.Oid;

    UNREFERENCED_PARAMETER(pAdapt);
    
    //
    // Get the originating VELAN. The VELAN will not be dereferenced
    // away until the pended request is completed.
    //
    pVElan = pMuxNdisRequest->pVElan;

    ASSERT(pVElan != NULL);
    ASSERT(pMuxNdisRequest == &pVElan->Request);
    
    if (Status != NDIS_STATUS_SUCCESS)
    {
        DBGPRINT(MUX_WARN, ("PtCompleteForwardedReq: pVElan %p, OID %x, Status %x\n", 
                    pVElan,
                    pMuxNdisRequest->Request.DATA.QUERY_INFORMATION.Oid,
                    Status));
    }

    //
    // Complete the original request.
    //
    switch (pNdisRequest->RequestType)
    {
        case NdisRequestQueryInformation:

            *pVElan->BytesReadOrWritten = 
                    pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
            *pVElan->BytesNeeded = 
                    pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;

            //
            // Before completing the request, do any necessary
            // post-processing.
            //
            Oid = pNdisRequest->DATA.QUERY_INFORMATION.Oid;
            if (Status == NDIS_STATUS_SUCCESS)
            {
                if (Oid == OID_GEN_LINK_SPEED)
                {
                    NdisMoveMemory (&pVElan->LinkSpeed,
                                    pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
                                    sizeof(ULONG));
                }
                else if (Oid == OID_PNP_CAPABILITIES)
                {
                    PtPostProcessPnPCapabilities(pVElan,
                                                 pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
                                                 pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength);
                }
            }

            NdisMQueryInformationComplete(pVElan->MiniportAdapterHandle, Status);

            break;

        case NdisRequestSetInformation:

            *pVElan->BytesReadOrWritten =
                    pNdisRequest->DATA.SET_INFORMATION.BytesRead;
            *pVElan->BytesNeeded =
                    pNdisRequest->DATA.SET_INFORMATION.BytesNeeded;

            //
            // Before completing the request, cache relevant information
            // in our structure.
            //
            if (Status == NDIS_STATUS_SUCCESS)
            {
                Oid = pNdisRequest->DATA.SET_INFORMATION.Oid;
                switch (Oid)
                {
                    case OID_GEN_CURRENT_LOOKAHEAD:
                        NdisMoveMemory(&pVElan->LookAhead,
                                 pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
                                 sizeof(ULONG));
                        break;

                    default:
                        break;
                }
            }

            NdisMSetInformationComplete(pVElan->MiniportAdapterHandle, Status);

            break;

        default:
            ASSERT(FALSE);
            break;
    }

    MUX_DECR_PENDING_SENDS(pVElan);

⌨️ 快捷键说明

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