⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 Vitual Ring Routing 管你知不知道
💻 C
📖 第 1 页 / 共 5 页
字号:
            uint NextHopsMatch = FALSE;
            
            if (RTE == SentinelRTE(&VA->RT)) {
                KeReleaseSpinLock(&VA->RT.Lock, OldIrql);
                Status = STATUS_INVALID_PARAMETER_2;

                goto Return;
            }

            //
            // Look for RTE matching the query.
            //
            if (VirtualAddressEqual(Query->EndpointA, RTE->A.Address) &&
                Query->PathId == RTE->PathId &&
                Query->addr == (uint)RTE) {    // gregos: debug then remove
                
                break;
            }
        }

        //
        // Return miscellaneous information about the RTE.
        //
        RtlCopyMemory(Info->EndpointA, RTE->A.Address, sizeof(VirtualAddress));
        RtlCopyMemory(Info->EndpointB, RTE->B.Address, sizeof(VirtualAddress));
        Info->PathId = RTE->PathId;
        KeAcquireSpinLockAtDpcLevel(&VA->NC.Lock);
        if (NULL != RTE->A.Next) {
            RtlCopyMemory(Info->NextA, RTE->A.Next->VAddress, sizeof(VirtualAddress));
            Info->LocIFa = RTE->A.Next->LocIF;
            Info->RemIFa = RTE->A.Next->RemIF;
        } else {
            RtlCopyMemory(Info->NextA, VRR_ADDRESS_UNSPECIFIED, sizeof(VirtualAddress));
            Info->LocIFa = VRR_IFID_UNSPECIFIED;
            Info->RemIFa = VRR_IFID_UNSPECIFIED;
        }
        if (NULL != RTE->B.Next) {
            RtlCopyMemory(Info->NextB, RTE->B.Next->VAddress, sizeof(VirtualAddress));
            Info->LocIFb = RTE->B.Next->LocIF;
            Info->RemIFb = RTE->B.Next->RemIF;
        } else {
            RtlCopyMemory(Info->NextB, VRR_ADDRESS_UNSPECIFIED, sizeof(VirtualAddress));
            Info->LocIFb = VRR_IFID_UNSPECIFIED;
            Info->RemIFb = VRR_IFID_UNSPECIFIED;
        }
        KeReleaseSpinLockFromDpcLevel(&VA->NC.Lock);
        Info->RefCnt = RTE->RefCnt;
        Info->State = RTE->State;
        Info->Flags = RTE->Flags;
        Info->ETT = RTE->ETT;
        Info->Timeout = TIMEOUT_TO_MS(RTE->Timeout);

        //
        // Return address of the next NTE (or zero).
        // Again, ensure enough for uniqueness of next query.
        //
        if (RTE->Next == SentinelRTE(&VA->RT)) {
            RtlZeroMemory(Info->Query.EndpointA, sizeof(VirtualAddress));
        }
        else {
            // Ensure enough here to uniquely identify the next RTE for the next query.
            RTE = RTE->Next;
            RtlCopyMemory(Info->Query.EndpointA, RTE->A.Address, sizeof(VirtualAddress));
            Info->Query.PathId =  RTE->PathId;
            Info->Query.addr = (uint)RTE;
        }

        KeReleaseSpinLock(&VA->RT.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;

}

//* ExecCommand
//
//  Helper for ioVrrCommand. Attempts the requested command.
//
uchar
ExecCommand(
    MiniportAdapter *VA,
    uchar OpCode,
    uchar Arg)
{
    uchar ExecResult = VRR_COMMAND_BAD_OPCODE;
    KIRQL OldIrql;

    if (OpCode == VRR_COMMAND_BOOT) {
        //
        // Set self active iff DriverLoadTime expired and not JoiningOnHold.
        //
        uint JoiningOnHold = IsJoiningOnHold(VA);
        Time Now = KeQueryInterruptTime();

        if (JoiningOnHold != 0) {
            VrrKdPrint("ExecCmd: cannot activate ring while JoiningOnHold!=0", NULL, NULL);
            ExecResult = VRR_COMMAND_NOT_READY;
        }
        else if (VA->DriverLoadTime > Now) {
            VrrKdPrint("ExecCmd: cannot activate ring during DriverLoadTime\n",NULL,NULL);
            ExecResult = VRR_COMMAND_NOT_READY;
        }
        else {
            VrrKdPrint("ExecCmd: Becoming boot node for ring at user command\n",NULL,NULL);
            KeAcquireSpinLock(&VA->NT.Lock, &OldIrql);
            SetSelfActive(VA,TRUE);  // VRR_COMMAND_BOOT
            InterlockedExchange(&VA->BootNode,TRUE);
            VA->MsFirstJoinSetupReq = TIME_TO_MS(KeQueryInterruptTime());
            KeReleaseSpinLock(&VA->NT.Lock, OldIrql);
            ExecResult = VRR_COMMAND_SUCCESS;
        }
    }
    else if (OpCode == VRR_COMMAND_SET_ADDR) {
        //
        // Not supported on VrrAPI. Ioctl must do this inline.
        //
        ExecResult = VRR_COMMAND_BAD_OPCODE;
    }
    else if (OpCode == VRR_COMMAND_ASSERT) {
        KdPrint(("ExecCmd: set VrrGlobal.KdBreakPointOnAssert = %i\n",Arg));
        VrrGlobal.KdBreakPointOnAssert = Arg;
        ExecResult = VRR_COMMAND_SUCCESS;
    }
    else if (OpCode == VRR_COMMAND_COUNTER_INIT) {
        NeighborCache *NC = &VA->NC;
        NeighborCacheEntry *NCE;

        KdPrint(("ExecCmd: reset counters to zero\n"));

        KeAcquireSpinLock(&NC->Lock, &OldIrql);
        for (NCE = NC->FirstNCE; NCE != SentinelNCE(NC); NCE = NCE->Next) {
            NCE->CountFailRexmit = 0;
            NCE->CountFailHelloLoss = 0;
            NCE->CountFailQoSEvict = 0;
            NCE->CountFailHelloFail = 0;
        }
        KeReleaseSpinLock(&NC->Lock, OldIrql);

        MaintBufResetStatistics(VA);

        InterlockedExchange((PLONG)&VA->MsJoinToHeardExpectedVSet,0);
        InterlockedExchange((PLONG)&VA->MsJoinToPathsExpectedVSet,0);
        InterlockedExchange((PLONG)&VA->CountSRNackSeqT,0);
        InterlockedExchange((PLONG)&VA->CountExitRing,0);
        InterlockedExchange((PLONG)&VA->CountExitExecCmd,0);
        InterlockedExchange((PLONG)&VA->CountExitNCE,0);
        InterlockedExchange((PLONG)&VA->CountExitNTE,0);
        InterlockedExchange((PLONG)&VA->CountSetActiveT,0);
        InterlockedExchange((PLONG)&VA->CountSetActiveF,0);
        InterlockedExchange((PLONG)&VA->CountMaxPLE,0);
        InterlockedExchange((PLONG)&VA->BootNode,0);
        InterlockedExchange((PLONG)&VA->MaxMsgTimeDelay,0);
        InterlockedExchange((PLONG)&VA->MaxMsgCountDelayed,0);
        InterlockedExchange((PLONG)&VA->CountMsQDropCritical,0);
        InterlockedExchange((PLONG)&VA->CountPnRepairSendSetup,0);
        InterlockedExchange((PLONG)&VA->CountHopCountExceeded,0);
        InterlockedExchange((PLONG)&VA->CountNTECloserThanSelf,0);
        InterlockedExchange((PLONG)&VA->CountSendHello,0);
        InterlockedExchange((PLONG)&VA->CountSendSetup,0);
        InterlockedExchange((PLONG)&VA->CountSendTearDown,0);
        InterlockedExchange((PLONG)&VA->CountSendSetupReq,0);
        InterlockedExchange((PLONG)&VA->CountSendSetupReqNack,0);
        InterlockedExchange((PLONG)&VA->CountFwdSetup,0);
        InterlockedExchange((PLONG)&VA->CountFwdTearDown,0);
        InterlockedExchange((PLONG)&VA->CountFwdSetupReq,0);
        InterlockedExchange((PLONG)&VA->CountMisroutedSetup,0);
        InterlockedExchange((PLONG)&VA->CountMisroutedSetupReq,0);
        InterlockedExchange((PLONG)&VA->CountMisroutedTearDown,0);
        InterlockedExchange((PLONG)&VA->CountSRDropHopCount,0);
        InterlockedExchange((PLONG)&VA->CountSRDropLoop,0);
        InterlockedExchange((PLONG)&VA->MaxPLESRcAntiRoute,0);
        InterlockedExchange((PLONG)&VA->MaxPLESRcAntiRouteRcv,0);
        InterlockedExchange((PLONG)&VA->CountFNHSRcAntiRoute,0);
        InterlockedExchange((PLONG)&VA->CountFNHsendSRleft,0);
        InterlockedExchange((PLONG)&VA->CountFNHsendSRright,0);
        InterlockedExchange((PLONG)&VA->CountRecvHello,0);
        InterlockedExchange((PLONG)&VA->CountRecvSetup,0);
        InterlockedExchange((PLONG)&VA->CountRecvTearDown,0);
        InterlockedExchange((PLONG)&VA->CountRecvSetupReq,0);
        InterlockedExchange((PLONG)&VA->CountRecvSRleft,0);
        InterlockedExchange((PLONG)&VA->CountRecvSRright,0);
        InterlockedExchange((PLONG)&VA->CountGenSRleft,0);
        InterlockedExchange((PLONG)&VA->CountGenSRright,0);
        RtlZeroMemory(VA->AddErrorVSet, sizeof(uint)*VRR_MAX_VSET_SIZE);
        RtlZeroMemory(VA->RejExpBypass, sizeof(uint)*REJ_EXP_BYPASS_COUNT);
        
        ExecResult = VRR_COMMAND_SUCCESS;
    }
    else if (OpCode == VRR_COMMAND_RATE_ADMIT) {
        uint RateEvictThreshold = InterlockedCompareExchange(&VA->RateEvictThreshold,0,0);
        uint BitsPerSec = MBPS_TO_BPS(Arg);

        if (BitsPerSec > RATE_ADMIT_MAX_BPS ||
            BitsPerSec < RATE_EVICT_MIN_BPS ||
            BitsPerSec <= RateEvictThreshold) {
            VrrKdPrint("ExecCmd: reject invalid RateAdmitThreshold", NULL, NULL);
            KdPrint(("    bps(%u) max(%u) min(%u) RateEvictThreshold(%u)\n",
                     BitsPerSec,RATE_ADMIT_MAX_BPS,RATE_EVICT_MIN_BPS,RateEvictThreshold));
            ExecResult = VRR_COMMAND_BAD_ARG;
        }
        else {
            InterlockedExchange(&VA->RateAdmitThreshold, BitsPerSec);
            ExecResult = VRR_COMMAND_SUCCESS;
        }
    }
    else if (OpCode == VRR_COMMAND_RATE_EVICT) {
        uint RateAdmitThreshold = InterlockedCompareExchange(&VA->RateAdmitThreshold,0,0);
        uint BitsPerSec = MBPS_TO_BPS(Arg);

        if (BitsPerSec > RATE_ADMIT_MAX_BPS ||
            BitsPerSec < RATE_EVICT_MIN_BPS ||
            BitsPerSec >= RateAdmitThreshold) {
            VrrKdPrint("ExecCmd: reject invalid RateEvictThreshold", NULL, NULL);
            KdPrint(("    bps(%u) max(%u) min(%u) RateAdmitThreshold(%u)\n",
                 BitsPerSec,RATE_ADMIT_MAX_BPS,RATE_EVICT_MIN_BPS,RateAdmitThreshold));

            ExecResult = VRR_COMMAND_BAD_ARG;
        }
        else {
            InterlockedExchange(&VA->RateEvictThreshold, BitsPerSec);
            ExecResult = VRR_COMMAND_SUCCESS;
        }
    }
    else if (OpCode == VRR_COMMAND_JOIN_HOLD) {
        uint JoiningOnHold = IsJoiningOnHold(VA);
        Time Now = KeQueryInterruptTime();

        if (JoiningOnHold == 0 && Arg != 0) {
            VrrKdPrint("ExecCmd: reject invalid JoiningOnHold", NULL, NULL);
            ExecResult = VRR_COMMAND_BAD_ARG;
        }
        else if (VA->DriverLoadTime > Now) {
            ExecResult = VRR_COMMAND_NOT_READY;
        }
        else {
            InterlockedExchange(&VA->JoiningOnHold, Arg);
            SetVSetChanged(VA);
            ExecResult = VRR_COMMAND_SUCCESS;
        }
    }
    else if (OpCode == VRR_COMMAND_RSSI_ADMIT) {
        uint RssiEvictThreshold = InterlockedCompareExchange(&VA->RssiEvictThreshold,0,0);
        uint Rssi = Arg;

        if (Rssi > RSSI_ADMIT_MAX ||
            Rssi < RSSI_EVICT_MIN ||
            Rssi <= RssiEvictThreshold) {
            VrrKdPrint("ExecCmd: reject invalid RssiAdmitThreshold", NULL, NULL);
            KdPrint(("    bps(%u) max(%u) min(%u) RssiEvictThreshold(%u)\n",
                     Rssi,RSSI_ADMIT_MAX,RSSI_EVICT_MIN,RssiEvictThreshold));
            ExecResult = VRR_COMMAND_BAD_ARG;
        }
        else {
            InterlockedExchange(&VA->RssiAdmitThreshold, Rssi);
            ExecResult = VRR_COMMAND_SUCCESS;
        }
    }
    else if (OpCode == VRR_COMMAND_RSSI_EVICT) {
        uint RssiAdmitThreshold = InterlockedCompareExchange(&VA->RssiAdmitThreshold,0,0);
        uint Rssi = Arg;

        if (Rssi > RSSI_ADMIT_MAX ||
            Rssi < RSSI_EVICT_MIN ||
            Rssi >= RssiAdmitThreshold) {
            VrrKdPrint("ExecCmd: reject invalid RssiEvictThreshold", NULL, NULL);
            KdPrint(("    bps(%u) max(%u) min(%u) RssiAdmitThreshold(%u)\n",
                 Rssi,RSSI_ADMIT_MAX,RSSI_EVICT_MIN,RssiAdmitThreshold));

            ExecResult = VRR_COMMAND_BAD_ARG;
        }
        else {
            InterlockedExchange(&VA->RssiEvictThreshold, Rssi);
            ExecResult = VRR_COMMAND_SUCCESS;
        }
    }
    else if (OpCode == VRR_COMMAND_PN_REPAIR) {
        InterlockedExchange(&VA->PartitionRepairEnabled, Arg);
        ExecResult = VRR_COMMAND_SUCCESS;
    }
    else if (OpCode == VRR_COMMAND_KDFLUSH) {
        int i;

        for (i = 0; i < Arg; i++)
            VrrTrace(VA, 2, "IO:EX=flush",NULL,NULL,NULL,"This",i,"Max",Arg);

        ExecResult = VRR_COMMAND_SUCCESS;
    }
    else if (OpCode == VRR_COMMAND_RESET) {
        VrrTrace(VA,2,"IO:EX=Reset",NULL,NULL,NULL,NULL,0,"Arg",Arg);
        FailAllNeigboursAndChangeState(VA,Arg);
        InterlockedExchange(&VA->JoiningOnHold, TRUE);
        InterlockedIncrement(&VA->CountExitExecCmd);
        ExecResult = VRR_COMMAND_SUCCESS;
    }
    else if (OpCode == VRR_COMMAND_NOISE_LEVEL) {
        InterlockedExchange(&VA->VrrTraceNoiseLevel, Arg);
        ExecResult = VRR_COMMAND_SUCCESS;
    }
    else if (OpCode == VRR_COMMAND_BC_RELAY) {
        InterlockedExchange(&VA->BroadcastRelay, Arg);
        ExecResult = VRR_COMMAND_SUCCESS;
    }
    else if (OpCode == VRR_COMMAND_TX_DROP_ALL) {
        InterlockedExchange(&VA->TxDropAllButHello, Arg);
        ExecResult = VRR_COMMAND_SUCCESS;
    }
    else if (OpCode == VRR_COMMAND_TX_DROP_HELLO) {
        InterlockedExchange(&VA->TxDropAllHello, Arg);
        ExecResult = VRR_COMMAND_SUCCESS;
    }

    return ExecResult;

}

//* IoVrrCommand
//
//  Simple command interface.
//
NTSTATUS
IoVrrCommand(
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpSp)
{
    VRR_COMMAND *Command;
    MiniportAdapter *VA = NULL;
    KIRQL OldIrql;
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    uchar ExecResult = VRR_COMMAND_ERROR;

    PAGED_CODE();
    
    Irp->IoStatus.Information = 0;

    if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Command) {
        Status = STATUS_INVALID_PARAMETER;
        goto Return;
    }

    Command = (VRR_COMMAND *) Irp->AssociatedIrp.SystemBuffer;

    //
    // Return information about the specified virtual adapter.
    //
    VA = FindVirtualAdapterFromQuery(&Command->VA);
    if (VA == NULL) {
        Status = STATUS_INVALID_PARAMETER_1;
        goto Return;
    }

    //
    // Attempt to execute the command.
    // Do inline those things that aren't supported by ExecCommand.
    //
    if (Command->OpCode == VRR_COMMAND_SET_ADDR) {
        HANDLE KeyHandle;
    
        VrrKdPrint("IoCmd: set VRR Address in registry", Command->ArgAddress, NULL);
        Status = STATUS_SUCCESS;
        ExecResult = VRR_COMMAND_SUCCESS;
        
        if (IsUnspecified(Command->ArgAddress)) {
            VrrKdPrint("IoCmd: reject unspecified address as new VA->Address", NULL, NULL);
            Status = STATUS_INVALID_PARAMETER_2;
            goto Return;
        }
        if (IsIEEEGroupAddress(Command->ArgAddress)) {
            VrrKdPrint("IoCmd: reject broadcast address as new VA->Address", NULL, NULL);
            Status = STATUS_INVALID_PARAMETER_2;
            goto Return;
        }
        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -