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

📄 packet.c

📁 VC网络程序设计实例导航配套代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                pRequest->Request.RequestType=NdisRequestSetInformation;
                pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid;

                pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=
                                                                OidData->Data;
                pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=
                                                           OidData->Length;


            } else {


                pRequest->Request.RequestType=NdisRequestQueryInformation;
                pRequest->Request.DATA.QUERY_INFORMATION.Oid= OidData->Oid;

                pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=
                                        OidData->Data;
                pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=
                                        OidData->Length;

            }

            //
            //  submit the request
            //
            NdisRequest(
                &status,
                open->AdapterHandle,
                &pRequest->Request
                );

        } else {
            //
            //  Buffer too small. The irp is completed by
            //  PacketRequestComplete routine.
            //
            status=NDIS_STATUS_FAILURE;
            pRequest->Request.DATA.SET_INFORMATION.BytesRead=0;
            pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0;

        }

        if (status != NDIS_STATUS_PENDING) {

            DebugPrint(("Calling RequestCompleteHandler\n"));

            PacketRequestComplete(
                open,
                &pRequest->Request,
                status
                );
                
        }

    }
    
    return STATUS_PENDING;

}






VOID
PacketRequestComplete(
    IN NDIS_HANDLE   ProtocolBindingContext,
    IN PNDIS_REQUEST NdisRequest,
    IN NDIS_STATUS   Status
    )
/*++

Routine Description:

    This routine is called when a protocol-initiated query or set 
    operation, begun with a call to NdisRequest that returned 
    NDIS_STATUS_PENDING, is completed. 

Arguments:


Return Value:


--*/

{
    POPEN_INSTANCE      open;
    PIO_STACK_LOCATION  irpSp;
    PIRP                irp;
    PINTERNAL_REQUEST   pRequest;
    UINT                functionCode;

    PPACKET_OID_DATA    OidData;

    DebugPrint(("RequestComplete\n"));

    open = (POPEN_INSTANCE)ProtocolBindingContext;

    pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
    irp = pRequest->Irp;

    if(Status == NDIS_STATUS_SUCCESS)
    {
        irpSp = IoGetCurrentIrpStackLocation(irp);

        functionCode=irpSp->Parameters.DeviceIoControl.IoControlCode;

        OidData = irp->AssociatedIrp.SystemBuffer;

        if (functionCode == IOCTL_PROTOCOL_SET_OID) {

            OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead;

        } else {

            if (functionCode == IOCTL_PROTOCOL_QUERY_OID) {

                OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;

            }

        }

        irp->IoStatus.Status = STATUS_SUCCESS;
        irp->IoStatus.Information=irpSp->Parameters.DeviceIoControl.InputBufferLength;
    } else {
        irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        irp->IoStatus.Information = 0;
    }
    
    ExFreePool(pRequest);
    IoCompleteRequest(irp, IO_NO_INCREMENT);
    IoDecrement(open);

    return;
}



VOID
PacketStatus(
    IN NDIS_HANDLE   ProtocolBindingContext,
    IN NDIS_STATUS   Status,
    IN PVOID         StatusBuffer,
    IN UINT          StatusBufferSize
    )
/*++

Routine Description:

    This routine is called to handle status changes indicated 
    by the underlying NDIS driver. 

Arguments:


Return Value:


--*/

{

    DebugPrint(("Indication Status: %0x, StatusBufferSize: %d\n",
                            Status, StatusBufferSize));

    return;

}



VOID
PacketStatusComplete(
    IN NDIS_HANDLE  ProtocolBindingContext
    )
/*++

Routine Description:

    This routine is called by NDIS, along with PacketStatus, 
    to report the start and end of an NDIS- or NIC-driver-
    initiated status indicate operation. 

Arguments:


Return Value:


--*/
{

    DebugPrint(("StatusIndicationComplete\n"));

    return;

}

NTSTATUS
PacketGetAdapterList(
    IN  PVOID              Buffer,
    IN  ULONG              Length,
    IN  OUT PULONG         DataLength
    )

/*++

Routine Description:

    This routine walks the adapter list and gets the symbolic
    link and NIC description and fills it in the Buffer.
    The format of the information is given below.
    
Arguments:


Return Value:

--*/
{
    ULONG               requiredLength = 0, numOfAdapters = 0;
    KIRQL               oldIrql;
    PLIST_ENTRY         thisEntry, listHead;
    POPEN_INSTANCE      open;   

    DebugPrint(("Enter PacketGetAdapterList\n"));

    KeAcquireSpinLock(&Globals.GlobalLock, &oldIrql);

    //
    // Walks the list to find out total space required for AdapterName
    // and Symbolic Link.
    //
    listHead = &Globals.AdapterList;
    
    for(thisEntry = listHead->Flink; 
        thisEntry != listHead;
        thisEntry = thisEntry->Flink)
    {
        open = CONTAINING_RECORD(thisEntry, OPEN_INSTANCE, AdapterListEntry);
        
        requiredLength += open->AdapterName.Length + sizeof(UNICODE_NULL); 
        requiredLength += open->SymbolicLink.Length + sizeof(UNICODE_NULL); 
        numOfAdapters++; 
    }

    //
    // We will return the data in the following format: 
    // numOfAdapters + One_Or_More("AdapterName\0" + "SymbolicLink\0") + UNICODE_NULL
    // So let's include the numOfAdapters and UNICODE_NULL size
    // to the total length.
    //
    
    requiredLength += sizeof(ULONG) + sizeof(UNICODE_NULL);     

    *DataLength = requiredLength;
    
    if(requiredLength > Length) {
        KeReleaseSpinLock(&Globals.GlobalLock, oldIrql);
        return STATUS_BUFFER_TOO_SMALL;
    }

    *(PULONG)Buffer = numOfAdapters;
    (PCHAR)Buffer += sizeof(ULONG);
    
    //
    // Copy the name and symbolic link of each adapter.
    //
    
    for(thisEntry = listHead->Flink; 
        thisEntry != listHead;
        thisEntry = thisEntry->Flink)
    {
        open = CONTAINING_RECORD(thisEntry, OPEN_INSTANCE, AdapterListEntry);
        
        RtlCopyMemory(Buffer, open->AdapterName.Buffer,
                            open->AdapterName.Length+sizeof(WCHAR));

        (PCHAR)Buffer += open->AdapterName.Length+sizeof(WCHAR);
        
        RtlCopyMemory(Buffer, open->SymbolicLink.Buffer,
                            open->SymbolicLink.Length+sizeof(WCHAR));

        (PCHAR)Buffer += open->SymbolicLink.Length+sizeof(WCHAR);
                            
    }
    
    *(PWCHAR)Buffer = UNICODE_NULL;
    
    KeReleaseSpinLock(&Globals.GlobalLock, oldIrql);
    
    return STATUS_SUCCESS;

}

VOID
PacketBindAdapter(
    OUT PNDIS_STATUS            Status,
    IN  NDIS_HANDLE             BindContext,
    IN  PNDIS_STRING            DeviceName,
    IN  PVOID                   SystemSpecific1,
    IN  PVOID                   SystemSpecific2
    )
/*++

Routine Description:

    Called by NDIS to bind to a miniport below.

Arguments:

    Status             - Return status of bind here.
    BindContext        - Can be passed to NdisCompleteBindAdapter 
                         if this call is pended.
    DeviceName         - Device name to bind to. This is passed to 
                            NdisOpenAdapter.
    SystemSpecific1    - Can be passed to NdisOpenProtocolConfiguration to 
                            read per-binding information
    SystemSpecific2    - Unused for NDIS 4.0.


Return Value:

    NDIS_STATUS_PENDING    if this call is pended. In this case call 
                           NdisCompleteBindAdapter to complete.
    Anything else         Completes this call synchronously

--*/
{
    NDIS_STATUS         status;
    UINT                mediumIndex;
    USHORT              length;
    POPEN_INSTANCE      open = NULL;
    UNICODE_STRING      unicodeDeviceName;
    PDEVICE_OBJECT      deviceObject = NULL;
    PWSTR               symbolicLink = NULL, deviceNameStr = NULL;
    NDIS_MEDIUM         mediumArray=NdisMedium802_3;// This sample only 
                                                    //supports Ethernet medium.
    DebugPrint(("Binding DeviceName %ws\n", DeviceName->Buffer));

    do{

        //
        // Create a deviceobject for every adapter we bind to.
        // To make a name for the deviceObject, we will append Packet_ 
        // to the name portion of the input DeviceName.
        //

        unicodeDeviceName.Buffer = NULL;
        length = DeviceName->Length + 7 * sizeof(WCHAR) + sizeof(UNICODE_NULL);

        deviceNameStr = ExAllocatePool(NonPagedPool, length);
        if (!deviceNameStr) {

            DebugPrint(("Memory allocation for create symbolic failed\n"));
            *Status = NDIS_STATUS_FAILURE;
            break;
        }
        swprintf(deviceNameStr, L"\\Device\\Packet_%ws", &DeviceName->Buffer[8]);
        RtlInitUnicodeString(&unicodeDeviceName, deviceNameStr);
        
        DebugPrint(("Exported DeviceName %ws\n", unicodeDeviceName.Buffer));

        //
        // Create the deviceobject
        //
        status = IoCreateDevice(
                    Globals.DriverObject,
                    sizeof(OPEN_INSTANCE),
                    &unicodeDeviceName,
                    FILE_DEVICE_PROTOCOL,
                    0,
                    TRUE, // only one handle to the device at a time.
                    &deviceObject
                    );
       
        if (status != STATUS_SUCCESS) {

            DebugPrint(("CreateDevice Failed: %x\n", status));
            *Status = NDIS_STATUS_FAILURE;
            break;
        }
        
        deviceObject->Flags |= DO_DIRECT_IO;

        open  =  (POPEN_INSTANCE) deviceObject->DeviceExtension;
        open->DeviceObject = deviceObject;

        //
        // Create a symbolic link.
        // We need to replace Device from \Device\Packet_{GUID} with DosDevices
        // to create a symbolic link of the form \DosDevices\Packet_{GUID}
        // There is a four character difference between these two 
        // strings.
        //
        
        length = unicodeDeviceName.Length + sizeof(UNICODE_NULL) + 
                    (4 * sizeof(WCHAR));
        
        symbolicLink = ExAllocatePool(NonPagedPool, length);
        if (!symbolicLink) {

            DebugPrint(("Memory allocation for create symbolic failed\n"));
            *Status = NDIS_STATUS_FAILURE;
            break;
        }

        swprintf(symbolicLink, L"\\DosDevices\\%ws", 
                    &unicodeDeviceName.Buffer[8]);
        
        RtlInitUnicodeString(&open->SymbolicLink,symbolicLink);

        DebugPrint(("Symbolic Link: %ws\n", open->SymbolicLink.Buffer));        
        
        status = IoCreateSymbolicLink(
                (PUNICODE_STRING) &open->SymbolicLink,
                (PUNICODE_STRING) &unicodeDeviceName
                );
        if (status != STATUS_SUCCESS) {

            DebugPrint(("Create symbolic failed\n"));
            *Status = NDIS_STATUS_FAILURE;
            break;
        }
       
        ExFreePool(unicodeDeviceName.Buffer);
        unicodeDeviceName.Buffer = NULL;

        //
        //  Allocate a packet pool for our xmit and receive packets
        //

        NdisAllocatePacketPool(
            &status,
            &open->PacketPool,
            TRANSMIT_PACKETS,
            sizeof(PACKET_RESERVED));

        if (status != NDIS_STATUS_SUCCESS) {
            DebugPrint(("Packet: Failed to allocate packet pool\n"));
            break;
        }

⌨️ 快捷键说明

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