📄 ndisreq.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 + -