📄 nic_req.c
字号:
}
newDeviceState = *(PDEVICE_POWER_STATE UNALIGNED)InformationBuffer;
oldDeviceState = FdoData->DevicePowerState;
FdoData->DevicePowerState = newDeviceState;
if (oldDeviceState == PowerDeviceD0) {
status = PciDrvPowerBeginQueuingIrps(
FdoData->Self,
1, // One for current OID request.
FALSE // Do not query for state change.
);
ASSERT(NT_SUCCESS(status));
}
//
// Set the power state - Cannot fail this request
//
status = NICSetPower(FdoData, newDeviceState );
if (status != STATUS_SUCCESS)
{
DebugPrint(ERROR, DBG_IOCTLS, "SET Power: Hardware error !!!\n");
break;
}
if (newDeviceState == PowerDeviceD0) {
//
// Our hardware is now on again. Here we empty our existing queue of
// requests and let in new ones.
//
FdoData->QueueState = AllowRequests;
PciDrvProcessQueuedRequests(FdoData);
}
status = STATUS_SUCCESS;
break;
case OID_PNP_ADD_WAKE_UP_PATTERN:
//
// call a function that would program the adapter's wake
// up pattern, return success
//
DebugPrint(TRACE, DBG_IOCTLS, "--> OID_PNP_ADD_WAKE_UP_PATTERN\n");
if (IsPoMgmtSupported(FdoData) )
{
status = NICAddWakeUpPattern(FdoData,
InformationBuffer,
InformationBufferLength,
&unUsed,
&unUsed);
}
else
{
status = STATUS_NOT_SUPPORTED;
}
break;
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
//
// call a function that would remove the adapter's wake
// up pattern, return success
//
DebugPrint(TRACE, DBG_IOCTLS, "--> OID_PNP_ADD_WAKE_UP_PATTERN\n");
if (IsPoMgmtSupported(FdoData) )
{
status = NICRemoveWakeUpPattern(FdoData,
InformationBuffer,
InformationBufferLength,
&unUsed,
&unUsed);
}
else
{
status = STATUS_NOT_SUPPORTED;
}
break;
case OID_PNP_ENABLE_WAKE_UP:
//
// call a function that would enable wake up on the adapter
// return success
//
DebugPrint(TRACE, DBG_IOCTLS, "--> OID_PNP_ENABLE_WAKE_UP\n");
if (IsPoMgmtSupported(FdoData))
{
ULONG WakeUpEnable;
RtlMoveMemory(&WakeUpEnable, InformationBuffer,sizeof(ULONG));
//
// The WakeUpEable can only be 0, or NDIS_PNP_WAKE_UP_PATTERN_MATCH since the driver only
// supports wake up pattern match
//
if ((WakeUpEnable != 0)
&& ((WakeUpEnable & NDIS_PNP_WAKE_UP_PATTERN_MATCH) != NDIS_PNP_WAKE_UP_PATTERN_MATCH ))
{
status = STATUS_NOT_SUPPORTED;
FdoData->AllowWakeArming = FALSE;
break;
}
//
// When the driver goes to low power state, it would check WakeUpEnable to decide
// which wake up methed it should use to wake up the machine. If WakeUpEnable is 0,
// no wake up method is enabled.
//
FdoData->AllowWakeArming = TRUE;
status = STATUS_SUCCESS;
}
else
{
status = STATUS_NOT_SUPPORTED;
}
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
}
}while (FALSE);
DebugPrint(LOUD, DBG_IOCTLS, "<-- HandleSetOIDRequest\n");
return (status);
}
VOID
NICServiceIndicateStatusIrp(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
This routine is used indicate media status of the client.
If the IRP was cancelled for some reason we will let
the cancel routine do the IRP completion.
Arguments:
Return Value:
None
--*/
{
PIRP pIrp = NULL;
PIO_STACK_LOCATION pIrpSp = NULL;
PNDISPROT_INDICATE_STATUS pIndicateStatus = NULL;
NTSTATUS ntStatus = STATUS_CANCELLED;
ULONG inBufLength, outBufLength;
KIRQL oldIrql;
DebugPrint(TRACE, DBG_IOCTLS, "-->ndisServiceIndicateStatusIrp\n");
KeAcquireSpinLock(&FdoData->Lock, &oldIrql);
pIrp = FdoData->StatusIndicationIrp;
if(pIrp){
//
// Clear the cancel routine.
//
if(IoSetCancelRoutine(pIrp, NULL)){
//
// Cancel routine cannot run now and cannot have already
// started to run.
//
pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
pIndicateStatus = pIrp->AssociatedIrp.SystemBuffer;
inBufLength = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
outBufLength = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
//
// Check to see whether the buffer is large enough.
//
if(outBufLength >= sizeof(NDISPROT_INDICATE_STATUS)){
if(MP_TEST_FLAG(FdoData, fMP_ADAPTER_NO_CABLE)){
pIndicateStatus->IndicatedStatus = NDIS_STATUS_MEDIA_DISCONNECT;
} else {
pIndicateStatus->IndicatedStatus = NDIS_STATUS_MEDIA_CONNECT;
}
pIndicateStatus->StatusBufferLength = 0;
pIndicateStatus->StatusBufferOffset = 0;
ntStatus = STATUS_SUCCESS;
} else {
ntStatus = STATUS_BUFFER_OVERFLOW;
}
//
// Since we are completing the IRP below, clear this field.
//
FdoData->StatusIndicationIrp = NULL;
}else {
//
// Cancel rotuine is running. Leave the irp alone.
//
pIrp = NULL;
}
}
KeReleaseSpinLock(&FdoData->Lock, oldIrql);
if(pIrp){
pIrp->IoStatus.Information = sizeof(NDISPROT_INDICATE_STATUS);
pIrp->IoStatus.Status = ntStatus;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
PciDrvIoDecrement (FdoData);
}
DebugPrint(TRACE, DBG_IOCTLS, "<--ndisServiceIndicateStatusIrp\n");
return;
}
MEDIA_STATE
NICIndicateMediaState(
IN PFDO_DATA FdoData
)
{
MEDIA_STATE CurrMediaState;
KeAcquireSpinLockAtDpcLevel(&FdoData->Lock);
CurrMediaState = GetMediaState(FdoData);
if (CurrMediaState != FdoData->MediaState)
{
DebugPrint(WARNING, DBG_IOCTLS, "Media state changed to %s\n",
((CurrMediaState == Connected)?
"Connected": "Disconnected"));
FdoData->MediaState = CurrMediaState;
if (CurrMediaState == Connected)
{
MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_NO_CABLE);
}
else
{
MP_SET_FLAG(FdoData, fMP_ADAPTER_NO_CABLE);
}
KeReleaseSpinLockFromDpcLevel(&FdoData->Lock);
// Indicate the media event
NICServiceIndicateStatusIrp(FdoData);
}
else
{
KeReleaseSpinLockFromDpcLevel(&FdoData->Lock);
}
return CurrMediaState;
}
NTSTATUS
NICGetStatsCounters(
IN PFDO_DATA FdoData,
IN NDIS_OID Oid,
OUT PULONG64 pCounter
)
/*++
Routine Description:
Get the value for a statistics OID
Arguments:
FdoData Pointer to our FdoData
Oid Self-explanatory
pCounter Pointer to receive the value
Return Value:
NT Status code
--*/
{
NTSTATUS status = STATUS_SUCCESS;
DebugPrint(TRACE, DBG_IOCTLS, "--> NICGetStatsCounters\n");
*pCounter = 0;
DumpStatsCounters(FdoData);
switch(Oid)
{
case OID_GEN_XMIT_OK:
*pCounter = FdoData->GoodTransmits;
break;
case OID_GEN_RCV_OK:
*pCounter = FdoData->GoodReceives;
break;
case OID_GEN_XMIT_ERROR:
*pCounter = FdoData->TxAbortExcessCollisions +
FdoData->TxDmaUnderrun +
FdoData->TxLostCRS +
FdoData->TxLateCollisions;
break;
case OID_GEN_RCV_ERROR:
*pCounter = FdoData->RcvCrcErrors +
FdoData->RcvAlignmentErrors +
FdoData->RcvResourceErrors +
FdoData->RcvDmaOverrunErrors +
FdoData->RcvRuntErrors;
break;
case OID_GEN_RCV_NO_BUFFER:
*pCounter = FdoData->RcvResourceErrors;
break;
case OID_GEN_RCV_CRC_ERROR:
*pCounter = FdoData->RcvCrcErrors;
break;
case OID_GEN_TRANSMIT_QUEUE_LENGTH:
*pCounter = FdoData->nWaitSend;
break;
case OID_802_3_RCV_ERROR_ALIGNMENT:
*pCounter = FdoData->RcvAlignmentErrors;
break;
case OID_802_3_XMIT_ONE_COLLISION:
*pCounter = FdoData->OneRetry;
break;
case OID_802_3_XMIT_MORE_COLLISIONS:
*pCounter = FdoData->MoreThanOneRetry;
break;
case OID_802_3_XMIT_DEFERRED:
*pCounter = FdoData->TxOKButDeferred;
break;
case OID_802_3_XMIT_MAX_COLLISIONS:
*pCounter = FdoData->TxAbortExcessCollisions;
break;
case OID_802_3_RCV_OVERRUN:
*pCounter = FdoData->RcvDmaOverrunErrors;
break;
case OID_802_3_XMIT_UNDERRUN:
*pCounter = FdoData->TxDmaUnderrun;
break;
case OID_802_3_XMIT_HEARTBEAT_FAILURE:
*pCounter = FdoData->TxLostCRS;
break;
case OID_802_3_XMIT_TIMES_CRS_LOST:
*pCounter = FdoData->TxLostCRS;
break;
case OID_802_3_XMIT_LATE_COLLISIONS:
*pCounter = FdoData->TxLateCollisions;
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
}
DebugPrint(TRACE, DBG_IOCTLS, "<-- NICGetStatsCounters\n");
return(status);
}
NTSTATUS NICSetPacketFilter(
IN PFDO_DATA FdoData,
IN ULONG PacketFilter
)
/*++
Routine Description:
This routine will set up the FdoData so that it accepts packets
that match the specified packet filter. The only filter bits
that can truly be toggled are for broadcast and promiscuous
Arguments:
FdoData Pointer to our FdoData
PacketFilter The new packet filter
Return Value:
--*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -