📄 packet.c
字号:
//
// 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 + -