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

📄 packet.c

📁 VC网络程序设计实例导航配套代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        
        //
        //  Initializing the Event used for synchronizing open and close.
        //
        
        NdisInitializeEvent(&open->Event);

        //
        // List to hold irp's want to reset the adapter
        //
        InitializeListHead(&open->ResetIrpList);

        //
        // Initialize the spinlock used for synchronizing access
        // to the reset list.
        //
        KeInitializeSpinLock(&open->ResetQueueLock);
        
        //
        //  Initialize list for holding pending read requests
        //
        KeInitializeSpinLock(&open->RcvQSpinLock);
        InitializeListHead(&open->RcvList);

        //
        // Now open the adapter below and complete the initialization
        //
        
        NdisOpenAdapter(Status,
                          &status,
                          &open->AdapterHandle,
                          &mediumIndex,
                          &mediumArray,
                          sizeof(mediumArray)/sizeof(NDIS_MEDIUM),
                          Globals.NdisProtocolHandle,
                          open,
                          DeviceName,
                          0,
                          NULL);

        if(*Status == NDIS_STATUS_PENDING)
        {
              NdisWaitEvent(&open->Event, 0);
              *Status = open->Status;
        }
        if(*Status != NDIS_STATUS_SUCCESS)
        {
            DebugPrint(("Failed to openAdapter\n"));
            break;
        }
        open->IrpCount = 0;

        InterlockedExchange( (PLONG)&open->Bound, TRUE );
        NdisInitializeEvent(&open->CleanupEvent);

        //
        // Let the initial state of the event to be signalled state.
        //

        NdisSetEvent(&open->CleanupEvent);

        //
        //  Save the the friendly name of the MAC driver
        //

        NdisQueryAdapterInstanceName(&open->AdapterName, 
                                        open->AdapterHandle);
        DebugPrint(("Bound AdapterName %ws\n", open->AdapterName.Buffer));

        open->Medium = mediumArray;
        //
        // Link this instance to the global adapterlist.
        //
        
        InitializeListHead(&open->AdapterListEntry);
        
        ExInterlockedInsertTailList(&Globals.AdapterList,
                                    &open->AdapterListEntry, 
                                    &Globals.GlobalLock);

        //
        // Clear the DO_DEVICE_INITIALIZING flag. This is required
        // if you create deviceobjects outside of DriverEntry.
        // Untill you do this, application cannot send I/O request.
        // 

        deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;


    } while(FALSE);

    if (*Status != NDIS_STATUS_SUCCESS)
    {
        if (open && open->PacketPool != NULL) {
             NdisFreePacketPool(open->PacketPool);
        }
        if (deviceObject != NULL) {
            IoDeleteDevice(deviceObject);
        }
        
        if(unicodeDeviceName.Buffer)
            ExFreePool(unicodeDeviceName.Buffer);

        if(symbolicLink) {
            IoDeleteSymbolicLink(&open->SymbolicLink);
            ExFreePool(open->SymbolicLink.Buffer);
        }
    }

    DebugPrint(("Return BindAdapter :0x%x\n", *Status));
}


VOID
PacketUnbindAdapter(
    OUT PNDIS_STATUS        Status,
    IN  NDIS_HANDLE         ProtocolBindingContext,
    IN  NDIS_HANDLE         UnbindContext
    )
/*++

Routine Description:

    Called by NDIS when we are required to unbind to the adapter below.

Arguments:

    Status                    Placeholder for return status
    ProtocolBindingContext    Pointer to the adapter structure
    UnbindContext            Context for NdisUnbindComplete() if this pends

Return Value:


--*/
{
    POPEN_INSTANCE   open =(POPEN_INSTANCE)ProtocolBindingContext;
    KIRQL            oldIrql;

    DebugPrint(("PacketUnbindAdapter :%ws\n", open->AdapterName.Buffer));

    if(open->AdapterHandle != NULL)
    {
        NdisResetEvent(&open->Event);

        //
        // Your are no longer bound to any adapter
        //

        InterlockedExchange( (PLONG) &open->Bound, FALSE );

        //
        // Cancel all the pending reads.
        // 

        PacketCancelReadIrps(open->DeviceObject);
        
        //
        // Wait for all the outstanding IRPs to complete
        //
        DebugPrint(("Waiting on CleanupEvent\n"));

        NdisWaitEvent(&open->CleanupEvent, 0);

        NdisCloseAdapter(Status, open->AdapterHandle);

        //
        // Wait for it to complete
        //
        if(*Status == NDIS_STATUS_PENDING)
        {
            NdisWaitEvent(&open->Event, 0);
            *Status = open->Status;
        }
        else
        {
            *Status = NDIS_STATUS_FAILURE;
            ASSERT(0);
        }

        //
        // Delink this instance from the global adapter list.
        //
        
        KeAcquireSpinLock(&Globals.GlobalLock, &oldIrql);
        RemoveEntryList(&open->AdapterListEntry);
        KeReleaseSpinLock(&Globals.GlobalLock, oldIrql);
        
        NdisFreePacketPool(open->PacketPool);
        
        NdisFreeMemory(open->AdapterName.Buffer, open->AdapterName.Length, 0);

        IoDeleteSymbolicLink(&open->SymbolicLink);
        ExFreePool(open->SymbolicLink.Buffer);
        
        IoDeleteDevice(open->DeviceObject);
    }

    DebugPrint(("Exit PacketUnbindAdapter\n"));
}

VOID
PacketOpenAdapterComplete(
    IN NDIS_HANDLE  ProtocolBindingContext,
    IN NDIS_STATUS  Status,
    IN NDIS_STATUS  OpenErrorStatus
    )
/*++

Routine Description:

    Completion routine for NdisOpenAdapter issued from within the 
    PacketBindAdapter. Simply unblock the caller.

Arguments:

    ProtocolBindingContext    Pointer to the adapter
    Status                    Status of the NdisOpenAdapter call
    OpenErrorStatus            Secondary status(ignored by us).

Return Value:

    None

--*/
{

    POPEN_INSTANCE    open = ProtocolBindingContext;

    DebugPrint(("Packet: OpenAdapterComplete\n"));

    open->Status = Status;
    NdisSetEvent(&open->Event);
    return;

}

VOID
PacketCloseAdapterComplete(
    IN NDIS_HANDLE  ProtocolBindingContext,
    IN NDIS_STATUS  Status
    )
/*++

Routine Description:

    Completion routine for NdisCloseAdapter issued from within the 
    PacketUnBindAdapter. Simply unblock the caller.

Arguments:

    ProtocolBindingContext    Pointer to the adapter
    Status                    Status of the NdisOpenAdapter call

Return Value:

    None

--*/

{
    POPEN_INSTANCE    open = ProtocolBindingContext;

    DebugPrint(("CloseAdapterComplete\n"));

    open->Status = Status;
    NdisSetEvent(&open->Event);
    
    return;

}


NDIS_STATUS
PacketPNPHandler(
    IN    NDIS_HANDLE        ProtocolBindingContext,
    IN    PNET_PNP_EVENT     NetPnPEvent
    )

/*++
Routine Description:

    NDIS calls ProtocolPnPEvent to indicate a Plug and Play 
    event or a Power Management event.  
    All PNP Related OIDS(requests) are routed to this function. 

Arguments:

    ProtocolBindingContext    Pointer to our adapter structure.
    NetPnPEvent               Pointer to a Net_PnP_Event

Return Value:

    NDIS_STATUS_SUCCESS: as we do not do much here

--*/
{
    POPEN_INSTANCE              open  =(POPEN_INSTANCE)ProtocolBindingContext;
    NDIS_STATUS                 Status  = NDIS_STATUS_SUCCESS;
    PNET_DEVICE_POWER_STATE     powerState;

    DebugPrint(("PacketPNPHandler\n"));
    
    powerState = (PNET_DEVICE_POWER_STATE)NetPnPEvent->Buffer;

    //
    // This will happen when all entities in the system need to be notified
    //
    //if(open == NULL)
    //{
    //  return Status;
    //}

    switch(NetPnPEvent->NetEvent)
    {
         case  NetEventSetPower :
            DebugPrint(("NetEventSetPower\n"));
            switch (*powerState) {
            
                case NetDeviceStateD0:
                    Status = NDIS_STATUS_SUCCESS;
                    break;

                default:
                    //
                    // We can't suspend, so we ask NDIS to Unbind us by
                    // returning this status:
                    //
                    Status = NDIS_STATUS_NOT_SUPPORTED;
                    break;
            }
            break;
         case NetEventQueryPower :
            DebugPrint(("NetEventQueryPower\n"));
            break;
            
         case NetEventQueryRemoveDevice  :
            DebugPrint(("NetEventQueryRemoveDevice \n"));
            break;

         case NetEventCancelRemoveDevice  :
            DebugPrint(("NetEventCancelRemoveDevice \n"));
            break;
            
         case NetEventReconfigure :
            //
            // The protocol should always succeed this event 
            // by returning NDIS_STATUS_SUCCESS
            //
            DebugPrint(("NetEventReconfigure\n"));
            break;

        case NetEventBindsComplete  :
            DebugPrint(("NetEventBindsComplete \n"));
            break;

        case NetEventPnPCapabilities  :
            DebugPrint(("NetEventPnPCapabilities \n"));
        case NetEventBindList:
            DebugPrint(("NetEventBindList \n"));
        default:
            Status = NDIS_STATUS_NOT_SUPPORTED;
            break;
    }

    return Status;
}


VOID
IoIncrement (
    IN  OUT POPEN_INSTANCE  Open
    )   

/*++
Routine Description:

    This routine increments the number of requests the device receives
    
Arguments:

    Open - pointer to the device extension.
    
Return Value:
--*/

{
    LONG            result;
    
    result = InterlockedIncrement(&Open->IrpCount);

    //DebugPrint(("IoIncrement %d\n", result));

    //
    // Need to clear event (when IrpCount bumps from 0 to 1) 
    //
    
    if (result == 1) {
        //
        // We need to clear the event
        //
        NdisResetEvent(&Open->CleanupEvent);
    }

    return;
}

VOID
IoDecrement (
    IN  OUT POPEN_INSTANCE  Open
    )
/*++
Routine Description:

    This routine decrements as it complete the request it receives

Arguments:

    Open - pointer to the device extension.
    
Return Value:

--*/
{
    LONG            result;
    
    result = InterlockedDecrement(&Open->IrpCount);

    //DebugPrint(("IoDecrement %d\n", result));

    if (result == 0) {

        //
        // Set the event when the count transition from 1 to 0.
        //
 
        NdisSetEvent (&Open->CleanupEvent);
    }
    return;
}



⌨️ 快捷键说明

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