📄 request.c
字号:
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 + -