📄 protocol.c
字号:
KeRaiseIrql(DISPATCH_LEVEL, &RaiseOldIrql);
{
NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's SendPackets handler\n"));
(*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext, &Packet, 1);
}
KeLowerIrql(RaiseOldIrql);
}
/* SendPackets handlers return void - they always "succeed" */
NdisStatus = NDIS_STATUS_SUCCESS;
}
else
{
/* XXX FIXME THIS IS WRONG */
/* uh oh... forgot why i thought that... */
if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE)
{
NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n"));
NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext, Packet, 0);
NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n"));
}
else
{
/* Send handlers always run at DISPATCH_LEVEL so we raise here */
KeRaiseIrql(DISPATCH_LEVEL, &RaiseOldIrql);
NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n"));
NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext, Packet, 0);
NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n"));
if( NdisStatus != NDIS_STATUS_PENDING ) {
Adapter->MiniportBusy = FALSE;
}
KeLowerIrql(RaiseOldIrql);
}
}
/* XXX why the hell do we do this? */
NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n"));
KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &SpinOldIrql);
{
if (Adapter->WorkQueueHead)
{
KeInsertQueueDpc(&Adapter->NdisMiniportBlock.DeferredDpc, NULL, NULL);
NDIS_DbgPrint(MAX_TRACE, ("MiniportDpc queued; returning NDIS_STATUS_SUCCESS\n"));
}
}
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql);
NDIS_DbgPrint(MAX_TRACE, ("returning 0x%x\n", NdisStatus));
return NdisStatus;
}
VOID NTAPI
ProSendPackets(
IN NDIS_HANDLE NdisBindingHandle,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets)
{
UNIMPLEMENTED
}
NDIS_STATUS NTAPI
ProTransferData(
IN NDIS_HANDLE MacBindingHandle,
IN NDIS_HANDLE MacReceiveContext,
IN UINT ByteOffset,
IN UINT BytesToTransfer,
IN OUT PNDIS_PACKET Packet,
OUT PUINT BytesTransferred)
/*
* FUNCTION: Forwards a request to copy received data into a protocol-supplied packet
* ARGUMENTS:
* MacBindingHandle = Adapter binding handle
* MacReceiveContext = MAC receive context
* ByteOffset = Offset in packet to place data
* BytesToTransfer = Number of bytes to copy into packet
* Packet = Pointer to NDIS packet descriptor
* BytesTransferred = Address of buffer to place number of bytes copied
*/
{
PADAPTER_BINDING AdapterBinding = GET_ADAPTER_BINDING(MacBindingHandle);
PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
/* FIXME: Interrupts must be disabled for adapter */
/* XXX sd - why is that true? */
if (Packet == Adapter->NdisMiniportBlock.IndicatedPacket[KeGetCurrentProcessorNumber()]) {
NDIS_DbgPrint(MAX_TRACE, ("LoopPacket\n"));
/* NDIS is responsible for looping this packet */
NdisCopyFromPacketToPacket(Packet,
ByteOffset,
BytesToTransfer,
Adapter->NdisMiniportBlock.IndicatedPacket[KeGetCurrentProcessorNumber()],
0,
BytesTransferred);
return NDIS_STATUS_SUCCESS;
}
return (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.TransferDataHandler)(
Packet,
BytesTransferred,
Adapter->NdisMiniportBlock.MiniportAdapterContext,
MacReceiveContext,
ByteOffset,
BytesToTransfer);
}
/*
* @implemented
*/
VOID
EXPORT
NdisCloseAdapter(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisBindingHandle)
/*
* FUNCTION: Closes an adapter opened with NdisOpenAdapter
* ARGUMENTS:
* Status = Address of buffer for status information
* NdisBindingHandle = Handle returned by NdisOpenAdapter
*/
{
KIRQL OldIrql;
PADAPTER_BINDING AdapterBinding = GET_ADAPTER_BINDING(NdisBindingHandle);
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
/* Remove from protocol's bound adapters list */
KeAcquireSpinLock(&AdapterBinding->ProtocolBinding->Lock, &OldIrql);
RemoveEntryList(&AdapterBinding->ProtocolListEntry);
KeReleaseSpinLock(&AdapterBinding->ProtocolBinding->Lock, OldIrql);
/* Remove protocol from adapter's bound protocols list */
NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n"));
KeAcquireSpinLock(&AdapterBinding->Adapter->NdisMiniportBlock.Lock, &OldIrql);
RemoveEntryList(&AdapterBinding->AdapterListEntry);
KeReleaseSpinLock(&AdapterBinding->Adapter->NdisMiniportBlock.Lock, OldIrql);
ExFreePool(AdapterBinding);
*Status = NDIS_STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
EXPORT
NdisDeregisterProtocol(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisProtocolHandle)
/*
* FUNCTION: Releases the resources allocated by NdisRegisterProtocol
* ARGUMENTS:
* Status = Address of buffer for status information
* NdisProtocolHandle = Handle returned by NdisRegisterProtocol
*/
{
KIRQL OldIrql;
PPROTOCOL_BINDING Protocol = GET_PROTOCOL_BINDING(NdisProtocolHandle);
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
/* FIXME: Make sure no adapter bindings exist */
/* Remove protocol from global list */
KeAcquireSpinLock(&ProtocolListLock, &OldIrql);
RemoveEntryList(&Protocol->ListEntry);
KeReleaseSpinLock(&ProtocolListLock, OldIrql);
ExFreePool(Protocol);
*Status = NDIS_STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
EXPORT
NdisOpenAdapter(
OUT PNDIS_STATUS Status,
OUT PNDIS_STATUS OpenErrorStatus,
OUT PNDIS_HANDLE NdisBindingHandle,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE NdisProtocolHandle,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_STRING AdapterName,
IN UINT OpenOptions,
IN PSTRING AddressingInformation OPTIONAL)
/*
* FUNCTION: Opens an adapter for communication
* ARGUMENTS:
* Status = Address of buffer for status information
* OpenErrorStatus = Address of buffer for secondary error code
* NdisBindingHandle = Address of buffer for adapter binding handle
* SelectedMediumIndex = Address of buffer for selected medium
* MediumArray = Pointer to an array of NDIS_MEDIUMs called can support
* MediumArraySize = Number of elements in MediumArray
* NdisProtocolHandle = Handle returned by NdisRegisterProtocol
* ProtocolBindingContext = Pointer to caller suplied context area
* AdapterName = Pointer to buffer with name of adapter
* OpenOptions = Bitmask with flags passed to next-lower driver
* AddressingInformation = Optional pointer to buffer with NIC specific information
*/
{
UINT i;
BOOLEAN Found;
PLOGICAL_ADAPTER Adapter;
PADAPTER_BINDING AdapterBinding;
PPROTOCOL_BINDING Protocol = GET_PROTOCOL_BINDING(NdisProtocolHandle);
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
if(!NdisProtocolHandle)
{
NDIS_DbgPrint(MAX_TRACE, ("NdisProtocolHandle is NULL\n"));
*OpenErrorStatus = *Status = NDIS_STATUS_FAILURE;
return;
}
Adapter = MiniLocateDevice(AdapterName);
if (!Adapter)
{
NDIS_DbgPrint(MIN_TRACE, ("Adapter not found.\n"));
*Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
return;
}
/* Find the media type in the list provided by the protocol driver */
Found = FALSE;
for (i = 0; i < MediumArraySize; i++)
{
if (Adapter->NdisMiniportBlock.MediaType == MediumArray[i])
{
*SelectedMediumIndex = i;
Found = TRUE;
break;
}
}
if (!Found)
{
NDIS_DbgPrint(MIN_TRACE, ("Medium is not supported.\n"));
*Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
return;
}
/* Now that we have confirmed that the adapter can be opened, create a binding */
AdapterBinding = ExAllocatePool(NonPagedPool, sizeof(ADAPTER_BINDING));
if (!AdapterBinding)
{
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
*Status = NDIS_STATUS_RESOURCES;
return;
}
RtlZeroMemory(AdapterBinding, sizeof(ADAPTER_BINDING));
AdapterBinding->ProtocolBinding = Protocol;
AdapterBinding->Adapter = Adapter;
AdapterBinding->NdisOpenBlock.ProtocolBindingContext = ProtocolBindingContext;
/* Set fields required by some NDIS macros */
AdapterBinding->NdisOpenBlock.BindingHandle = (NDIS_HANDLE)AdapterBinding;
/* Set handlers (some NDIS macros require these) */
AdapterBinding->NdisOpenBlock.RequestHandler = ProRequest;
AdapterBinding->NdisOpenBlock.ResetHandler = ProReset;
AdapterBinding->NdisOpenBlock.SendHandler = ProSend;
AdapterBinding->NdisOpenBlock.SendPacketsHandler = ProSendPackets;
AdapterBinding->NdisOpenBlock.TransferDataHandler = ProTransferData;
AdapterBinding->NdisOpenBlock.RequestCompleteHandler =
Protocol->Chars.RequestCompleteHandler;
#if 0
/* XXX this looks fishy */
/* OK, this really *is* fishy - it bugchecks */
/* Put on protocol's bound adapters list */
ExInterlockedInsertTailList(&Protocol->AdapterListHead, &AdapterBinding->ProtocolListEntry, &Protocol->Lock);
#endif
/* XXX so does this */
/* Put protocol on adapter's bound protocols list */
NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n"));
ExInterlockedInsertTailList(&Adapter->ProtocolListHead, &AdapterBinding->AdapterListEntry, &Adapter->NdisMiniportBlock.Lock);
*NdisBindingHandle = (NDIS_HANDLE)AdapterBinding;
*Status = NDIS_STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
EXPORT
NdisRegisterProtocol(
OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE NdisProtocolHandle,
IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics,
IN UINT CharacteristicsLength)
/*
* FUNCTION: Registers an NDIS driver's ProtocolXxx entry points
* ARGUMENTS:
* Status = Address of buffer for status information
* NdisProtocolHandle = Address of buffer for handle used to identify the driver
* ProtocolCharacteristics = Pointer to NDIS_PROTOCOL_CHARACTERISTICS structure
* CharacteristicsLength = Size of structure which ProtocolCharacteristics targets
* NOTES:
* - you *must* set NdisProtocolHandle before doing anything that could wind up
* getting BindAdapterHandler, as it will probably call OpenAdapter with this handle
* - the above implies that the initialization of the protocol block must be complete
* by then
* TODO:
* - break this function up - probably do a 'ndisRefreshProtocolBindings' function
* - make this thing able to handle >1 protocol
*/
{
PPROTOCOL_BINDING Protocol;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -