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

📄 protocol.c

📁 vc++网络程序设计实例详解 人民邮电出版社5-6章源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    else
    {
        NdisReleaseSpinLock(&pAdapt->Lock);
    }
#ifndef WIN9X
    //
    // Check if we had called NdisIMInitializeDeviceInstanceEx and
    // we are awaiting a call to MiniportInitialize.
    //
    if (pAdapt->MiniportInitPending == TRUE)
    {
        //
        // Try to cancel the pending IMInit process.
        //
        LocalStatus = NdisIMCancelInitializeDeviceInstance(
                        DriverHandle,
                        &pAdapt->DeviceName);

        if (LocalStatus == NDIS_STATUS_SUCCESS)
        {
            //
            // Successfully cancelled IM Initialization; our
            // Miniport Initialize routine will not be called
            // for this device.
            //
            pAdapt->MiniportInitPending = FALSE;
            ASSERT(pAdapt->MiniportHandle == NULL);
        }
        else
        {
            //
            // Our Miniport Initialize routine will be called
            // (may be running on another thread at this time).
            // Wait for it to finish.
            //
            NdisWaitEvent(&pAdapt->MiniportInitEvent, 0);
            ASSERT(pAdapt->MiniportInitPending == FALSE);
        }

    }
#endif // !WIN9X

    //
    // Call NDIS to remove our device-instance. We do most of the work
    // inside the HaltHandler.
    //
    // The Handle will be NULL if our miniport Halt Handler has been called or
    // if the IM device was never initialized
    //
    
    if (pAdapt->MiniportHandle != NULL)
    {
        *Status = NdisIMDeInitializeDeviceInstance(pAdapt->MiniportHandle);

        if (*Status != NDIS_STATUS_SUCCESS)
        {
            *Status = NDIS_STATUS_FAILURE;
        }
    }
    else
    {
        //
        // We need to do some work here. 
        // Close the binding below us 
        // and release the memory allocated.
        //
        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;
            }
            pAdapt->BindingHandle = NULL;
        }
        else
        {
            //
            // Both Our MiniportHandle and Binding Handle  should not be NULL.
            //
            *Status = NDIS_STATUS_FAILURE;
            ASSERT(0);
        }

        //
        //    Free the memory here, if was not released earlier(by calling the HaltHandler)
        //
   // BEGIN_PTUSERIO	
				
			// 移除协议对适配器的引用
			PtDerefAdapter(pAdapt);

// END_PTUSERIO
    }

    DBGPRINT(("<== PtUnbindAdapter: Adapt %p\n", pAdapt));
}

VOID
PtUnloadProtocol(
    VOID
)
{
    NDIS_STATUS Status;

    if (ProtHandle != NULL)
    {
        NdisDeregisterProtocol(&Status, ProtHandle);
        ProtHandle = NULL;
    }

    DBGPRINT(("PtUnloadProtocol: done!\n"));
}



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(("CloseAdapterComplete: 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.

--*/
{

    UNREFERENCED_PARAMETER(ProtocolBindingContext);
    UNREFERENCED_PARAMETER(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 the previously posted request. All OIDS
    are completed by and sent to the same miniport that they were requested for.
    If Oid == OID_PNP_QUERY_POWER then the data structure needs to returned with all entries =
    NdisDeviceStateUnspecified

Arguments:

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

Return Value:

    None

--*/
{
    PADAPT        pAdapt = (PADAPT)ProtocolBindingContext;
    NDIS_OID      Oid = pAdapt->Request.DATA.SET_INFORMATION.Oid ;


// BEGIN_PTUSERIO

   if(NdisRequest != &(pAdapt->Request))
   {
	  DevRequestComplete(pAdapt, NdisRequest,Status);
      return;

   }
// END_PTUSERIO

    //
    // Since our request is not outstanding anymore
    //
    ASSERT(pAdapt->OutstandingRequests == TRUE);

    pAdapt->OutstandingRequests = FALSE;

    //
    // Complete the Set or Query, and fill in the buffer for OID_PNP_CAPABILITIES, if need be.
    //
    switch (NdisRequest->RequestType)
    {
      case NdisRequestQueryInformation:

        //
        // We never pass OID_PNP_QUERY_POWER down.
        //
        ASSERT(Oid != OID_PNP_QUERY_POWER);

        if ((Oid == OID_PNP_CAPABILITIES) && (Status == NDIS_STATUS_SUCCESS))
        {
            MPQueryPNPCapabilities(pAdapt, &Status);
        }
        *pAdapt->BytesReadOrWritten = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
        *pAdapt->BytesNeeded = NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;

        if ((Oid == OID_GEN_MAC_OPTIONS) && (Status == NDIS_STATUS_SUCCESS))
        {
            //
            // Remove the no-loopback bit from mac-options. In essence we are
            // telling NDIS that we can handle loopback. We don't, but the
            // interface below us does. If we do not do this, then loopback
            // processing happens both below us and above us. This is wasteful
            // at best and if Netmon is running, it will see multiple copies
            // of loopback packets when sniffing above us.
            //
            // Only the lowest miniport is a stack of layered miniports should
            // ever report this bit set to NDIS.
            //
            *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer &= ~NDIS_MAC_OPTION_NO_LOOPBACK;
        }

        NdisMQueryInformationComplete(pAdapt->MiniportHandle,
                                      Status);
        break;

      case NdisRequestSetInformation:

        ASSERT( Oid != OID_PNP_SET_POWER);

        *pAdapt->BytesReadOrWritten = NdisRequest->DATA.SET_INFORMATION.BytesRead;
        *pAdapt->BytesNeeded = NdisRequest->DATA.SET_INFORMATION.BytesNeeded;
        NdisMSetInformationComplete(pAdapt->MiniportHandle,
                                    Status);
        break;

      default:
        ASSERT(0);
        break;
    }
    
}


VOID
PtStatus(
    IN  NDIS_HANDLE         ProtocolBindingContext,
    IN  NDIS_STATUS         GeneralStatus,
    IN  PVOID               StatusBuffer,
    IN  UINT                StatusBufferSize
    )
/*++

Routine Description:

    Status handler for the lower-edge(protocol).

Arguments:

    ProtocolBindingContext    Pointer to the adapter structure
    GeneralStatus             Status code
    StatusBuffer              Status buffer
    StatusBufferSize          Size of the status buffer

Return Value:

    None

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

    //
    // Pass up this indication only if the upper edge miniport is initialized
    // and powered on. Also ignore indications that might be sent by the lower
    // miniport when it isn't at D0.
    //
    if ((pAdapt->MiniportHandle != NULL)  &&
        (pAdapt->MPDeviceState == NdisDeviceStateD0) &&
        (pAdapt->PTDeviceState == NdisDeviceStateD0))    
    {
        if ((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) || 
            (GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT))
        {
            
            pAdapt->LastIndicatedStatus = GeneralStatus;
        }
        NdisMIndicateStatus(pAdapt->MiniportHandle,
                            GeneralStatus,
                            StatusBuffer,
                            StatusBufferSize);
    }
    //
    // Save the last indicated media status 
    //
    else
    {
        if ((pAdapt->MiniportHandle != NULL) && 
        ((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) || 
            (GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT)))
        {
            pAdapt->LatestUnIndicateStatus = GeneralStatus;
        }
    }
    
}


VOID
PtStatusComplete(
    IN NDIS_HANDLE            ProtocolBindingContext
    )
/*++

Routine Description:


Arguments:


Return Value:


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

    //
    // Pass up this indication only if the upper edge miniport is initialized
    // and powered on. Also ignore indications that might be sent by the lower
    // miniport when it isn't at D0.
    //
    if ((pAdapt->MiniportHandle != NULL)  &&
        (pAdapt->MPDeviceState == NdisDeviceStateD0) &&
        (pAdapt->PTDeviceState == NdisDeviceStateD0))    
    {
        NdisMIndicateStatusComplete(pAdapt->MiniportHandle);
    }
}


VOID
PtSendComplete(
    IN  NDIS_HANDLE            ProtocolBindingContext,
    IN  PNDIS_PACKET           Packet,
    IN  NDIS_STATUS            Status
    )
/*++

Routine Description:

    Called by NDIS when the miniport below had completed a send. We should
    complete the corresponding upper-edge send this represents.

⌨️ 快捷键说明

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