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

📄 ndisreq.c

📁 ndis windows网络驱动程序的范例
💻 C
字号:
/*++

Copyright (c) 1996  Microsoft Corporation

Module Name:

    ndisreq.c

Abstract:

    routines for passing NdisRequests up and down

Author:

    Jim Mateer 

Environment:

    Kernel Mode

Revision History:

--*/

#include "ImSamp.h"


#pragma hdrstop






NDIS_STATUS
MPQueryInformation(
    IN  NDIS_HANDLE MiniportAdapterContext,
    IN  NDIS_OID Oid,
    IN  PVOID InformationBuffer,
    IN  ULONG InformationBufferLength,
    OUT PULONG BytesWritten,
    OUT PULONG BytesNeeded
    );

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

STATIC NDIS_STATUS
MakeNdisRequest(
    IN  PADAPTER Adapter,
    IN  NDIS_REQUEST_TYPE RequestType,
    IN  NDIS_OID Oid,
    IN  PVOID InformationBuffer,
    IN  ULONG InformationBufferLength,
    OUT PULONG BytesReadOrWritten,
    OUT PULONG BytesNeeded,
    LOCAL_NDISREQUEST_COMPLETION_FUNCTION CompletionFunc
    );

VOID
CLRequestComplete(
    IN  NDIS_HANDLE ProtocolBindingContext,
    IN  PNDIS_REQUEST NdisRequestBuf,
    IN  NDIS_STATUS Status
    );

NDIS_STATUS
MakeLocalNdisRequest(
    PADAPTER Adapter,
    NDIS_OID Oid,
    PVOID Buffer,
    ULONG BufferSize,
    LOCAL_NDISREQUEST_COMPLETION_FUNCTION CompletionFunc OPTIONAL
    );




NDIS_STATUS
MPQueryInformation(
	IN	NDIS_HANDLE				MiniportAdapterContext,
	IN	NDIS_OID				Oid,
	IN	PVOID					InformationBuffer,
	IN	ULONG					InformationBufferLength,
	OUT PULONG					BytesWritten,
	OUT PULONG					BytesNeeded
	)

/*++

Routine Description:

    handler for QueryInformation NdisRequests. We note the type of request and
    pass the request on to a common rebundling routine

Arguments:

    See the DDK...

Return Values:

    return the value returned to us by the underlying adapter

--*/

{
    PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;

    ImDbgOut(DBG_TRACE, DBG_MINIPORT, ("(%08X) MPQueryInformation:\n", Adapter ));

    IMStructAssert( Adapter );

    return MakeNdisRequest(Adapter,
                           NdisRequestQueryInformation,
                           Oid,
                           InformationBuffer,
                           InformationBufferLength,
                           BytesWritten,
                           BytesNeeded,
                           NULL);
                         
} // MPQueryInformation


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:

    handler for SetInformation NdisRequests. We note the type of request and
    pass the request on to a common rebundling routine

Arguments:

    See the DDK...

Return Values:

    return the value returned to us by the underlying adapter

--*/

{
    PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;

    ImDbgOut(DBG_TRACE, DBG_MINIPORT, ("(%08X) MPSetInformation\n", Adapter ));

    IMStructAssert( Adapter );

    return MakeNdisRequest(Adapter,
                           NdisRequestSetInformation,
                           Oid,
                           InformationBuffer,
                           InformationBufferLength,
                           BytesRead,
                           BytesNeeded,
                           NULL);
                         
} // MPSetInformation


STATIC NDIS_STATUS
MakeNdisRequest(
	IN	PADAPTER				Adapter,
    IN  NDIS_REQUEST_TYPE       RequestType,
	IN	NDIS_OID				Oid,
	IN	PVOID					InformationBuffer,
	IN	ULONG					InformationBufferLength,
	OUT PULONG					BytesReadOrWritten,
	OUT PULONG					BytesNeeded,
    LOCAL_NDISREQUEST_COMPLETION_FUNCTION CompletionFunc
	)

/*++

Routine Description:

    common handler for set and query  information, local ndis request.
    An NDIS_REQUEST is built and issued to the underlying MP

Arguments:

    See the DDK...

    CompletionFunc - pointer to a function that gets called when the request
        completion handler has been called. Only used for local requests.

    RequestType also includes NdisRequestLocal{Set,Query}Info which is used
    to indicate a local request meaning the request is originated by the
    ImSamp protocol section and needs no further completion

Return Values:

    return the value returned to us by the underlying adapter

--*/

{
    PIM_NDIS_REQUEST IMReqBuffer;
    NDIS_STATUS Status;
	
    ImDbgOut(DBG_TRACE, DBG_MINIPORT, ("(%08X) MakeNdisRequest: OID %08X\n", Adapter, Oid ));

		          
    IMReqBuffer = NdisAllocateFromNPagedLookasideList( &NdisRequestLL );

  
    if ( IMReqBuffer == NULL ) {

        return NDIS_STATUS_RESOURCES;

    }

    if ( RequestType == NdisRequestSetInformation ||
         RequestType == NdisRequestLocalSetInfo ) {

        IMReqBuffer->ReqBuffer.RequestType = NdisRequestSetInformation;
        IMReqBuffer->LocalRequest = ( RequestType == NdisRequestLocalSetInfo );
        IMReqBuffer->ReqBuffer.DATA.SET_INFORMATION.Oid = Oid;
        IMReqBuffer->ReqBuffer.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
        IMReqBuffer->ReqBuffer.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;

    } else {

        IMAssert(RequestType == NdisRequestQueryInformation ||
                RequestType == NdisRequestLocalQueryInfo);
  
        IMReqBuffer->ReqBuffer.RequestType = NdisRequestQueryInformation;
        IMReqBuffer->LocalRequest = ( RequestType == NdisRequestLocalQueryInfo );
        IMReqBuffer->ReqBuffer.DATA.QUERY_INFORMATION.Oid = Oid;
        IMReqBuffer->ReqBuffer.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
        IMReqBuffer->ReqBuffer.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;

    }

    //
    // store the pointers to BytesReadOrWritten and BytesNeeded so they can be
    // updated in the completion routine if necessary. Save the completion func
    //

    IMReqBuffer->BytesReadOrWritten = BytesReadOrWritten;
    IMReqBuffer->BytesNeeded = BytesNeeded;
    IMReqBuffer->LocalCompletionFunc = CompletionFunc;

// This call requires an updated version of ndis.h. The version included with the 
//Jan, 1997 DDK release will not work.
// The new ndis.h can be found on FTP.MICROSOFT.COM/developr/win_dk/ndis/

    NdisRequest( &Status, 
                 (NDIS_HANDLE) Adapter->LowerMPHandle, 
                 (PNDIS_REQUEST)IMReqBuffer); 

    if ( Status != NDIS_STATUS_PENDING ) {

        CLRequestComplete( (NDIS_HANDLE)Adapter, (PNDIS_REQUEST)IMReqBuffer, Status );

    }

    return NDIS_STATUS_PENDING;
}                               // MakeNdisRequest


VOID
CLRequestComplete(
    IN  NDIS_HANDLE     ProtocolBindingContext,
    IN  PNDIS_REQUEST   NdisRequestBuf,
    IN  NDIS_STATUS     Status
    )

/*++

Routine Description:

    Completion routine for NdisRequest. Stuff our block back on the lookaside
    list and call the appropriate completion routine

Arguments:

    See the DDK...

Return Values:

    None

--*/

{
    PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
    PIM_NDIS_REQUEST IMReqBuffer;
    BOOLEAN CallQueryInfoCompletion;
    NDIS_OID Oid;

    IMReqBuffer = CONTAINING_RECORD( NdisRequestBuf, IM_NDIS_REQUEST, ReqBuffer );

    ImDbgOut(DBG_TRACE, DBG_PROTOCOL, ("(%08X) CLRequestComplete: OID %08X\n",
                                       Adapter,
                                       IMReqBuffer->ReqBuffer.DATA.SET_INFORMATION.Oid));

    IMStructAssert( Adapter );

    //
    // set the output vars based on what we got back from the underlying adapter
    // also grab the Oid and remember which completion func we're supposed to
    // call
    //

    if ( IMReqBuffer->ReqBuffer.RequestType == NdisRequestSetInformation ) {

        *IMReqBuffer->BytesReadOrWritten =
            IMReqBuffer->ReqBuffer.DATA.SET_INFORMATION.BytesRead;
        *IMReqBuffer->BytesNeeded =
            IMReqBuffer->ReqBuffer.DATA.SET_INFORMATION.BytesNeeded;
        Oid = IMReqBuffer->ReqBuffer.DATA.SET_INFORMATION.Oid;

        CallQueryInfoCompletion = FALSE;

    } else {

        IMAssert(IMReqBuffer->ReqBuffer.RequestType == NdisRequestQueryInformation );

        *IMReqBuffer->BytesReadOrWritten =
            IMReqBuffer->ReqBuffer.DATA.QUERY_INFORMATION.BytesWritten;
        *IMReqBuffer->BytesNeeded =
            IMReqBuffer->ReqBuffer.DATA.QUERY_INFORMATION.BytesNeeded;
        Oid = IMReqBuffer->ReqBuffer.DATA.QUERY_INFORMATION.Oid;

        CallQueryInfoCompletion = TRUE;
    }

    //
    // see if the underlying MP supports NdisSendPackets. if not, fake it by
    // saying we support one.
    //

    if ( Oid == OID_GEN_MAXIMUM_SEND_PACKETS && !NT_SUCCESS( Status )) {

        *((PULONG)IMReqBuffer->ReqBuffer.DATA.QUERY_INFORMATION.InformationBuffer) = 1;
        Status = NDIS_STATUS_SUCCESS;
    }

    //
    // if querying mac options, add full dux option.
    //

    if ( Oid == OID_GEN_MAC_OPTIONS ) {

        *((PULONG)IMReqBuffer->ReqBuffer.DATA.QUERY_INFORMATION.InformationBuffer) |=
            NDIS_MAC_OPTION_FULL_DUPLEX;
    }

    //
    // if the caller specified a local completion function, then call it now.
    // this function is responsible for completing the original request
    //

    if ( IMReqBuffer->LocalCompletionFunc ) {

        (*IMReqBuffer->LocalCompletionFunc)( Adapter, IMReqBuffer, Status );
    } else {

        //
        // if this was a IM originated request and no local completion function was
        // specified, then set the event to indicate that the request completed.
        // Note that the event can only be used at lowered IRQL.
        //

        if ( IMReqBuffer->LocalRequest ) {

            Adapter->FinalStatus = Status;
            NdisSetEvent( &Adapter->BlockingEvent );
        } else {

            //
            // if this is not a local request, call the appropriate NDIS completion
            // routine
            //

            if ( CallQueryInfoCompletion ) {

                NdisMQueryInformationComplete( Adapter->IMNdisHandle, Status );
            } else {

                NdisMSetInformationComplete( Adapter->IMNdisHandle, Status );
            }
        }
    }


   


    //
    // give back our ndis request buffer
    //

    NdisFreeToNPagedLookasideList( &NdisRequestLL, IMReqBuffer );

}                              



NDIS_STATUS
MakeLocalNdisRequest(
    PADAPTER Adapter,
    NDIS_OID Oid,
    PVOID Buffer,
    ULONG BufferSize,
    LOCAL_NDISREQUEST_COMPLETION_FUNCTION CompletionFunc OPTIONAL
    )

/*++

Routine Description:

    Make an NdisRequest to the underlying adapter on behalf of the ImSamp driver

Arguments:

    Adapter and Oid should be obvious

    Buffer, BufferSize - pointer to and size of location that receives the info

    CompletionFunc - if non-null, then don't wait on the adapter's event. Used when we're
        running at dispatch level

Return Value:

    Standard NDIS_STATUS from an NdisRequest

--*/

{
    NDIS_STATUS Status;
    ULONG BytesRead, BytesNeeded;

    Status = MakeNdisRequest(Adapter,
                             NdisRequestLocalQueryInfo,
                             Oid,
                             Buffer,
                             BufferSize,
                             &BytesRead,
                             &BytesNeeded,
                             CompletionFunc);

    //
    // only wait if no completion function has been specified
    //

    if ( !ARGUMENT_PRESENT( CompletionFunc ) && Status == NDIS_STATUS_PENDING ) {

        NdisWaitEvent( &Adapter->BlockingEvent, 0 );
        NdisResetEvent( &Adapter->BlockingEvent );
        Status = Adapter->FinalStatus;
    }

    //
    // some MPs return an NT specific status code - duh...
    //

    if ( Status == STATUS_NOT_SUPPORTED ) {

        Status = NDIS_STATUS_INVALID_OID;
    }

    return Status;

} // MakeLocalNdisRequest

/* end ndisreq.c */

⌨️ 快捷键说明

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