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

📄 io.c

📁 Vitual Ring Routing 管你知不知道
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -