📄 adapter.c
字号:
if ( MediumArraySize == 0 && MediumArray[ 0 ] != AdapterInList->MediaType ) {
return NDIS_STATUS_UNSUPPORTED_MEDIA;
}
*SelectedMediumIndex = MediumArraySize;
//
// save NDIS's handle to us
//
AdapterInList->IMNdisHandle = MiniportAdapterHandle;
//
// finish the initialization process by set our attributes
//
NdisMSetAttributesEx(MiniportAdapterHandle,
AdapterInList,
0,
NDIS_ATTRIBUTE_DESERIALIZE,
0);
// mark the adapter as running
AdapterInList->IMMPState = ADAPTER_STATE_RUNNING;
return NDIS_STATUS_SUCCESS;
} // MPInitialize
PADAPTER
FindAdapterByInstanceNumber(
#if BINARY_COMPATIBLE
CHAR InstanceNumber
#else
WCHAR InstanceNumber
#endif
)
/*++
Routine Description:
Using the instance number, find the associated adapter struct. Up the
adapter's ref count before leaving
Arguments:
InstanceNumber - pointer to unicode char of instance number
Return Value:
pointer to ADAPTER struct, otherwise NULL
--*/
{
PLIST_ENTRY NextAdapter;
PADAPTER AdapterInList;
#if BINARY_COMPATIBLE
CHAR LastChar;
#else
WCHAR LastChar;
#endif
NdisAcquireSpinLock( &AdapterListLock );
NextAdapter = AdapterList.Flink;
while ( NextAdapter != &AdapterList ) {
AdapterInList = CONTAINING_RECORD( NextAdapter, ADAPTER, Linkage );
#if BINARY_COMPATIBLE
LastChar = *(((PCHAR)AdapterInList->IMDeviceName.Buffer) +
AdapterInList->IMDeviceName.Length - 2);
#else
LastChar = AdapterInList->IMDeviceName.Buffer[ ( AdapterInList->IMDeviceName.Length /
sizeof( WCHAR )) - 1];
#endif
if ( InstanceNumber == LastChar ) {
break;
}
NextAdapter = NextAdapter->Flink;
}
if ( NextAdapter != &AdapterList ) {
NdisAcquireSpinLock( &AdapterInList->Lock );
++AdapterInList->RefCount;
ImDbgOut( DBG_TRACE, DBG_REFCNTS, ("(%08X) +Adapter:k %2d\n",
AdapterInList, AdapterInList->RefCount ));
NdisReleaseSpinLock( &AdapterInList->Lock );
} else {
AdapterInList = NULL;
}
NdisReleaseSpinLock( &AdapterListLock );
return AdapterInList;
}
PADAPTER
FindAdapterByName(
PWCHAR AdapterName
)
/*++
Routine Description:
Using the name, find the associated adapter struct. Up the
adapter's ref count before leaving
Arguments:
AdapterName - pointer to unicode string version of adapter name
Return Value:
pointer to ADAPTER struct, otherwise NULL
--*/
{
PLIST_ENTRY NextAdapter;
PADAPTER AdapterInList;
ULONG NameLength = 0;
PWCHAR pw = AdapterName;
while ( *pw++ != 0 && NameLength < 64 ) {
++NameLength;
}
NameLength *= sizeof( WCHAR );
NdisAcquireSpinLock( &AdapterListLock );
NextAdapter = AdapterList.Flink;
while ( NextAdapter != &AdapterList ) {
AdapterInList = CONTAINING_RECORD( NextAdapter, ADAPTER, Linkage );
if ( AdapterInList->IMDeviceName.Length == NameLength ) {
if ( NdisEqualMemory(AdapterInList->IMDeviceName.Buffer,
AdapterName,
AdapterInList->IMDeviceName.Length)) {
break;
}
}
NextAdapter = NextAdapter->Flink;
}
if ( NextAdapter != &AdapterList ) {
NdisAcquireSpinLock( &AdapterInList->Lock );
++AdapterInList->RefCount;
ImDbgOut( DBG_TRACE, DBG_REFCNTS, ("(%08X) +Adapter:k %2d\n",
AdapterInList, AdapterInList->RefCount ));
NdisReleaseSpinLock( &AdapterInList->Lock );
} else {
AdapterInList = NULL;
}
NdisReleaseSpinLock( &AdapterListLock );
return AdapterInList;
}
VOID
UnbindFromLowerMP(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE UnbindContext
)
/*++
Routine Description:
Called by NDIS to indicate that an adapter is going away. Release our reference
on the adapter and set the closing flag to true to prevent any further
references from being obtained.
Arguments:
See the DDK...
Return Values:
None
--*/
{
PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
NDIS_STATUS LocalStatus;
ImDbgOut(DBG_TRACE, DBG_PROTOCOL | DBG_INIT, ("(%08X) UnbindFromLowerMP\n", Adapter));
IMStructAssert( Adapter );
//
// set the adapter to closing
//
NdisAcquireSpinLock( &Adapter->Lock );
Adapter->IMMPState = ADAPTER_STATE_CLOSING;
NdisReleaseSpinLock( &Adapter->Lock );
//
// deinit the IM miniport associated with the underlying MP
//
if ( Adapter->ShutdownMask & SHUTDOWN_DEINIT_DEV_INSTANCE ) {
LocalStatus = NdisIMDeInitializeDeviceInstance( Adapter->IMNdisHandle );
IMAssert( NT_SUCCESS( LocalStatus ));
Adapter->ShutdownMask &= ~SHUTDOWN_DEINIT_DEV_INSTANCE;
}
//
// Remember the UnbindContext so we can complete the unbinding explicitly.
// Remove the reference on the adapter.
//
Adapter->BindContext = UnbindContext;
DerefAdapter( Adapter );
*Status = NDIS_STATUS_PENDING;
} // UnbindAdapter
VOID
DerefAdapter(
PADAPTER Adapter
)
/*++
Routine Description:
Decrement the ref counter associated with this structure. When it goes to
zero, close the adapter, and delete the memory associated with the struct
Arguments:
Adapter - pointer to adapter context block
Return Value:
number of references remaining associated with this structure
--*/
{
LONG RefCount;
IMStructAssert( Adapter );
NdisAcquireSpinLock( &Adapter->Lock );
if(Adapter->RefCount){
RefCount = --Adapter->RefCount;
ImDbgOut( DBG_TRACE, DBG_REFCNTS, ("(%08X) -Adapter:a %2d\n", Adapter, Adapter->RefCount ));
}
if ( RefCount == 0 ) {
CleanupAdapter( Adapter );
} else {
NdisReleaseSpinLock( &Adapter->Lock );
}
IMAssert ( RefCount >= 0 );
} // DerefAdapter
VOID
CleanupAdapter(
PADAPTER Adapter
)
/*++
Routine Description:
All refs have been removed on this struct. Free its resources.
Called with adapter lock HELD
Arguments:
Adapter - pointer to adapter context block
Return Value:
None
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NdisReleaseSpinLock( &Adapter->Lock );
//
// set the adapter to closing. we may have gotten here during init failure
// so we may not have previously set the state to closing
//
NdisAcquireSpinLock( &Adapter->Lock );
Adapter->IMMPState = ADAPTER_STATE_CLOSING;
NdisReleaseSpinLock( &Adapter->Lock );
//
// deinit the IM miniport associated with the underlying MP
//
if ( Adapter->ShutdownMask & SHUTDOWN_DEINIT_DEV_INSTANCE ) {
Status = NdisIMDeInitializeDeviceInstance( Adapter->IMNdisHandle );
IMAssert( NT_SUCCESS( Status ));
}
//
// close the adapter. remainder of processing is done in the completion
// routine
//
NdisCloseAdapter( &Status, Adapter->LowerMPHandle );
IMAssert( NT_SUCCESS( Status ));
if ( Status != NDIS_STATUS_PENDING ) {
LowerMPCloseAdapterComplete( Adapter, Status );
}
} // CleanupAdapter
VOID
LowerMPCloseAdapterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Completion routine for NdisCloseAdapter. All that should be left is to free
the pool associated with the structure
Arguments:
See the DDK...
Return Values:
None
--*/
{
PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
PSINGLE_LIST_ENTRY SListEntry;
PNDIS_PACKET Packet;
PNDIS_BUFFER NdisBuffer;
PVOID SysBuffer;
ULONG SysLength;
PIM_BUFFER_CONTEXT BufContext;
BOOLEAN TimerCancelled;
ImDbgOut(DBG_TRACE, DBG_PROTOCOL, ("(%08X) LowerMPCloseAdapterComplete\n", Adapter));
IMStructAssert( Adapter );
IMAssert( NT_SUCCESS( Status ));
//
// complete the unbinding if necessary
//
if ( Adapter->BindContext ) {
NdisCompleteUnbindAdapter( Adapter->BindContext, Status );
}
//
// acquire the main adapter list lock and remove this entry
//
NdisAcquireSpinLock( &AdapterListLock );
RemoveEntryList( &Adapter->Linkage );
NdisReleaseSpinLock( &AdapterListLock );
//
// return packet pool resources
//
while ( SListEntry = NdisInterlockedPopEntrySList(&Adapter->PacketSList,
&Adapter->PacketSListLock)) {
NdisFreePacket( CONTAINING_RECORD( SListEntry, NDIS_PACKET, ProtocolReserved ));
}
if ( Adapter->ShutdownMask & SHUTDOWN_DEALLOC_PACKET_POOL ) {
NdisFreePacketPool( Adapter->PacketPoolHandle );
}
//
// return lookahead buffer pool resources
//
while ( SListEntry = NdisInterlockedPopEntrySList(&Adapter->LookaheadSList,
&Adapter->LookaheadSListLock)) {
BufContext = (PIM_BUFFER_CONTEXT)SListEntry;
NdisAdjustBufferLength( BufContext->NdisBuffer, Adapter->LookaheadBufferSize );
NdisFreeBuffer( BufContext->NdisBuffer );
IMFreePool( BufContext );
}
if ( Adapter->ShutdownMask & SHUTDOWN_DEALLOC_LOOKAHEAD_POOL ) {
NdisFreeBufferPool( Adapter->LookaheadPoolHandle );
}
//
// same for residual buffer pool resources
//
while ( SListEntry = NdisInterlockedPopEntrySList(&Adapter->ResidualSList,
&Adapter->ResidualSListLock)) {
BufContext = (PIM_BUFFER_CONTEXT)SListEntry;
NdisAdjustBufferLength( BufContext->NdisBuffer, Adapter->TotalSize );
NdisFreeBuffer( BufContext->NdisBuffer );
IMFreePool( BufContext );
}
if ( Adapter->ShutdownMask & SHUTDOWN_DEALLOC_RESIDUAL_POOL ) {
NdisFreeBufferPool( Adapter->ResidualPoolHandle );
}
//
// free adapter lock from dispatcher DB and free mem for adapter struct
//
NdisFreeSpinLock( &Adapter->Lock );
IMFreePool( Adapter );
} // LowerMPCloseAdapterComplete
VOID
CLUnloadProtocol(
VOID
)
/*++
Routine Description:
Memphis checks to see if this defined for checked builds - sigh...
Arguments:
None
Return Value:
None
--*/
{
}
VOID
MPHalt(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
This handler is called on Memphis. It indicates that the IM MP is no more
and we should avoid calling NdisIMDeInitializeDeviceInstance...
Arguments:
See the DDK...
Return Values:
None
--*/
{
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
IMStructAssert( Adapter );
ImDbgOut(DBG_TRACE, DBG_MINIPORT, ("(%08X) MPHalt\n", Adapter));
Adapter->ShutdownMask &= ~SHUTDOWN_DEINIT_DEV_INSTANCE;
}
NDIS_STATUS
MPReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
Arguments:
See the DDK...
Return Values:
None
--*/
{
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
IMStructAssert( Adapter );
ImDbgOut(DBG_TRACE, DBG_MINIPORT, ("(%08X) MPReset\n", Adapter));
*AddressingReset = FALSE;
#if BINARY_COMPATIBLE
#if DBG
//
// linker doesn't include the routine if no one is calling it. force some code to
// be generated for it
//
{
volatile INT A = 0;
if ( A ) {
DumpAdapter( Adapter );
}
}
#endif // DBG
#endif // BINARY_COMPATIBLE
return NDIS_STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -