📄 io.c
字号:
MiniportAdapter *VA,
VRR_QUERY_PHYSICAL_ADAPTER *Query)
{
ProtocolAdapter *PA;
if (Query->Index == 0)
PA = FindPhysicalAdapterFromGuid(VA, &Query->Guid);
else
PA = FindPhysicalAdapterFromIndex(VA, Query->Index);
return PA;
}
//* ReturnQueryPhysicalAdapter
//
// Initializes a returned VRR_QUERY_PHYSICAL_ADAPTER structure
// with query information for the specified physical adapter.
//
void
ReturnQueryPhysicalAdapter(
ProtocolAdapter *PA,
VRR_QUERY_PHYSICAL_ADAPTER *Query)
{
if (PA == NULL) {
ReturnQueryVirtualAdapter(NULL, &Query->VA);
Query->Index = (uint)-1;
RtlZeroMemory(&Query->Guid, sizeof Query->Guid);
}
else {
ReturnQueryVirtualAdapter(PA->VirtualAdapter, &Query->VA);
Query->Index = PA->Index;
Query->Guid = PA->Guid;
}
}
//* IoQueryPhysicalAdapter
//
// Handles queries for information about a virtual adapter.
//
NTSTATUS
IoQueryPhysicalAdapter(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
VRR_QUERY_PHYSICAL_ADAPTER *Query;
VRR_INFO_PHYSICAL_ADAPTER *Info;
MiniportAdapter *VA;
ProtocolAdapter *PA;
KIRQL OldIrql;
NTSTATUS Status;
Irp->IoStatus.Information = 0;
if ((IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Query) ||
(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof *Info)) {
Status = STATUS_INVALID_PARAMETER;
goto Return;
}
Query = (VRR_QUERY_PHYSICAL_ADAPTER *) Irp->AssociatedIrp.SystemBuffer;
Info = (VRR_INFO_PHYSICAL_ADAPTER *) Irp->AssociatedIrp.SystemBuffer;
//
// Return information about the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(&Query->VA);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
if (Query->Index == (uint)-1) {
//
// Return query information for the first physical adapter.
//
KeAcquireSpinLock(&VA->Lock, &OldIrql);
ReturnQueryPhysicalAdapter(VA->PhysicalAdapters, &Info->Next);
KeReleaseSpinLock(&VA->Lock, OldIrql);
Irp->IoStatus.Information = sizeof Info->Next;
}
else {
//
// Return information about the specified physical adapter.
//
PA = FindPhysicalAdapterFromQuery(VA, Query);
if (PA == NULL) {
Status = STATUS_INVALID_PARAMETER_2;
goto ReturnReleaseVA;
}
//
// Return query information for the next physical adapter.
//
KeAcquireSpinLock(&VA->Lock, &OldIrql);
ReturnQueryPhysicalAdapter(PA->Next, &Info->Next);
KeReleaseSpinLock(&VA->Lock, OldIrql);
//
// Return miscellaneous information about the virtual adapter.
//
ReturnQueryPhysicalAdapter(PA, &Info->This);
ProtocolQuery(PA, Info);
#if 0
ReleasePA(PA);
#endif
Irp->IoStatus.Information = sizeof *Info;
}
ReturnQueryVirtualAdapter(VA, &Info->Next.VA);
Status = STATUS_SUCCESS;
ReturnReleaseVA:
#if 0
ReleaseVA(VA);
#endif
Return:
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//* IoQueryNeighborCacheInitLink
//
// Helper for IoQueryNeighborCache.
//
IoQueryNeighborCacheInitLink(
MiniportAdapter *VA,
VRR_INFO_LINK *LInfo,
Link *link)
{
Time Delta = IoTimeDelta();
uint i;
LInfo->FromIF = link->outif;
LInfo->ToIF = link->inif;
LInfo->Metric = link->Metric;
LInfo->TimeStamp = link->TimeStamp + Delta;
LInfo->Usage = link->Usage;
LInfo->Failures = link->Failures;
LInfo->DropRatio = link->DropRatio;
LInfo->ArtificialDrops = link->ArtificialDrops;
LInfo->QueueDrops = link->QueueDrops;
switch (VA->MetricType) {
case METRIC_TYPE_WCETT:
LInfo->MetricInfo.Wcett.TotSentProbes = link->MetricInfo.Wcett.Etx.TotSentProbes;
LInfo->MetricInfo.Wcett.TotRcvdProbes = link->MetricInfo.Wcett.Etx.TotRcvdProbes;
LInfo->MetricInfo.Wcett.FwdDeliv = link->MetricInfo.Wcett.Etx.FwdDeliv;
LInfo->MetricInfo.Wcett.ProbeHistorySZ = link->MetricInfo.Wcett.Etx.ProbeHistorySZ;
LInfo->MetricInfo.Wcett.LastProb = link->MetricInfo.Wcett.Etx.LastProb;
LInfo->MetricInfo.Wcett.PairsSent = link->MetricInfo.Wcett.PktPair.PairsSent;
LInfo->MetricInfo.Wcett.RepliesSent = link->MetricInfo.Wcett.PktPair.RepliesSent;
LInfo->MetricInfo.Wcett.RepliesRcvd = link->MetricInfo.Wcett.PktPair.RepliesRcvd;
LInfo->MetricInfo.Wcett.LastPktPair = link->MetricInfo.Wcett.PktPair.LastPktPair;
LInfo->MetricInfo.Wcett.CurrMin = link->MetricInfo.Wcett.PktPair.CurrMin;
LInfo->MetricInfo.Wcett.NumPktPairValid = link->MetricInfo.Wcett.NumPktPairValid;
LInfo->MetricInfo.Wcett.NumPktPairInvalid = link->MetricInfo.Wcett.NumPktPairInvalid;
break;
}
}
//* IoQueryNeighborCache
//
// Handles queries for information about a neighbor cache entry.
//
NTSTATUS
IoQueryNeighborCache(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
VRR_QUERY_NEIGHBOR_CACHE *Query;
VRR_INFO_NEIGHBOR_CACHE *Info;
MiniportAdapter *VA = NULL;
NeighborCacheEntry *NCE;
KIRQL OldIrql;
NTSTATUS Status;
Time Now = KeQueryInterruptTime();
uint millisecs;
uint ns100;
PAGED_CODE();
Irp->IoStatus.Information = 0;
if ((IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Query) ||
(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof *Info)) {
Status = STATUS_INVALID_PARAMETER;
goto Return;
}
//
// Note that the Query and Info->Query structures overlap!
//
Query = (VRR_QUERY_NEIGHBOR_CACHE *) Irp->AssociatedIrp.SystemBuffer;
Info = (VRR_INFO_NEIGHBOR_CACHE *) Irp->AssociatedIrp.SystemBuffer;
//
// Return information about the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(&Query->VA);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
if (IsUnspecified(Query->Address)) {
//
// Return the address of the first NCE.
//
KeAcquireSpinLock(&VA->NC.Lock, &OldIrql);
if (VA->NC.FirstNCE != SentinelNCE(&VA->NC)) {
RtlCopyMemory(Info->Query.Address, VA->NC.FirstNCE->VAddress,
sizeof(VirtualAddress));
Info->Query.RemIF = VA->NC.FirstNCE->RemIF;
Info->Query.LocIF = VA->NC.FirstNCE->LocIF;
}
KeReleaseSpinLock(&VA->NC.Lock, OldIrql);
Irp->IoStatus.Information = sizeof Info->Query;
}
else {
//
// Find the specified NCE.
//
KeAcquireSpinLock(&VA->NC.Lock, &OldIrql);
for (NCE = VA->NC.FirstNCE; ; NCE = NCE->Next) {
if (NCE == SentinelNCE(&VA->NC)) {
KeReleaseSpinLock(&VA->NC.Lock, OldIrql);
Status = STATUS_INVALID_PARAMETER_2;
goto Return;
}
if (VirtualAddressEqual(Query->Address, NCE->VAddress) &&
(Query->RemIF == NCE->RemIF) &&
(Query->LocIF == NCE->LocIF)) // VRR: NCE (address,RemIF) may no longer be unique.
break;
}
//
// Return miscellaneous information about the NCE.
//
RtlCopyMemory(Info->Address, NCE->PAddress, sizeof(PhysicalAddress));
Info->LocIF = NCE->LocIF;
Info->State = NCE->State;
Info->RefCnt = NCE->RefCnt;
Info->BitsPerSec = NCE->BitsPerSec;
Info->Rssi = NCE->Rssi;
Info->TimeLastHello = (uint)(KeQueryInterruptTime() - NCE->TimeLastHello);
if (NCE->Timeout == 0)
Info->Timeout = 0;
else
Info->Timeout = (uint)((NCE->Timeout - KeQueryInterruptTime()) / 10000);
Info->CountFailRexmit = NCE->CountFailRexmit;
Info->CountFailHelloLoss = NCE->CountFailHelloLoss;
Info->CountFailQoSEvict = NCE->CountFailQoSEvict;
Info->CountFailHelloFail = NCE->CountFailHelloFail;
Info->AveUsedBitsPerSecond = NCE->AveUsedBitsPerSecond;
//
// Populate AdjOut link members.
//
IoQueryNeighborCacheInitLink(VA,&Info->AdjOut,&NCE->AdjOut);
//
// Return address of the next NCE (or zero).
//
if (NCE->Next == SentinelNCE(&VA->NC)) {
RtlZeroMemory(Info->Query.Address, sizeof(VirtualAddress));
Info->Query.RemIF = (uint)-1;
Info->Query.LocIF = -1;
}
else {
RtlCopyMemory(Info->Query.Address, NCE->Next->VAddress,
sizeof(VirtualAddress));
Info->Query.RemIF = NCE->Next->RemIF;
Info->Query.LocIF = NCE->Next->LocIF;
}
KeReleaseSpinLock(&VA->NC.Lock, OldIrql);
Irp->IoStatus.Information = sizeof *Info;
}
Status = STATUS_SUCCESS;
Return:
#if 0
if (VA != NULL)
ReleaseVA(VA);
#endif
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//* IoFlushNeighborCache
//
// Handles requests to flush the neighbor cache.
//
NTSTATUS
IoFlushNeighborCache(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
VRR_QUERY_NEIGHBOR_CACHE *Query;
MiniportAdapter *VA;
const uchar *Address;
NTSTATUS Status;
PAGED_CODE();
Irp->IoStatus.Information = 0;
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Query) {
Status = STATUS_INVALID_PARAMETER;
goto Return;
}
Query = (VRR_QUERY_NEIGHBOR_CACHE *) Irp->AssociatedIrp.SystemBuffer;
//
// Find the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(&Query->VA);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
if (IsUnspecified(Query->Address))
Address = NULL;
else
Address = Query->Address;
NeighborCacheFlushAddress(&VA->NC, Address, (VRRIf) Query->RemIF);
#if 0
ReleaseVA(VA);
#endif
Status = STATUS_SUCCESS;
Return:
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//* ReturnQueryMaintenanceBufferNode
//
// Initializes a returned VRR_QUERY_MAINTENANCE_BUFFER_NODE structure
// with query information for the specified maintenance buffer node.
// Does NOT initialize Query->VA.
//
void
ReturnQueryMaintenanceBufferNode(
MaintBufNode *MBN,
VRR_QUERY_MAINTENANCE_BUFFER_NODE *Query)
{
if (MBN == NULL) {
RtlZeroMemory(Query->Node.Address, SR_ADDR_LEN);
Query->Node.InIF = 0;
Query->Node.OutIF = 0;
}
else {
RtlCopyMemory(Query->Node.Address, MBN->Address, SR_ADDR_LEN);
Query->Node.InIF = MBN->InIf;
Query->Node.OutIF = MBN->OutIf;
}
}
//* IoQueryMaintenanceBuffer
//
// Handles queries for information about the maintenance buffer.
//
NTSTATUS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -