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

📄 miniport.c

📁 Vitual Ring Routing 管你知不知道
💻 C
📖 第 1 页 / 共 5 页
字号:
    //
    (void) GlobalInit(VA);

    //
    // Init VrrHelloParams.
    //
    VrrHelloInit(VA);
    
    //
    // Now we have our address we can set up our NTE.
    //
    VA->NT.Self = NodeInitSelf(VA);
    if (NULL == VA->NT.Self)
        goto ErrorFreeBufferPool;

    //
    // Set up our maintenance buffer.
    //
    VA->MaintBuf = MaintBufNew();
    if (VA->MaintBuf == NULL)
        goto ErrorFreeSelf;

    //
    // Set up our forwarding queue.
    //
    VA->ForwardLast = &VA->ForwardList;
    VRRASSERT(VA->ForwardList == NULL);
    VRRASSERT(VA->ForwardTime == 0);

    //
    // Initialize with NDIS as a protocol. This will bind
    // our virtual adapter to physical adapters,
    // based on the protocol name that we supply here.
    //
    Status = ProtocolInit(L"msvrrtp", VA); 
    if (Status != NDIS_STATUS_SUCCESS)
        goto ErrorFreeMaintBuffer;

    //
    // We have an aperiodic timeout function,
    // with a maximum timeout of MINIPORT_TIMEOUT.
    //
    VA->TimeoutMinLoops = MAXULONG;
    KeInitializeDpc(&VA->TimeoutDpc, MiniportTimeout, VA);
    KeInitializeTimer(&VA->Timer);
    Timeout.QuadPart = - (LONGLONG) (MINIPORT_TIMEOUT * 10000);
    VA->Timeout = KeQueryInterruptTime() - Timeout.QuadPart;
    KeSetTimer(&VA->Timer, Timeout, &VA->TimeoutDpc);

    //
    // Add the virtual adapter to our list.
    //
    KeAcquireSpinLock(&MiniportAdapters.Lock, &OldIrql);
    VA->Prev = &MiniportAdapters.VirtualAdapters;
    VA->Next = MiniportAdapters.VirtualAdapters;
    if (MiniportAdapters.VirtualAdapters != NULL)
        MiniportAdapters.VirtualAdapters->Prev = &VA->Next;
    MiniportAdapters.VirtualAdapters = VA;
    KeReleaseSpinLock(&MiniportAdapters.Lock, OldIrql);
   
    return NDIS_STATUS_SUCCESS;

ErrorCloseRegistry:
    ZwClose(KeyHandle);
    goto ErrorFreeBufferPool;

ErrorFreeMaintBuffer:
    MaintBufFree(VA);
ErrorFreeSelf:
    NodeTableCleanup(VA);
ErrorFreeBufferPool:
    NdisFreeBufferPool(VA->BufferPool);
ErrorFreePacketPool:
    NdisFreePacketPool(VA->PacketPool);
ErrorFreePool:
    ExFreePool(VA);
ErrorReturn:
    KdPrint(("VRR!MiniportInitialize -> %x\n", Status));
    return Status;
}

NDIS_OID MiniportSupportedOidArray[] =
{
    OID_GEN_SUPPORTED_LIST,
    OID_GEN_HARDWARE_STATUS,
    OID_GEN_MEDIA_SUPPORTED,
    OID_GEN_MEDIA_IN_USE,
    OID_GEN_MAXIMUM_LOOKAHEAD,
    OID_GEN_CURRENT_LOOKAHEAD,
    OID_GEN_MAXIMUM_FRAME_SIZE,
    OID_GEN_MAC_OPTIONS,
    OID_GEN_LINK_SPEED,
    OID_GEN_TRANSMIT_BUFFER_SPACE,
    OID_GEN_RECEIVE_BUFFER_SPACE,
    OID_GEN_MAXIMUM_TOTAL_SIZE,
    OID_GEN_TRANSMIT_BLOCK_SIZE,
    OID_GEN_RECEIVE_BLOCK_SIZE,
    OID_GEN_VENDOR_ID,
    OID_GEN_VENDOR_DESCRIPTION,
    OID_GEN_CURRENT_PACKET_FILTER,
    OID_GEN_DRIVER_VERSION,
    OID_GEN_MEDIA_CONNECT_STATUS,
    OID_GEN_MAXIMUM_SEND_PACKETS,

    OID_802_3_PERMANENT_ADDRESS,
    OID_802_3_CURRENT_ADDRESS,
    OID_802_3_MULTICAST_LIST,           // Set only?
    OID_802_3_MAXIMUM_LIST_SIZE,

    OID_802_3_RCV_ERROR_ALIGNMENT,
    OID_802_3_XMIT_ONE_COLLISION,
    OID_802_3_XMIT_MORE_COLLISIONS,

    OID_PNP_CAPABILITIES,
    OID_PNP_SET_POWER,                  // Set only.
    OID_PNP_QUERY_POWER,
};

uchar MiniportVendorDescription[] = "VRR Miniport Driver";
uchar MiniportVendorId[3] = {0xFF, 0xFF, 0xFF};

NDIS_PNP_CAPABILITIES MiniportPnpCapabilities = {
    0, 
    NdisDeviceStateUnspecified,
    NdisDeviceStateUnspecified,
    NdisDeviceStateUnspecified
};

//* MiniportQueryInformation
//
//  Called by NDIS to retrieve information about our virtual adapter.
//
NDIS_STATUS
MiniportQueryInformation(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_OID Oid,
    IN PVOID InformationBuffer,
    IN ULONG InformationBufferLength,
    OUT PULONG BytesWritten,
    OUT PULONG BytesNeeded)
{
    MiniportAdapter *VA = (MiniportAdapter *) MiniportAdapterContext;
    uint GenericUint;
    ushort GenericUshort;
    void *Data;
    uint DataLength;

    //
    // Prepare to return a uint - this is the common case.
    //
    Data = &GenericUint;
    DataLength = sizeof GenericUint;

    //
    // If you change this switch, be sure to update MiniportSupportedOidArray.
    //
    switch (Oid) {
    case OID_GEN_SUPPORTED_LIST:
        Data = MiniportSupportedOidArray;
        DataLength = sizeof MiniportSupportedOidArray;
        break;

    case OID_GEN_HARDWARE_STATUS:
        GenericUint = NdisHardwareStatusReady;
        break;

    case OID_GEN_MEDIA_SUPPORTED:
    case OID_GEN_MEDIA_IN_USE:
        GenericUint = VA->Medium;
        break;

    case OID_GEN_MAXIMUM_LOOKAHEAD:
        GenericUint = MINIPORT_MAX_LOOKAHEAD;
        break;

    case OID_GEN_CURRENT_LOOKAHEAD:
        GenericUint = VA->LookAhead;
        break;

    case OID_GEN_MAXIMUM_FRAME_SIZE:
        GenericUint = VA->MediumMaxFrameLen;
        break;

    case OID_GEN_MAC_OPTIONS:
        GenericUint = NDIS_MAC_OPTION_NO_LOOPBACK;
        break;

    case OID_GEN_LINK_SPEED:
        GenericUint = VA->MediumLinkSpeed;
        break;

    case OID_GEN_TRANSMIT_BUFFER_SPACE:
    case OID_GEN_RECEIVE_BUFFER_SPACE:
    case OID_GEN_MAXIMUM_TOTAL_SIZE:
        GenericUint = VA->MediumMaxPacketLen;
        break;

    case OID_GEN_TRANSMIT_BLOCK_SIZE:
    case OID_GEN_RECEIVE_BLOCK_SIZE:
        GenericUint = 1;
        break;

    case OID_GEN_VENDOR_ID:
        Data = MiniportVendorId;
        DataLength = sizeof MiniportVendorId;
        break;

    case OID_GEN_VENDOR_DESCRIPTION:
        Data = MiniportVendorDescription;
        DataLength = sizeof MiniportVendorDescription;
        break;

    case OID_GEN_CURRENT_PACKET_FILTER:
        GenericUint = VA->PacketFilter;
        break;

    case OID_GEN_DRIVER_VERSION:
        GenericUshort = (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION;
        Data = &GenericUshort;
        DataLength = sizeof GenericUshort;
        break;

    case OID_GEN_MEDIA_CONNECT_STATUS:
        if (VA->PhysicalAdapters != NULL)
            GenericUint = NdisMediaStateConnected;
        else
            GenericUint = NdisMediaStateDisconnected;
        break;

    case OID_GEN_MAXIMUM_SEND_PACKETS:
        GenericUint = MAX_RECV_QUEUE_SIZE;
        break;

    case OID_802_3_PERMANENT_ADDRESS:
    case OID_802_3_CURRENT_ADDRESS:
        Data = VA->Address;
        DataLength = sizeof VA->Address;
        break;

    case OID_802_3_MAXIMUM_LIST_SIZE:
        GenericUint = MINIPORT_MAX_MULTICAST_ADDRESS;
        break;

    case OID_802_3_RCV_ERROR_ALIGNMENT:
    case OID_802_3_XMIT_ONE_COLLISION:
    case OID_802_3_XMIT_MORE_COLLISIONS:
        GenericUint = 0;
        break;

    case OID_PNP_CAPABILITIES:
        Data = &MiniportPnpCapabilities;
        DataLength = sizeof MiniportPnpCapabilities;
        break;

    case OID_PNP_QUERY_POWER:
        DataLength = 0;
        break;

    default:
        KdPrint(("VRR!MiniportQueryInformation(VA %p OID %x)\n", VA, Oid));

        //
        // The following OIDs are called in practice,
        // but we do not support them.
        //
    case OID_GEN_VENDOR_DRIVER_VERSION:
    case OID_GEN_SUPPORTED_GUIDS:
    case OID_GEN_PHYSICAL_MEDIUM:
    case OID_GEN_MEDIA_CAPABILITIES:
    case OID_FFP_SUPPORT:
    case OID_TCP_TASK_OFFLOAD:
    case 0xff54554e: // OID_CUSTOM_TUNMP_INSTANCE_ID
        return NDIS_STATUS_NOT_SUPPORTED;
    }

    *BytesNeeded = DataLength;
    if (DataLength > InformationBufferLength)
        return NDIS_STATUS_BUFFER_TOO_SHORT;

    RtlCopyMemory(InformationBuffer, Data, DataLength);
    *BytesWritten = DataLength;
    return NDIS_STATUS_SUCCESS;
}

//* MiniportSetInformation
//
//  Called by NDIS to specify information for our virtual adapter.
//
NDIS_STATUS
MiniportSetInformation(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_OID Oid,
    IN PVOID InformationBuffer,
    IN ULONG InformationBufferLength,
    OUT PULONG BytesRead,
    OUT PULONG BytesNeeded)
{
    MiniportAdapter *VA = (MiniportAdapter *) MiniportAdapterContext;

    switch (Oid) {
    case OID_GEN_CURRENT_LOOKAHEAD: {
        uint LookAhead;

        if (InformationBufferLength != sizeof LookAhead) {
            *BytesNeeded = sizeof LookAhead;
            return NDIS_STATUS_INVALID_LENGTH;
        }

        LookAhead = * (uint UNALIGNED *) InformationBuffer;
        *BytesRead = sizeof LookAhead;

        if (LookAhead > MINIPORT_MAX_LOOKAHEAD)
            return NDIS_STATUS_INVALID_DATA;

        if (LookAhead > VA->LookAhead)
            VA->LookAhead = LookAhead;

        return NDIS_STATUS_SUCCESS;
    }

    case OID_PNP_SET_POWER: {
        NDIS_DEVICE_POWER_STATE PowerState;

        if (InformationBufferLength != sizeof PowerState) {
            *BytesNeeded = sizeof PowerState;
            return NDIS_STATUS_INVALID_LENGTH;
        }

        PowerState = * (NDIS_DEVICE_POWER_STATE UNALIGNED *) InformationBuffer;
        *BytesRead = sizeof PowerState;

        KdPrint(("VRR!MiniportSetInformation(VA %p SetPower %x)\n",
                 VA, PowerState));

        //
        // Should we pend until any outstanding operations are completed,
        // when transitioning to a sleep state?
        //

        if (PowerState == NdisDeviceStateD0) {
            //
            // We are waking up after being asleep.
            // The environment has likely changed.
            // The neighbor cache does not need to be flushed.
            //
        }

        return NDIS_STATUS_SUCCESS;
    }

    case OID_802_3_MULTICAST_LIST:
    case OID_GEN_CURRENT_PACKET_FILTER:
        *BytesRead = InformationBufferLength;
        return NDIS_STATUS_SUCCESS;

    default:
        KdPrint(("VRR!MiniportSetInformation(VA %p OID %x)\n", VA, Oid));

        //
        // The following OIDs are called in practice,
        // but we do not support them.
        //
    case OID_GEN_TRANSPORT_HEADER_OFFSET:
    case OID_GEN_NETWORK_LAYER_ADDRESSES:
    case OID_PNP_ADD_WAKE_UP_PATTERN:
    case OID_PNP_REMOVE_WAKE_UP_PATTERN:
        return NDIS_STATUS_NOT_SUPPORTED;
    }
}


//* MiniportControlSendComplete
//
//  Completes the transmission of a Source-Routed control packet,
//  such as a Route Request, Route Reply or Route Error.
//
static void
MiniportControlSendComplete(
    MiniportAdapter *VA,
    SRPacket *srp,
    NDIS_STATUS Status)
{
    UNREFERENCED_PARAMETER(VA);
    UNREFERENCED_PARAMETER(Status);

    SRPacketFree(srp);
}



//* MiniportForwardCleanup
//
//  Cleans up the forwarding queue.
//
static void
MiniportForwardCleanup(MiniportAdapter *VA)
{
    SRPacket *SRP;

    while ((SRP = VA->ForwardList) != NULL) {
        VA->ForwardList = SRP->Next;

        (*SRP->TransmitComplete)(VA, SRP, NDIS_STATUS_FAILURE);
    }
}




//* MiniportSendComplete
//
//  Called when a MiniportSendPacket operation has finished
//  and the packet must be returned to NDIS.

⌨️ 快捷键说明

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