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

📄 request.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 4 页
字号:

    NDIS_STATUS_SUCCESS if the request is sent down.

--*/
{
    PWDM_NDIS_REQUEST   wdmNdisRequest = &Adapter->WdmNdisRequest;

    DEBUGP(MP_TRACE, ("--> NICForwardRequest\n"));

    wdmNdisRequest->Oid = Oid;
    wdmNdisRequest->RequestType = RequestType;
    wdmNdisRequest->InformationBuffer = InformationBuffer;
    wdmNdisRequest->InformationBufferLength = InformationBufferLength;
    wdmNdisRequest->BytesNeeded = BytesNeeded;
    wdmNdisRequest->BytesReadOrWritten = BytesReadOrWritten;

    NdisAcquireSpinLock(&Adapter->Lock);
    Adapter->RequestPending = TRUE;    
    NdisReleaseSpinLock(&Adapter->Lock);
    
    MP_INC_REF(Adapter);

    NdisInitializeWorkItem(&wdmNdisRequest->WorkItem, 
                        NICRequestWorkItemCallback, Adapter);
    
    NdisScheduleWorkItem(&wdmNdisRequest->WorkItem);     

    DEBUGP(MP_TRACE, ("<-- NICForwardRequest\n"));
    
    return (NDIS_STATUS_SUCCESS);
}

VOID 
NICRequestWorkItemCallback(
    PNDIS_WORK_ITEM WorkItem, 
    PVOID Context) 
{

    PMP_ADAPTER Adapter = (PMP_ADAPTER)Context;
    PWDM_NDIS_REQUEST wdmNdisRequest = (PWDM_NDIS_REQUEST)WorkItem;
    NDIS_STATUS Status;
    BOOLEAN isResetPending = FALSE;
    
    DEBUGP(MP_TRACE, ("--> NICRequestWorkItemCallback\n"));

    ASSERT(wdmNdisRequest == &Adapter->WdmNdisRequest);

    Status = NICSendRequest(Adapter, 
                    wdmNdisRequest->RequestType,
                    wdmNdisRequest->Oid,
                    wdmNdisRequest->InformationBuffer,
                    wdmNdisRequest->InformationBufferLength,
                    wdmNdisRequest->BytesReadOrWritten,
                    wdmNdisRequest->BytesNeeded
                    );

    //
    // Make sure the multicast list reported by the physical doesn't exceed our
    // hardcoded limit of NIC_MAX_MCAST_LIST.
    //
    if(wdmNdisRequest->Oid == OID_802_3_MAXIMUM_LIST_SIZE){
        if(*(PLONG)wdmNdisRequest->InformationBuffer > NIC_MAX_MCAST_LIST) {
            *(PLONG)wdmNdisRequest->InformationBuffer = NIC_MAX_MCAST_LIST;
        }
    }

    //
    // Check to see if there is any pending reset. If so we should complet it
    // after completing the request.
    //
    NdisAcquireSpinLock(&Adapter->Lock);

    Adapter->RequestPending = FALSE;    
    if(Adapter->ResetPending){
        
        Adapter->ResetPending = FALSE;
        isResetPending = TRUE;
    }     
    
    NdisReleaseSpinLock(&Adapter->Lock);
    
    //
    // Inform NDIS to complete the pending request and reset.
    //
    if(wdmNdisRequest->RequestType == NdisRequestSetInformation){            
        NdisMSetInformationComplete(Adapter->AdapterHandle, Status);
    }else {
        NdisMQueryInformationComplete(Adapter->AdapterHandle, Status);
    }
    
    //
    // NDIS will not send another OID request as long as a reset is pending.
    // So we don't have to worry about another requests sneeking in before
    // we complete the reset.
    //
    if(isResetPending){
        DEBUGP(MP_LOUD, ("Called NdisMResetComplete\n"));        
        NdisMResetComplete(Adapter->AdapterHandle, NDIS_STATUS_SUCCESS, FALSE);
    }
        
    MP_DEC_REF(Adapter);     

    DEBUGP(MP_TRACE, ("<-- NICRequestWorkItemCallback: %x\n", Status));

    return;
}


NDIS_STATUS
NICSendRequest(
    IN PMP_ADAPTER                  Adapter,
    IN NDIS_REQUEST_TYPE            RequestType,
    IN NDIS_OID                     Oid,
    IN PVOID                        InformationBuffer,
    IN ULONG                        InformationBufferLength,
    OUT PULONG                      BytesReadOrWritten,
    OUT PULONG                      BytesNeeded
    )
/*++

Routine Description:

    Utility routine that forwards an NDIS request made on a Adapter to the
    target driver. 
    
Arguments:


Return Value:


--*/
{
    NDIS_STATUS         Status;
    PNDISPROT_QUERY_OID pQueryOid = NULL;
    PNDISPROT_SET_OID   pSetOid = NULL;    
    PVOID               buffer;
    NTSTATUS            ntStatus;
    ULONG               length, bytes;
    
    DEBUGP(MP_TRACE, ("--> NICSendRequest\n"));


    PAGED_CODE();

    //
    // Allocate memory for adapter context
    //
    
    if(NdisRequestQueryInformation){
        length = sizeof(NDISPROT_QUERY_OID) + InformationBufferLength - sizeof(ULONG);
    }else{
        length = sizeof(NDISPROT_SET_OID) + InformationBufferLength - sizeof(ULONG);
    }
    
    Status = NdisAllocateMemoryWithTag(&buffer, length, NIC_TAG);
    if(Status != NDIS_STATUS_SUCCESS)
    {
        DEBUGP(MP_ERROR, ("NICSendRequest failed to allocate memory\n"));
        goto End;
    }

    *BytesNeeded = 0;
    
    switch (RequestType)
    {
        case NdisRequestQueryInformation:
            
            
            pQueryOid = (PNDISPROT_QUERY_OID) buffer;            
            pQueryOid->Oid = Oid;
            
            ntStatus = NICMakeSynchronousIoctl(
                            Adapter->TargetDeviceObject,
                            Adapter->FileObject,
                            IOCTL_NDISPROT_QUERY_OID_VALUE,
                            pQueryOid,
                            length,
                            pQueryOid,
                            length,
                            &bytes
                            );
            if(!NT_SUCCESS(ntStatus)) {
                
                DEBUGP(MP_ERROR, ("NICMakeSynchronousIoctl failed %x\n", 
                                    ntStatus));
                *BytesNeeded = bytes;
                
            } else {
            
            
                RtlCopyMemory(InformationBuffer, pQueryOid->Data, 
                                        InformationBufferLength);
                *BytesReadOrWritten = bytes - FIELD_OFFSET(NDISPROT_QUERY_OID, Data);
            }
            
            NT_STATUS_TO_NDIS_STATUS(ntStatus, &Status);
            break;

        case NdisRequestSetInformation:

            pSetOid = (PNDISPROT_SET_OID) buffer;            
            pSetOid->Oid = Oid;
            
            RtlCopyMemory(pSetOid->Data, InformationBuffer, 
                                    InformationBufferLength);
            
            ntStatus = NICMakeSynchronousIoctl(
                            Adapter->TargetDeviceObject,
                            Adapter->FileObject,
                            IOCTL_NDISPROT_SET_OID_VALUE,
                            pSetOid,
                            length,
                            NULL,
                            0,
                            &bytes
                            );
            if(!NT_SUCCESS(ntStatus)) {
                
                DEBUGP(MP_ERROR, ("NICMakeSynchronousIoctl failed %x\n", ntStatus)); 
                *BytesNeeded = bytes;
            }else {            
                //
                // Unfortunately, the NDISPROT driver returns 0 as the number of
                // bytes read. So let us just use the InformationBufferLength.
                //
                *BytesReadOrWritten = InformationBufferLength;
            }
            
            NT_STATUS_TO_NDIS_STATUS(ntStatus, &Status);            
            break;

        default:
            ASSERT(FALSE);
            break;
    }

End:
    if(buffer){
        NdisFreeMemory(buffer, length, 0);
    }
    
    DEBUGP(MP_TRACE, ("<-- NICSendRequest %x\n", Status));
    
    return (Status);
}

PUCHAR 
DbgGetOidName(ULONG oid)
{
    PCHAR oidName;

    switch (oid){

        #undef MAKECASE
        #define MAKECASE(oidx) case oidx: oidName = #oidx; break;

        MAKECASE(OID_GEN_SUPPORTED_LIST)
        MAKECASE(OID_GEN_HARDWARE_STATUS)
        MAKECASE(OID_GEN_MEDIA_SUPPORTED)
        MAKECASE(OID_GEN_MEDIA_IN_USE)
        MAKECASE(OID_GEN_MAXIMUM_LOOKAHEAD)
        MAKECASE(OID_GEN_MAXIMUM_FRAME_SIZE)
        MAKECASE(OID_GEN_LINK_SPEED)
        MAKECASE(OID_GEN_TRANSMIT_BUFFER_SPACE)
        MAKECASE(OID_GEN_RECEIVE_BUFFER_SPACE)
        MAKECASE(OID_GEN_TRANSMIT_BLOCK_SIZE)
        MAKECASE(OID_GEN_RECEIVE_BLOCK_SIZE)
        MAKECASE(OID_GEN_VENDOR_ID)
        MAKECASE(OID_GEN_VENDOR_DESCRIPTION)
        MAKECASE(OID_GEN_CURRENT_PACKET_FILTER)
        MAKECASE(OID_GEN_CURRENT_LOOKAHEAD)
        MAKECASE(OID_GEN_DRIVER_VERSION)
        MAKECASE(OID_GEN_MAXIMUM_TOTAL_SIZE)
        MAKECASE(OID_GEN_PROTOCOL_OPTIONS)
        MAKECASE(OID_GEN_MAC_OPTIONS)
        MAKECASE(OID_GEN_MEDIA_CONNECT_STATUS)
        MAKECASE(OID_GEN_MAXIMUM_SEND_PACKETS)
        MAKECASE(OID_GEN_VENDOR_DRIVER_VERSION)
        MAKECASE(OID_GEN_SUPPORTED_GUIDS)
        MAKECASE(OID_GEN_NETWORK_LAYER_ADDRESSES)
        MAKECASE(OID_GEN_TRANSPORT_HEADER_OFFSET)
        MAKECASE(OID_GEN_MEDIA_CAPABILITIES)
        MAKECASE(OID_GEN_PHYSICAL_MEDIUM)
        MAKECASE(OID_GEN_XMIT_OK)
        MAKECASE(OID_GEN_RCV_OK)
        MAKECASE(OID_GEN_XMIT_ERROR)
        MAKECASE(OID_GEN_RCV_ERROR)
        MAKECASE(OID_GEN_RCV_NO_BUFFER)
        MAKECASE(OID_GEN_DIRECTED_BYTES_XMIT)
        MAKECASE(OID_GEN_DIRECTED_FRAMES_XMIT)
        MAKECASE(OID_GEN_MULTICAST_BYTES_XMIT)
        MAKECASE(OID_GEN_MULTICAST_FRAMES_XMIT)
        MAKECASE(OID_GEN_BROADCAST_BYTES_XMIT)
        MAKECASE(OID_GEN_BROADCAST_FRAMES_XMIT)
        MAKECASE(OID_GEN_DIRECTED_BYTES_RCV)
        MAKECASE(OID_GEN_DIRECTED_FRAMES_RCV)
        MAKECASE(OID_GEN_MULTICAST_BYTES_RCV)
        MAKECASE(OID_GEN_MULTICAST_FRAMES_RCV)
        MAKECASE(OID_GEN_BROADCAST_BYTES_RCV)
        MAKECASE(OID_GEN_BROADCAST_FRAMES_RCV)
        MAKECASE(OID_GEN_RCV_CRC_ERROR)
        MAKECASE(OID_GEN_TRANSMIT_QUEUE_LENGTH)
        MAKECASE(OID_GEN_GET_TIME_CAPS)
        MAKECASE(OID_GEN_GET_NETCARD_TIME)
        MAKECASE(OID_GEN_NETCARD_LOAD)
        MAKECASE(OID_GEN_DEVICE_PROFILE)
        MAKECASE(OID_GEN_INIT_TIME_MS)
        MAKECASE(OID_GEN_RESET_COUNTS)
        MAKECASE(OID_GEN_MEDIA_SENSE_COUNTS)
        MAKECASE(OID_PNP_CAPABILITIES)
        MAKECASE(OID_PNP_SET_POWER)
        MAKECASE(OID_PNP_QUERY_POWER)
        MAKECASE(OID_PNP_ADD_WAKE_UP_PATTERN)
        MAKECASE(OID_PNP_REMOVE_WAKE_UP_PATTERN)
        MAKECASE(OID_PNP_ENABLE_WAKE_UP)
        MAKECASE(OID_802_3_PERMANENT_ADDRESS)
        MAKECASE(OID_802_3_CURRENT_ADDRESS)
        MAKECASE(OID_802_3_MULTICAST_LIST)
        MAKECASE(OID_802_3_MAXIMUM_LIST_SIZE)
        MAKECASE(OID_802_3_MAC_OPTIONS)
        MAKECASE(OID_802_3_RCV_ERROR_ALIGNMENT)
        MAKECASE(OID_802_3_XMIT_ONE_COLLISION)
        MAKECASE(OID_802_3_XMIT_MORE_COLLISIONS)
        MAKECASE(OID_802_3_XMIT_DEFERRED)
        MAKECASE(OID_802_3_XMIT_MAX_COLLISIONS)
        MAKECASE(OID_802_3_RCV_OVERRUN)
        MAKECASE(OID_802_3_XMIT_UNDERRUN)
        MAKECASE(OID_802_3_XMIT_HEARTBEAT_FAILURE)
        MAKECASE(OID_802_3_XMIT_TIMES_CRS_LOST)
        MAKECASE(OID_802_3_XMIT_LATE_COLLISIONS)

        default: 
            oidName = "<** UNKNOWN OID **>";
            break;
    }

    return oidName;
}


⌨️ 快捷键说明

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