📄 miniport.c
字号:
case METRIC_TYPE_WCETT:
VRR_INIT_CONTROL_WCETT(Control);
(void) GetRegDWORDValue(Key, L"Alpha",
(PULONG)&Control->MetricParams.Wcett.Alpha);
(void) GetRegDWORDValue(Key, L"PenaltyFactor",
(PULONG)&Control->MetricParams.Wcett.PenaltyFactor);
(void) GetRegDWORDValue(Key, L"LossInterval",
(PULONG)&Control->MetricParams.Wcett.LossInterval);
(void) GetRegDWORDValue(Key, L"Beta",
(PULONG)&Control->MetricParams.Wcett.Beta);
(void) GetRegDWORDValue(Key, L"PktPairProbePeriod",
(PULONG)&Control->MetricParams.Wcett.PktPairProbePeriod);
(void) GetRegDWORDValue(Key, L"PktPairMinOverProbes",
(PULONG)&Control->MetricParams.Wcett.PktPairMinOverProbes);
break;
}
ZwClose(Key);
}
//* MiniportControl
//
// Sets configuration parameters from the structure.
// Note that CryptoKeyMAC, CryptoKeyAES, and MetricType
// can not be modified.
//
NTSTATUS
MiniportControl(
MiniportAdapter *VA,
VRR_CONTROL_VIRTUAL_ADAPTER *Control)
{
//
// Check each parameter first.
//
if ((Control->MetricType != (uint)-1) &&
(Control->MetricType != VA->MetricType)) {
//
// We do not allow the MetricType to change.
//
return STATUS_INVALID_PARAMETER_2;
}
switch (Control->MetricType) {
case METRIC_TYPE_PKTPAIR:
if (Control->MetricParams.PktPair.Alpha != (uint)-1) {
//
// Alpha is interpreted as Alpha/MAXALPHA.
// Since the result of this division should
// not exceed 1, the maximum value of Alpha is MAXALPHA.
//
if (Control->MetricParams.PktPair.Alpha > MAXALPHA)
return STATUS_INVALID_PARAMETER_3;
}
if (Control->MetricParams.PktPair.ProbePeriod != (uint)-1) {
//
// The probe period should not be less than 100ms to
// prevent system overload.
//
if (Control->MetricParams.PktPair.ProbePeriod < 100 * MILLISECOND)
return STATUS_INVALID_PARAMETER_4;
}
if (Control->MetricParams.PktPair.PenaltyFactor != (uint)-1) {
//
// The penalty factor should be at most 32 to avoid
// overflow problems.
//
if ((Control->MetricParams.PktPair.PenaltyFactor < 1) ||
(Control->MetricParams.PktPair.PenaltyFactor > 32))
return STATUS_INVALID_PARAMETER_5;
}
break;
case METRIC_TYPE_WCETT:
if (Control->MetricParams.Wcett.LossInterval != (uint)-1) {
//
// The loss interval should not be less than 100ms.
// to prevent system overload. The upper bound is 1 minute
// to prevent too much memory consumption.
//
if ((Control->MetricParams.Wcett.LossInterval < 100 * MILLISECOND) ||
(Control->MetricParams.Wcett.LossInterval > 1 * MINUTE))
return STATUS_INVALID_PARAMETER_4;
}
if (Control->MetricParams.Wcett.Alpha != (uint)-1) {
//
// Alpha is interpreted as Alpha/MAXALPHA.
// Since the result of this division should
// not exceed 1, the maximum value of Alpha is MAXALPHA.
//
if (Control->MetricParams.Wcett.Alpha > MAXALPHA)
return STATUS_INVALID_PARAMETER_5;
}
if (Control->MetricParams.Wcett.PenaltyFactor != (uint)-1) {
//
// The penalty factor should be at most 32 to avoid
// overflow problems.
//
if ((Control->MetricParams.Wcett.PenaltyFactor < 1) ||
(Control->MetricParams.Wcett.PenaltyFactor > 32))
return STATUS_INVALID_PARAMETER_6;
}
if (Control->MetricParams.Wcett.Beta != (uint)-1) {
//
// Beta is interpreted as Beta/MAXALPHA.
// Since the result of this division should
// not exceed 1, the maximum value of Weight is MAXALPHA.
//
if (Control->MetricParams.Wcett.Beta > MAXALPHA)
return STATUS_INVALID_PARAMETER_7;
}
if (Control->MetricParams.Wcett.PktPairProbePeriod != (uint)-1) {
//
// The probe period should not be less than 100ms to
// prevent system overload.
//
if (Control->MetricParams.Wcett.PktPairProbePeriod < 100 * MILLISECOND)
return STATUS_INVALID_PARAMETER_8;
}
if (Control->MetricParams.Wcett.PktPairMinOverProbes != (uint)-1) {
//
// The number of probes should be at least one.
//
if (Control->MetricParams.Wcett.PktPairMinOverProbes < 1)
return STATUS_INVALID_PARAMETER_9;
}
break;
}
//
// Now, set the ones that we need to set.
//
if (Control->Snooping != (boolint) -1)
VA->Snooping = Control->Snooping;
if (Control->ArtificialDrop != (boolint) -1)
VA->ArtificialDrop = Control->ArtificialDrop;
if (Control->Crypto != (boolint) -1)
VA->Crypto = Control->Crypto;
if (Control->LinkTimeout != (uint)-1)
VA->LinkTimeout = (Time)Control->LinkTimeout * SECOND;
switch (Control->MetricType) {
case METRIC_TYPE_PKTPAIR:
if (Control->MetricParams.PktPair.Alpha != (uint)-1)
VA->MetricParams.PktPair.Alpha = Control->MetricParams.PktPair.Alpha;
if (Control->MetricParams.PktPair.ProbePeriod != (uint)-1)
VA->MetricParams.PktPair.ProbePeriod = Control->MetricParams.PktPair.ProbePeriod;
if (Control->MetricParams.PktPair.PenaltyFactor != (uint)-1)
VA->MetricParams.PktPair.PenaltyFactor = Control->MetricParams.PktPair.PenaltyFactor;
break;
case METRIC_TYPE_WCETT:
if (Control->MetricParams.Wcett.ProbePeriod != (uint)-1)
VA->MetricParams.Wcett.ProbePeriod = Control->MetricParams.Wcett.ProbePeriod;
if (Control->MetricParams.Wcett.LossInterval != (uint)-1)
VA->MetricParams.Wcett.LossInterval = Control->MetricParams.Wcett.LossInterval;
if (Control->MetricParams.Wcett.Alpha != (uint)-1)
VA->MetricParams.Wcett.Alpha = Control->MetricParams.Wcett.Alpha;
if (Control->MetricParams.Wcett.PenaltyFactor != (uint)-1)
VA->MetricParams.Wcett.PenaltyFactor = Control->MetricParams.Wcett.PenaltyFactor;
if (Control->MetricParams.Wcett.Beta != (uint)-1)
VA->MetricParams.Wcett.Beta = Control->MetricParams.Wcett.Beta;
if (Control->MetricParams.Wcett.PktPairProbePeriod != (uint)-1)
VA->MetricParams.Wcett.PktPairProbePeriod = Control->MetricParams.Wcett.PktPairProbePeriod;
if (Control->MetricParams.Wcett.PktPairMinOverProbes != (uint)-1)
VA->MetricParams.Wcett.PktPairMinOverProbes = Control->MetricParams.Wcett.PktPairMinOverProbes;
break;
}
return STATUS_SUCCESS;
}
//* MiniportInitialize
//
// Called by NDIS to initialize an adapter.
//
NDIS_STATUS
MiniportInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE WrapperConfigurationContext)
{
VRR_CONTROL_VIRTUAL_ADAPTER Control;
MiniportAdapter *VA;
HANDLE KeyHandle;
LARGE_INTEGER Timeout;
KIRQL OldIrql;
NDIS_STATUS Status;
NTSTATUS NtStatus;
uint i;
UNREFERENCED_PARAMETER(OpenErrorStatus);
UNREFERENCED_PARAMETER(WrapperConfigurationContext);
//
// We emulate 802.3. Figure out which index that is.
//
for (i = 0; ; i++) {
if (i == MediumArraySize) {
Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
goto ErrorReturn;
}
if (MediumArray[i] == NdisMedium802_3) {
*SelectedMediumIndex = i;
break;
}
}
//
// Allocate our virtual adapter structure.
//
VA = (MiniportAdapter *) ExAllocatePool(NonPagedPool, sizeof *VA);
if (VA == NULL) {
Status = NDIS_STATUS_RESOURCES;
goto ErrorReturn;
}
KdPrint(("VRR!MiniportInitialize -> VA %p\n", VA));
RtlZeroMemory(VA, sizeof *VA);
VA->Index = InterlockedIncrement((PLONG)&NextVirtualAdapterIndex);
KeInitializeSpinLock(&VA->Lock);
NeighborCacheInit(&VA->NC);
NodeTableInit(&VA->NT);
RouteTableInit(&VA->RT);
TearDownCacheInit(&VA->TDC);
ProbeListInit(&VA->PL);
ZeroListInit(&VA->ZL);
PacketIndexInit(&VA->PX);
BroadcastListInit(&VA->BL);
PbackInit(VA);
VA->MiniportHandle = MiniportAdapterContext;
VA->Snooping = TRUE;
VA->ArtificialDrop = FALSE;
VA->LinkTimeout = (Time)1 * MINUTE;
VA->LookAhead = 0;
VA->MediumLinkSpeed = 100000; // 10 Mbps.
VA->MediumMinPacketLen = MINIPORT_HEADER_SIZE;
VA->MediumMaxPacketLen = MINIPORT_HEADER_SIZE + MINIPORT_MAX_FRAME_SIZE;
VA->MediumMacHeaderLen = MINIPORT_HEADER_SIZE;
VA->MediumMaxFrameLen = MINIPORT_MAX_FRAME_SIZE;
VA->MinVersionSeen = Version;
VA->MaxVersionSeen = Version;
VA->RateAdmitThreshold = RATE_ADMIT_DEFAULT;
VA->RateEvictThreshold = RATE_EVICT_DEFAULT;
VA->RssiAdmitThreshold = RSSI_ADMIT_DEFAULT;
VA->RssiEvictThreshold = RSSI_EVICT_DEFAULT;
//
// Get our device objects.
//
NdisMGetDeviceProperty(MiniportAdapterContext,
&VA->PhysicalDeviceObject,
&VA->DeviceObject,
NULL, NULL, NULL);
//
// Allocate a packet pool.
//
NdisAllocatePacketPool(&Status, &VA->PacketPool,
PACKET_POOL_SZ, sizeof(PacketContext));
if (Status != NDIS_STATUS_SUCCESS) {
KdPrint(("VRR!NdisAllocatePacketPool -> %x\n", Status));
goto ErrorFreePool;
}
//
// Allocate a buffer pool.
//
NdisAllocateBufferPool(&Status, &VA->BufferPool, PACKET_POOL_SZ * 2);
if (Status != NDIS_STATUS_SUCCESS) {
KdPrint(("VRR!NdisAllocateBufferPool -> %x\n", Status));
goto ErrorFreePacketPool;
}
//
// Give NDIS some information about our virtual adapter.
//
NdisMSetAttributesEx(MiniportAdapterContext, VA, 0,
NDIS_ATTRIBUTE_IGNORE_TOKEN_RING_ERRORS |
NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT |
NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND |
NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK |
NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS |
NDIS_ATTRIBUTE_DESERIALIZE,
0);
//
// Open our configuration information in the registry.
//
NtStatus = IoOpenDeviceRegistryKey(VA->PhysicalDeviceObject,
PLUGPLAY_REGKEY_DRIVER,
GENERIC_READ,
&KeyHandle);
if (! NT_SUCCESS(NtStatus)) {
KdPrint(("VRR!IoOpenDeviceRegistryKey -> %x\n", NtStatus));
Status = NDIS_STATUS_FAILURE;
goto ErrorFreeBufferPool;
}
//
// Read the adapter's virtual link-layer address.
//
Status = MiniportReadOrCreateAdapterAddress(KeyHandle, VA->Address);
if (Status != NDIS_STATUS_SUCCESS)
goto ErrorCloseRegistry;
Uint64ToVirtualAddress(VirtualAddressToUint64(VA->Address)-1,VA->AddressDec);
Uint64ToVirtualAddress(VirtualAddressToUint64(VA->Address)+1,VA->AddressInc);
VrrTrace(VA,1,"MP:**=Addresses(self-1,self,self+1)",
VA->AddressDec, VA->Address, VA->AddressInc,NULL,0,NULL,0);
//
// Read the adapter's guid.
//
NtStatus = GetRegGuid(KeyHandle, L"NetCfgInstanceId", &VA->Guid);
if (! NT_SUCCESS(NtStatus)) {
KdPrint(("VRR!GetRegGuid -> %x\n", NtStatus));
Status = NDIS_STATUS_FAILURE;
goto ErrorCloseRegistry;
}
ZwClose(KeyHandle);
//
// Read configuration parameters from the registry.
//
MiniportReadControl(VA, &Control);
//
// Initialize Metric parameters.
// The default MetricType was WCETT - which is now imposed.
//
Control.MetricType = METRIC_TYPE_WCETT;
switch (Control.MetricType) {
case METRIC_TYPE_PKTPAIR:
VA->MetricType = METRIC_TYPE_PKTPAIR;
PktPairInit(VA);
break;
case METRIC_TYPE_WCETT:
default:
VA->MetricType = METRIC_TYPE_WCETT;
WcettInit(VA);
break;
}
if (VRR_KEY_PRESENT(Control.CryptoKeyMAC) &&
VRR_KEY_PRESENT(Control.CryptoKeyAES)) {
//
// Initialize the crypto parameters.
// Crypto will be enabled, unless MiniportControl overrides.
//
VA->Crypto = TRUE;
RtlCopyMemory(VA->CryptoKeyMAC, Control.CryptoKeyMAC,
sizeof VA->CryptoKeyMAC);
RtlCopyMemory(VA->CryptoKeyAES, Control.CryptoKeyAES,
sizeof VA->CryptoKeyAES);
}
#if BUILD_CRYPTO // DDK
//
// Modify our MAC key, using Version and MetricType.
// If they disagree then nodes should fail to communicate.
//
CryptoKeyMACModify(VA, VA->CryptoKeyMAC);
#endif
//
// Update the virtual adapter using the parameters.
// This can modify VA->Crypto but not MetricType,
// CryptoKeyMAC, or CryptoKeyAES.
//
(void) MiniportControl(VA, &Control);
VA->JoiningOnHold = JOINING_ON_HOLD;
VA->PartitionRepairEnabled = PARTITION_REPAIR_ENABLED;
VA->BroadcastRelay = BROADCAST_RELAY_ENABLED;
VA->BroadcastJitterMinMs = BC_MIN_JITTER;
VA->BroadcastJitterMaxMs = BC_MAX_JITTER;
VA->TxDropAllButHello = TX_DROP_ALL;
VA->TxDropAllHello = TX_DROP_HELLO;
VA->VrrTraceNoiseLevel = DEFAULT_TRACE_NOISE;
VA->DriverLoadTime = KeQueryInterruptTime() + DriverLoadDelay;
//
// Init VrrGlobal.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -