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

📄 read.c

📁 网卡驱动相关实例 这是和网卡NT KMD驱动程序有关的一些资料和例子。主要是以下三方面内容: 3.1 article 一些有用的文档 3.2 Canberra 网络诊听工具Ethern
💻 C
字号:
/*++

Copyright (c) 1990  Microsoft Corporation

Module Name:

    packet.c

Abstract:


Author:


Environment:

    Kernel mode only.

Notes:


Future:



Revision History:

--*/

#include "stdarg.h"
#include "ntddk.h"
#include "ntiologc.h"
#include "ndis.h"

#include "debug.h"
#include "packet.h"



NTSTATUS
PacketRead(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the dispatch routine for create/open and close requests.
    These requests complete successfully.

Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    Status is returned.

--*/

{
    POPEN_INSTANCE      Open;
    PIO_STACK_LOCATION  IrpSp;
    PNDIS_PACKET        pPacket;
    PMDL                pMdl;
    NDIS_STATUS         Status;

    IF_LOUD(DbgPrint("Packet: Read\n");)

    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    Open=IrpSp->FileObject->FsContext;

    //
    //  See if the buffer is atleast big enough to hold the
    //  ethernet header
    //
    if (IrpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) {

        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        return STATUS_UNSUCCESSFUL;
    }

    //
    //  Allocate an MDL to map the portion of the buffer following the
    //  header
    //
    pMdl=IoAllocateMdl(
              MmGetMdlVirtualAddress(Irp->MdlAddress),
              MmGetMdlByteCount(Irp->MdlAddress),
              FALSE,
              FALSE,
              NULL
              );


    if (pMdl == NULL) {
        IF_LOUD(DbgPrint("Packet: Read-Failed to allocate Mdl\n");)
        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        return STATUS_UNSUCCESSFUL;
    }

    //
    //  Build the mdl to point to the the portion of the buffer followin
    //  the header
    //
    IoBuildPartialMdl(
        Irp->MdlAddress,
        pMdl,
        ((PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress))+ETHERNET_HEADER_LENGTH,
        0
        );

    //
    //  Clear the next link in the new MDL
    //
    pMdl->Next=NULL;

    //
    //  Try to get a packet from our list of free ones
    //

    NdisAllocatePacket(
        &Status,
        &pPacket,
        Open->PacketPool
        );

    if (Status != NDIS_STATUS_SUCCESS) {
        IF_LOUD(DbgPrint("Packet: Read- No free packets\n");)

        IoFreeMdl(pMdl);
        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        return STATUS_UNSUCCESSFUL;
    }

    //
    //  Get a pointer to the packet itself
    //

    RESERVED(pPacket)->Irp=Irp;
    RESERVED(pPacket)->pMdl=pMdl;

    IoMarkIrpPending(Irp);
    Irp->IoStatus.Status = STATUS_PENDING;


    //
    //  Attach our new MDL to the packet
    //
    NdisChainBufferAtFront(pPacket,pMdl);

    //
    //  Put this packet in a list of pending reads.
    //  The receive indication handler will attemp to remove packets
    //  from this list for use in transfer data calls
    //
    ExInterlockedInsertTailList(
        &Open->RcvList,
        &RESERVED(pPacket)->ListElement,
        &Open->RcvQSpinLock);




    return(STATUS_PENDING);

}




NDIS_STATUS
PacketReceiveIndicate (
    IN NDIS_HANDLE ProtocolBindingContext,
    IN NDIS_HANDLE MacReceiveContext,
    IN PVOID       HeaderBuffer,
    IN UINT        HeaderBufferSize,
    IN PVOID       LookAheadBuffer,
    IN UINT        LookaheadBufferSize,
    IN UINT        PacketSize
    )

{
    POPEN_INSTANCE      Open;
    PIO_STACK_LOCATION  IrpSp;
    PIRP                Irp;
    PLIST_ENTRY         PacketListEntry;
    PNDIS_PACKET        pPacket;
    ULONG               SizeToTransfer;
    NDIS_STATUS         Status;
    UINT                BytesTransfered;
    ULONG               BufferLength;

    PPACKET_RESERVED    Reserved;

    IF_LOUD(DbgPrint("Packet: ReceiveIndicate\n");)

    Open= (POPEN_INSTANCE)ProtocolBindingContext;

    if (HeaderBufferSize > ETHERNET_HEADER_LENGTH) {

        return NDIS_STATUS_SUCCESS;
    }

    //
    //  See if there are any pending read that we can satisfy
    //
    PacketListEntry=ExInterlockedRemoveHeadList(
                        &Open->RcvList,
                        &Open->RcvQSpinLock
                        );

    if (PacketListEntry == NULL) {

        return NDIS_STATUS_SUCCESS;
    }


    Reserved=CONTAINING_RECORD(PacketListEntry,PACKET_RESERVED,ListElement);
    pPacket=CONTAINING_RECORD(Reserved,NDIS_PACKET,ProtocolReserved);

    Irp=RESERVED(pPacket)->Irp;
    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    //
    //  This is the length of our partial MDL
    //
    BufferLength=IrpSp->Parameters.Read.Length-ETHERNET_HEADER_LENGTH;

    //
    //  Find out how much to transfer
    //
    SizeToTransfer = (PacketSize < BufferLength) ?
                       PacketSize : BufferLength;

    //
    //  copy the ethernet header into the actual readbuffer
    //
    NdisMoveMappedMemory(
        MmGetSystemAddressForMdl(Irp->MdlAddress),
        HeaderBuffer,
        HeaderBufferSize
        );

    //
    //  Call the Mac to transfer the packet
    //

    NdisTransferData(
        &Status,
        Open->AdapterHandle,
        MacReceiveContext,
        0,
        SizeToTransfer,
        pPacket,
        &BytesTransfered);

    if (Status != NDIS_STATUS_PENDING) {

        //
        //  If it didn't pend, call the completeion routine now
        //
        PacketTransferDataComplete(
            Open,
            pPacket,
            Status,
            BytesTransfered
            );


    }



    return NDIS_STATUS_SUCCESS;

}


VOID
PacketTransferDataComplete (
    IN NDIS_HANDLE   ProtocolBindingContext,
    IN PNDIS_PACKET  pPacket,
    IN NDIS_STATUS   Status,
    IN UINT          BytesTransfered
    )

{
    PIO_STACK_LOCATION   IrpSp;
    POPEN_INSTANCE       Open;
    PIRP                 Irp;
    PMDL                 pMdl;

    IF_LOUD(DbgPrint("Packet: TransferDataComplete\n");)

    Open= (POPEN_INSTANCE)ProtocolBindingContext;

    Irp=RESERVED(pPacket)->Irp;

    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    pMdl=RESERVED(pPacket)->pMdl;

    //
    //  Free the MDL that we allocated
    //
    IoFreeMdl(pMdl);

    //
    //  recylcle the packet
    //
    NdisReinitializePacket(pPacket);

    //
    //  Put the packet on the free queue
    //
    NdisFreePacket(pPacket);

    Irp->IoStatus.Status = Status;
    Irp->IoStatus.Information = BytesTransfered+ETHERNET_HEADER_LENGTH;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);


    return;


}









VOID
PacketReceiveComplete(
    IN NDIS_HANDLE  ProtocolBindingContext
    )

{

    return;

}

⌨️ 快捷键说明

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