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

📄 io.c

📁 Vitual Ring Routing 管你知不知道
💻 C
📖 第 1 页 / 共 5 页
字号:
IoQueryMaintenanceBuffer(
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpSp)
{
    VRR_QUERY_MAINTENANCE_BUFFER_NODE *Query;
    VRR_INFO_MAINTENANCE_BUFFER_NODE *Info;
    MiniportAdapter *VA;
    MaintBufNode *MBN;
    Time Delta;
    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_MAINTENANCE_BUFFER_NODE *)
        Irp->AssociatedIrp.SystemBuffer;
    Info = (VRR_INFO_MAINTENANCE_BUFFER_NODE *)
        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->Node.Address)) {
        //
        // Return query information for the first maintenance buffer node.
        //
        KeAcquireSpinLock(&VA->MaintBuf->Lock, &OldIrql);
        ReturnQueryMaintenanceBufferNode(VA->MaintBuf->MBN, &Info->Query);
        KeReleaseSpinLock(&VA->MaintBuf->Lock, OldIrql);

        Irp->IoStatus.Information = sizeof Info->Query;
    }
    else {
        //
        // Return information about the specified maintenance buffer node.
        //
        KeAcquireSpinLock(&VA->MaintBuf->Lock, &OldIrql);
        for (MBN = VA->MaintBuf->MBN; ; MBN = MBN->Next) {
            if (MBN == NULL) {
                KeReleaseSpinLock(&VA->MaintBuf->Lock, OldIrql);
                Status = STATUS_INVALID_PARAMETER_2;
                goto ReturnReleaseVA;
            }

            if (RtlEqualMemory(MBN->Address,
                               Query->Node.Address, SR_ADDR_LEN) &&
                (MBN->InIf == Query->Node.InIF) &&
                (MBN->OutIf == Query->Node.OutIF))
                break;
        }

        //
        // Return query information for the next maintenance buffer node.
        //
        ReturnQueryMaintenanceBufferNode(MBN->Next, &Info->Query);

        //
        // Return miscellaneous information about the maintenance buffer node.
        //
        Delta = IoTimeDelta();
        Info->NextAckNum = MBN->NextAckNum;
        Info->FirstAckReq = MBN->FirstAckReq + Delta;
        Info->LastAckReq = MBN->LastAckReq + Delta;
        Info->LastAckNum = MBN->LastAckNum;
        Info->LastAckRcv = MBN->LastAckRcv + Delta;
        Info->NumPackets = MBN->NumPackets;
        Info->HighWater = MBN->HighWater;
        Info->NumAckReqs = MBN->NumAckReqs;
        Info->NumFastReqs = MBN->NumFastReqs;
        Info->NumValidAcks = MBN->NumValidAcks;
        Info->NumInvalidAcks = MBN->NumInvalidAcks;
        Info->MBNCountPackets = MBN->MBNCountPackets;
        Info->MBNTxSuccess = MBN->MBNTxSuccess;
        Info->MBNRexmits = MBN->MBNRexmits;
        Info->MBNTxFailed = MBN->MBNTxFailed;

        KeReleaseSpinLock(&VA->MaintBuf->Lock, OldIrql);

        Irp->IoStatus.Information = sizeof *Info;
    }

    ReturnQueryVirtualAdapter(VA, &Info->Query.VA);
    Status = STATUS_SUCCESS;
ReturnReleaseVA:
#if 0
    ReleaseVA(VA);
#endif
Return:
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;
}


//* IoResetStatistics
//
//  Resets our counters and statistics gathering.
//
NTSTATUS
IoResetStatistics(
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpSp)
{
    VRR_QUERY_VIRTUAL_ADAPTER *Query;
    MiniportAdapter *VA;
    NTSTATUS Status;

    Irp->IoStatus.Information = 0;

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

    Query = (VRR_QUERY_VIRTUAL_ADAPTER *)
        Irp->AssociatedIrp.SystemBuffer;

    //
    // Use the specified virtual adapter.
    //
    VA = FindVirtualAdapterFromQuery(Query);
    if (VA == NULL) {
        Status = STATUS_INVALID_PARAMETER_1;
        goto Return;
    }

    MiniportResetStatistics(VA);

    Status = STATUS_SUCCESS;
#if 0
    ReleaseVA(VA);
#endif
Return:
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;
}

//* IoControlVirtualAdapter
//
//  Handles requests to change attributes of a virtual adapter.
//
NTSTATUS
IoControlVirtualAdapter(
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpSp,
    IN boolint Persistent)
{
    VRR_CONTROL_VIRTUAL_ADAPTER *Control;
    MiniportAdapter *VA;
    NTSTATUS Status;

    Irp->IoStatus.Information = 0;

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

    Control = (VRR_CONTROL_VIRTUAL_ADAPTER *) Irp->AssociatedIrp.SystemBuffer;

    //
    // Get the specified virtual adapter.
    //
    VA = FindVirtualAdapterFromQuery(&Control->This);
    if (VA == NULL) {
        Status = STATUS_INVALID_PARAMETER_1;
        goto Return;
    }

    if (Persistent)
        Status = MiniportPersistControl(VA, Control);
    else
        Status = MiniportControl(VA, Control);

Return:
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;
}

//* IoControlPhysicalAdapter
//
//  Handles requests to change attributes of a physical adapter.
//
NTSTATUS
IoControlPhysicalAdapter(
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpSp)
{
    VRR_CONTROL_PHYSICAL_ADAPTER *Control;
    MiniportAdapter *VA;
    ProtocolAdapter *PA;
    NTSTATUS Status;

    Irp->IoStatus.Information = 0;

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

    Control = (VRR_CONTROL_PHYSICAL_ADAPTER *) Irp->AssociatedIrp.SystemBuffer;

    //
    // Get the specified virtual adapter.
    //
    VA = FindVirtualAdapterFromQuery(&Control->This.VA);
    if (VA == NULL) {
        Status = STATUS_INVALID_PARAMETER_1;
        goto Return;
    }

    //
    // Get the specified physical adapter.
    //
    PA = FindPhysicalAdapterFromQuery(VA, &Control->This);
    if (PA == NULL) {
        Status = STATUS_INVALID_PARAMETER_2;
        goto ReturnReleaseVA;
    }

    Status = ProtocolControl(PA, Control);

#if 0
    ReleasePA(PA);
#endif
ReturnReleaseVA:
#if 0
    ReleaseVA(VA);
#endif
Return:
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;
}

//* IoQueryVSet
//
//  Handles queries for information about our VSet.
//
NTSTATUS
IoQueryVSet(
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpSp)
{
    VRR_QUERY_VSET *Query;
    VRR_INFO_VSET *Info;
    MiniportAdapter *VA = NULL;
    NodeTable *NT;
    NodeTableEntry *NTE;
    KIRQL OldIrql;
    NTSTATUS Status;
    uint i;

    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_VSET *) Irp->AssociatedIrp.SystemBuffer;
    Info = (VRR_INFO_VSET *) Irp->AssociatedIrp.SystemBuffer;

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

    //
    // Copy VSetLeft + self + VSetRight to info buffer.
    //
    RtlZeroMemory(Info->VSet,sizeof (Info->VSet));
    NT = &VA->NT;
    KeAcquireSpinLock(&NT->Lock, &OldIrql);
    VSetToFlatBuffer(VA,Info->VSet);
    Info->NTCount = VA->NT.Count;
    KeReleaseSpinLock(&NT->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;

}

//* IoQueryRouteTableEntry
//
//  Handles queries for information about a route table entry.
//
NTSTATUS
IoQueryRouteTableEntry(
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpSp)
{
    VRR_QUERY_ROUTE_TABLE_ENTRY *Query;
    VRR_INFO_ROUTE_TABLE_ENTRY *Info;
    MiniportAdapter *VA = NULL;
    RouteTableEntry *RTE;
    KIRQL OldIrql;
    NTSTATUS Status;

    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_ROUTE_TABLE_ENTRY *) Irp->AssociatedIrp.SystemBuffer;
    Info = (VRR_INFO_ROUTE_TABLE_ENTRY *) 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->EndpointA)) {
        //
        // Return the address of the first NTE.
        //
        KeAcquireSpinLock(&VA->RT.Lock, &OldIrql);
        if (VA->RT.FirstRTE != SentinelRTE(&VA->RT)) {
            RTE = VA->RT.FirstRTE;
            // Ensure enough here to uniquely identify the entry.
            RtlCopyMemory(Info->Query.EndpointA, RTE->A.Address, sizeof(VirtualAddress));
            Info->Query.PathId =  RTE->PathId;
            Info->Query.addr = (uint)RTE; // gregos: debug then remove
        }
        KeReleaseSpinLock(&VA->RT.Lock, OldIrql);
        Irp->IoStatus.Information = sizeof Info->Query;
    }
    else {
        //
        // Find the specified RTE.
        //
        KeAcquireSpinLock(&VA->RT.Lock, &OldIrql);
        for (RTE = VA->RT.FirstRTE; ; RTE = RTE->Next) {

⌨️ 快捷键说明

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