📄 io.c
字号:
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// (c) Microsoft Corporation. All rights reserved.
//
// This file is part of the Microsoft Virtual Ring Routing distribution.
// You should have received a copy of the Microsoft Research Shared Source
// license agreement (MSR-SSLA) for this software; see the file "license.txt".
// If not, please see http://research.microsoft.com/vrr/license.htm,
// or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
//
// This file is derived from the Microsoft Research Mesh Connectivity Layer,
// available under the MSR-SSLA license, and downloadable from
// http://research.microsoft.com/mesh/.
//
#include "headers.h"
#define MIN(a, b) ((a) < (b) ? (a) : (b))
//* IoTimeDelta
//
// Calculates a delta between interrupt time and system time.
// We use interrupt time internally but we return system time
// in our ioctls. So any absolute time values must be translated.
//
Time
IoTimeDelta(void)
{
Time InterruptTime;
Time SystemTime;
InterruptTime = KeQueryInterruptTime();
KeQuerySystemTime((LARGE_INTEGER *)&SystemTime);
return SystemTime - InterruptTime;
}
//* IoCreate
//
// Handles the IRP_MJ_CREATE request for the VRR device.
//
NTSTATUS
IoCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
return STATUS_SUCCESS;
}
//* IoCleanup
//
// Handles the IRP_MJ_CLEANUP request for the VRR device.
//
NTSTATUS
IoCleanup(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
return STATUS_SUCCESS;
}
//* IoClose
//
// Handles the IRP_MJ_CLOSE request for the VRR device.
//
NTSTATUS
IoClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
return STATUS_SUCCESS;
}
//* FindVirtualAdapterFromQuery
//
// Given an VRR_QUERY_VIRTUAL_ADAPTER structure,
// finds the specified virtual adapter.
// The virtual adapter (if found) is returned with a reference.
//
MiniportAdapter *
FindVirtualAdapterFromQuery(
VRR_QUERY_VIRTUAL_ADAPTER *Query)
{
MiniportAdapter *VA;
if (Query->Index == 0)
VA = FindVirtualAdapterFromGuid(&Query->Guid);
else
VA = FindVirtualAdapterFromIndex(Query->Index);
return VA;
}
//* ReturnQueryVirtualAdapter
//
// Initializes a returned VRR_QUERY_VIRTUAL_ADAPTER structure
// with query information for the specified virtual adapter.
//
void
ReturnQueryVirtualAdapter(
MiniportAdapter *VA,
VRR_QUERY_VIRTUAL_ADAPTER *Query)
{
if (VA == NULL) {
Query->Index = (uint)-1;
RtlZeroMemory(&Query->Guid, sizeof Query->Guid);
}
else {
Query->Index = VA->Index;
Query->Guid = VA->Guid;
}
}
//* IoQueryVirtualAdapter
//
// Handles queries for information about a virtual adapter.
//
NTSTATUS
IoQueryVirtualAdapter(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
VRR_QUERY_VIRTUAL_ADAPTER *Query;
VRR_INFO_VIRTUAL_ADAPTER *Info;
MiniportAdapter *VA;
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_VIRTUAL_ADAPTER *) Irp->AssociatedIrp.SystemBuffer;
Info = (VRR_INFO_VIRTUAL_ADAPTER *) Irp->AssociatedIrp.SystemBuffer;
if (Query->Index == (uint)-1) {
//
// Return query information for the first virtual adapter.
//
KeAcquireSpinLock(&MiniportAdapters.Lock, &OldIrql);
ReturnQueryVirtualAdapter(MiniportAdapters.VirtualAdapters,
&Info->Next);
KeReleaseSpinLock(&MiniportAdapters.Lock, OldIrql);
Irp->IoStatus.Information = sizeof Info->Next;
}
else {
//
// Return information about the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(Query);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
//
// Return query information for the next virtual adapter.
//
KeAcquireSpinLock(&MiniportAdapters.Lock, &OldIrql);
ReturnQueryVirtualAdapter(VA->Next, &Info->Next);
KeReleaseSpinLock(&MiniportAdapters.Lock, OldIrql);
//
// Return miscellaneous information about the virtual adapter.
//
ReturnQueryVirtualAdapter(VA, &Info->This);
Info->Version = Version;
Info->MinVersionSeen = VA->MinVersionSeen;
Info->MaxVersionSeen = VA->MaxVersionSeen;
RtlCopyMemory(Info->Address, VA->Address, sizeof(VirtualAddress));
Info->LookAhead = VA->LookAhead;
Info->Snooping = VA->Snooping;
Info->ArtificialDrop = VA->ArtificialDrop;
Info->MetricType = VA->MetricType;
Info->Crypto = VA->Crypto;
RtlCopyMemory(Info->CryptoKeyMAC, VA->CryptoKeyMAC,
sizeof Info->CryptoKeyMAC);
#if BUILD_CRYPTO // DDK
CryptoKeyMACModify(VA, Info->CryptoKeyMAC);
#endif
RtlCopyMemory(Info->CryptoKeyAES, VA->CryptoKeyAES,
sizeof Info->CryptoKeyAES);
Info->LinkTimeout = (uint)(VA->LinkTimeout / SECOND);
Info->TotalForwardingStall = VA->TotalForwardingStall;
Info->ForwardNum = VA->ForwardNum;
Info->ForwardMax = VA->ForwardMax;
Info->CountForwardFast = VA->CountForwardFast;
Info->CountForwardQueue = VA->CountForwardQueue;
Info->CountForwardDrop = VA->CountForwardDrop;
Info->DriverInitialized = IsDriverInitialized(VA);
Info->DriverActive = IsDriverActive(VA);
Info->VrrAPIJoined = VA->VrrAPIJoined;
Info->JoiningOnHold = IsJoiningOnHold(VA);
Info->PartitionRepairEnabled = IsPartitionRepairEnabled(VA);
Info->BroadcastRelay = IsBroadcastRelay(VA);
Info->BroadcastJitterMinMs = VA->BroadcastJitterMinMs;
Info->BroadcastJitterMaxMs = VA->BroadcastJitterMaxMs;
Info->TxDropAllButHello = VA->TxDropAllButHello;
Info->TxDropAllHello = VA->TxDropAllHello;
Info->BroadcastRelay = IsBroadcastRelay(VA);
Info->VrrTraceNoiseLevel = VA->VrrTraceNoiseLevel;
Info->MsJoinToHeardExpectedVSet = VA->MsJoinToHeardExpectedVSet;
Info->MsJoinToPathsExpectedVSet = VA->MsJoinToPathsExpectedVSet;
RtlCopyMemory(Info->ExpectedVSet,VA->ExpectedVSet,sizeof(VirtualAddress)*VRR_MAX_VSET_SIZE);
RtlCopyMemory(Info->AddErrorVSet,VA->AddErrorVSet,sizeof(uint)*VRR_MAX_VSET_SIZE);
RtlCopyMemory(Info->RejExpBypass,VA->RejExpBypass,sizeof(uint)*REJ_EXP_BYPASS_COUNT);
Info->TestExpectedVSet = VA->TestExpectedVSet;
RtlZeroMemory(Info->CurrentVSet, sizeof(VirtualAddress) * VRR_MAX_VSET_SIZE);
KeAcquireSpinLock(&VA->NT.Lock, &OldIrql);
Info->VSetIsComplete = VSetIsComplete(VA);
VSetToFlatBuffer(VA,Info->CurrentVSet + VRR_WING_SIZE - VA->NT.CountLeft);
KeReleaseSpinLock(&VA->NT.Lock, OldIrql);
RtlZeroMemory(Info->RoutesVSet, sizeof(VirtualAddress) * VRR_MAX_VSET_SIZE);
KeAcquireSpinLock(&VA->RT.Lock, &OldIrql);
{
int i;
for (i=0; i < VRR_MAX_VSET_SIZE; i++) {
if (i == VRR_WING_SIZE)
RtlCopyMemory(Info->RoutesVSet[i],VA->Address,sizeof(VirtualAddress));
else if (FindVSetRoute(VA,VA->Address,Info->CurrentVSet[i]) != NULL)
RtlCopyMemory(Info->RoutesVSet[i],Info->CurrentVSet[i],sizeof(VirtualAddress));
}
}
KeReleaseSpinLock(&VA->RT.Lock, OldIrql);
switch (VA->MetricType) {
case METRIC_TYPE_PKTPAIR:
Info->MetricParams.PktPair.Alpha = VA->MetricParams.PktPair.Alpha;
Info->MetricParams.PktPair.PenaltyFactor = VA->MetricParams.PktPair.PenaltyFactor;
Info->MetricParams.PktPair.ProbePeriod = VA->MetricParams.PktPair.ProbePeriod;
break;
case METRIC_TYPE_WCETT:
Info->MetricParams.Wcett.ProbePeriod = VA->MetricParams.Wcett.ProbePeriod;
Info->MetricParams.Wcett.LossInterval = VA->MetricParams.Wcett.LossInterval;
Info->MetricParams.Wcett.Alpha = VA->MetricParams.Wcett.Alpha;
Info->MetricParams.Wcett.PenaltyFactor = VA->MetricParams.Wcett.PenaltyFactor;
Info->MetricParams.Wcett.Beta = VA->MetricParams.Wcett.Beta;
Info->MetricParams.Wcett.PktPairProbePeriod = VA->MetricParams.Wcett.PktPairProbePeriod;
Info->MetricParams.Wcett.PktPairMinOverProbes = VA->MetricParams.Wcett.PktPairMinOverProbes;
break;
}
Info->CountPacketPoolFailure = VA->CountPacketPoolFailure;
Info->TimeoutMinLoops = VA->TimeoutMinLoops;
Info->TimeoutMaxLoops = VA->TimeoutMaxLoops;
Info->RateAdmitThreshold = VA->RateAdmitThreshold;
Info->RateEvictThreshold = VA->RateEvictThreshold;
Info->RssiAdmitThreshold = VA->RssiAdmitThreshold;
Info->RssiEvictThreshold = VA->RssiEvictThreshold;
Info->PbackAckMaxDupTime = VA->PCache.AckMaxDupTime;
Info->PbackNumber = VA->PCache.Number;
Info->PbackHighWater = VA->PCache.HighWater;
Info->MaintBufNumPackets = VA->MaintBuf->NumPackets;
Info->MaintBufHighWater = VA->MaintBuf->HighWater;
Info->CountPbackReply = VA->PCache.CountPbackReply;
Info->CountAloneReply = VA->PCache.CountAloneReply;
Info->CountPbackError = VA->PCache.CountPbackError;
Info->CountAloneError = VA->PCache.CountAloneError;
Info->CountPbackInfo = VA->PCache.CountPbackInfo;
Info->CountAloneInfo = VA->PCache.CountAloneInfo;
Info->CountSRNackSeqT = VA->CountSRNackSeqT;
Info->CountExitRing = VA->CountExitRing;
Info->CountExitExecCmd = VA->CountExitExecCmd;
Info->CountExitNCE = VA->CountExitNCE;
Info->CountExitNTE = VA->CountExitNTE;
Info->CountSetActiveT = VA->CountSetActiveT;
Info->CountSetActiveF = VA->CountSetActiveF;
Info->CountMaxPLE = VA->CountMaxPLE;
Info->BootNode = VA->BootNode;
Info->MaxMsgTimeDelay = VA->MaxMsgTimeDelay;
Info->MaxMsgCountDelayed = VA->MaxMsgCountDelayed;
Info->CountMsQDropCritical = VA->CountMsQDropCritical;
Info->CountPnRepairSendSetup = VA->CountPnRepairSendSetup;
Info->CountHopCountExceeded = VA->CountHopCountExceeded;
Info->CountNTECloserThanSelf = VA->CountNTECloserThanSelf;
Info->CountXmit = VA->CountXmit;
Info->CountXmitLocally = VA->CountXmitLocally;
Info->CountXmitQueueFull = VA->CountXmitQueueFull;
Info->CountRexmitQueueFull = VA->CountRexmitQueueFull;
Info->CountXmitNoRoute = VA->CountXmitNoRoute;
Info->CountXmitMulticast = VA->CountXmitMulticast;
Info->CountXmitMaintBuf = VA->CountXmitMaintBuf;
Info->CountXmitForwardUnicast = VA->CountXmitForwardUnicast;
Info->CountXmitForwardQueueFull = VA->CountXmitForwardQueueFull;
Info->CountXmitForwardBroadcast = VA->CountXmitForwardBroadcast;
Info->CountXmitProbe = VA->CountXmitProbe;
Info->CountXmitProbeReply = VA->CountXmitProbeReply;
Info->CountSendHello = VA->CountSendHello;
Info->CountSendSetup = VA->CountSendSetup;
Info->CountSendTearDown = VA->CountSendTearDown;
Info->CountSendSetupReq = VA->CountSendSetupReq;
Info->CountSendSetupReqNack = VA->CountSendSetupReqNack;
Info->CountFwdSetup = VA->CountFwdSetup;
Info->CountFwdTearDown = VA->CountFwdTearDown;
Info->CountFwdSetupReq = VA->CountFwdSetupReq;
Info->CountMisroutedSetup = VA->CountMisroutedSetup;
Info->CountMisroutedSetupReq = VA->CountMisroutedSetupReq;
Info->CountMisroutedTearDown = VA->CountMisroutedTearDown;
Info->CountSRDropHopCount = VA->CountSRDropHopCount;
Info->CountSRDropLoop = VA->CountSRDropLoop;
Info->MaxPLESRcAntiRoute = VA->MaxPLESRcAntiRoute;
Info->MaxPLESRcAntiRouteRcv = VA->MaxPLESRcAntiRouteRcv;
Info->CountFNHSRcAntiRoute = VA->CountFNHSRcAntiRoute;
Info->CountFNHsendSRleft = VA->CountFNHsendSRleft;
Info->CountFNHsendSRright = VA->CountFNHsendSRright;
Info->CountRecv = VA->CountRecv;
Info->CountRecvLocallySalvaged = VA->CountRecvLocallySalvaged;
Info->CountRecvLocally = VA->CountRecvLocally;
Info->CountRecvBadMAC = VA->CountRecvBadMAC;
Info->CountRecvAckRequest = VA->CountRecvAckRequest;
Info->CountRecvAck = VA->CountRecvAck;
Info->CountRecvDupAckReq = VA->CountRecvDupAckReq;
Info->CountRecvProbe = VA->CountRecvProbe;
Info->CountRecvProbeReply = VA->CountRecvProbeReply;
Info->CountRecvHello = VA->CountRecvHello;
Info->CountRecvSetup = VA->CountRecvSetup;
Info->CountRecvTearDown = VA->CountRecvTearDown;
Info->CountRecvSetupReq = VA->CountRecvSetupReq;
Info->CountRecvSRleft = VA->CountRecvSRleft;
Info->CountRecvSRright = VA->CountRecvSRright;
Info->CountGenSRleft = VA->CountGenSRleft;
Info->CountGenSRright = VA->CountGenSRright;
Info->CountRecvRecursive = VA->CountRecvRecursive;
Info->CountRecvEmpty = VA->CountRecvEmpty;
Info->CountRecvSmall = VA->CountRecvSmall;
Info->CountRecvDecryptFailure = VA->CountRecvDecryptFailure;
Info->NDISPacketPoolUsage = NdisPacketPoolUsage(VA->PacketPool);
#if 0
ReleaseVA(VA);
#endif
Irp->IoStatus.Information = sizeof *Info;
}
Status = STATUS_SUCCESS;
Return:
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//* FindPhysicalAdapterFromQuery
//
// Given an VRR_QUERY_PHYSICAL_ADAPTER structure,
// finds the specified virtual adapter.
// The virtual adapter (if found) is returned with a reference.
//
ProtocolAdapter *
FindPhysicalAdapterFromQuery(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -