📄 adapter.c
字号:
//
// initialize the corresponding device instance associated with the underlying
// miniport. NdisIMInitializeDeviceInstanceEx doesn't want the \Device part of
// the name so we strip that off
//
NdisInitUnicodeString( &IMDevName, &Adapter->IMDeviceName.Buffer[ 8 ] );
//
// temporarily stuff the adapter pointer into a global so we can find it when
// MiniportInitialize is called.
CurrentAdapter = Adapter;
Status = NdisIMInitializeDeviceInstance( LMDriverHandle, &IMDevName );
if ( !NT_SUCCESS( Status )) {
#if BINARY_COMPATIBLE
ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
("(%08X) ProcessLowerMPOpenAdapter: can't init IM device %s (%08X)\n",
Adapter, IMDevName.Buffer, Status));
#else
ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
("(%08X) ProcessLowerMPOpenAdapter: can't init IM device %ws (%08X)\n",
Adapter, IMDevName.Buffer, Status));
#endif
ErrorLogData[ 0 ] = IM_ERROR_CANT_INITIALIZE_IMSAMP_DEVICE;
ErrorLogData[ 1 ] = Status;
NdisWriteErrorLogEntry(Adapter->LowerMPHandle,
NDIS_ERROR_CODE_DRIVER_FAILURE,
2,
ErrorLogData);
goto ErrorExit;
}
Adapter->ShutdownMask |= SHUTDOWN_DEINIT_DEV_INSTANCE;
return;
//
// when things go wrong...
//
ErrorExit:
DerefAdapter( Adapter );
} // ProcessLowerMPOpenAdapter
VOID
LowerMPOpenAdapterComplete(
IN PADAPTER Adapter,
IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus
)
/*++
Routine Description:
Signal that the binding on the lower miniport is complete
Arguments:
see the DDK
Return Values:
None
--*/
{
NTSTATUS EventStatus;
PWSTR SecondaryName;
NDIS_HARDWARE_STATUS HWStatus;
NDIS_MEDIA_STATE MediaState = 0xFFFFFFFF;
NDIS_STRING PSDevName;
ULONG MacOptions;
ULONG ErrorLogData[2];
PWCHAR StringData[2];
PVOID DumpData;
ImDbgOut(DBG_TRACE, DBG_PROTOCOL, ("(%08X) LowerMPOpenAdapterComplete\n", Adapter));
//
// stuff the final status in the Adapter block and signal the bind handler to continue
//
Adapter->FinalStatus = Status;
NdisSetEvent( &Adapter->BlockingEvent );
} // LowerMPOpenAdapterComplete
STATIC NDIS_STATUS
AllocatePacketPool(
PADAPTER Adapter
)
/*++
Routine Description:
Allocate the packet pool. Note there are no buffers associated with this pool.
Arguments:
Adapter - pointer to adapter context block
Return Value:
None
--*/
{
NDIS_STATUS Status;
PNDIS_PACKET Packet;
ULONG ErrorLogData[2];
ULONG i;
ULONG ProtoReservedSize;
NdisInitializeSListHead( &Adapter->PacketSList );
NdisAllocateSpinLock( &Adapter->PacketSListLock );
//
// figure the amount of space we need in the protocol reserved area.
//
ProtoReservedSize = sizeof( IM_PACKET_CONTEXT );
NdisAllocatePacketPool(&Status,
&Adapter->PacketPoolHandle,
ConfigData.PacketPoolSize,
ProtoReservedSize);
if ( NT_SUCCESS( Status )) {
Adapter->ShutdownMask |= SHUTDOWN_DEALLOC_PACKET_POOL;
for ( i = 0; i < ConfigData.PacketPoolSize; ++i ) {
NdisAllocatePacket( &Status, &Packet, Adapter->PacketPoolHandle );
if ( !NT_SUCCESS( Status )) {
ErrorLogData[ 0 ] = IM_ERROR_PACKET;
ErrorLogData[ 1 ] = Status;
NdisWriteErrorLogEntry(Adapter->LowerMPHandle,
NDIS_ERROR_CODE_OUT_OF_RESOURCES,
2,
ErrorLogData);
return Status;
}
IMSetTag( IM_PACKET_CONTEXT_FROM_PACKET( Adapter, Packet ), PacketContext );
NdisInterlockedPushEntrySList(&Adapter->PacketSList,
(PSINGLE_LIST_ENTRY)Packet->ProtocolReserved,
&Adapter->PacketSListLock);
}
} else {
ErrorLogData[ 0 ] = IM_ERROR_PACKET_POOL;
ErrorLogData[ 1 ] = Status;
NdisWriteErrorLogEntry(Adapter->LowerMPHandle,
NDIS_ERROR_CODE_OUT_OF_RESOURCES,
2,
ErrorLogData);
}
return Status;
} // AllocatePacketPool
STATIC NDIS_STATUS
AllocateReceiveBufferPools(
PADAPTER Adapter
)
/*++
Routine Description:
Allocate two buffer pools, one used for header and lookahead data and the other
for residual lookahead data
Arguments:
Adapter - pointer to adapter context block
Return Value:
None
--*/
{
NDIS_STATUS Status;
ULONG i;
PVOID SysBuffer;
PNDIS_BUFFER NdisBuffer;
PIM_BUFFER_CONTEXT BufContext;
ULONG HeaderSize;
ULONG FrameSize; // doesn't include the header
NDIS_ERROR_CODE ErrorCode;
ULONG ErrorLogData[2];
//
// max amount of data w/o the MAC header
//
Status = MakeLocalNdisRequest(Adapter,
OID_GEN_MAXIMUM_FRAME_SIZE,
&FrameSize,
sizeof( FrameSize ),
NULL);
if ( !NT_SUCCESS( Status )) {
ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
("(%08X) AllocateReceiveBufferPool: Can't get frame size - Status %08X\n",
Adapter, Status));
ErrorCode = NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER;
ErrorLogData[ 0 ] = IM_ERROR_MISSING_OID;
ErrorLogData[ 1 ] = OID_GEN_MAXIMUM_FRAME_SIZE;
goto ErrorExit;
}
//
// this one includes the header
//
Status = MakeLocalNdisRequest(Adapter,
OID_GEN_MAXIMUM_TOTAL_SIZE,
&Adapter->TotalSize,
sizeof( Adapter->TotalSize ),
NULL);
if ( !NT_SUCCESS( Status )) {
ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
("(%08X) AllocateReceiveBufferPool: Can't get total size - Status %08X\n",
Adapter, Status));
ErrorCode = NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER;
ErrorLogData[ 0 ] = IM_ERROR_MISSING_OID;
ErrorLogData[ 1 ] = OID_GEN_MAXIMUM_TOTAL_SIZE;
goto ErrorExit;
}
//
// figure the real header size
//
HeaderSize = Adapter->TotalSize - FrameSize;
Status = MakeLocalNdisRequest(Adapter,
OID_GEN_MAXIMUM_LOOKAHEAD,
&Adapter->LookaheadBufferSize,
sizeof( Adapter->LookaheadBufferSize ),
NULL);
if ( !NT_SUCCESS( Status )) {
ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
("(%08X) AllocateReceiveBufferPool: Can't get lookahead size - Status %08X\n",
Adapter, Status));
ErrorCode = NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER;
ErrorLogData[ 0 ] = IM_ERROR_MISSING_OID;
ErrorLogData[ 1 ] = OID_GEN_MAXIMUM_LOOKAHEAD;
goto ErrorExit;
}
//
// figure the buffer size for the lookahead buffers, which also include
// the header. The residual buffer size is the total size, since the MP
// can indicate less than the max lookahead buffer size, we need to be
// prepared to receive the whole frame in the residual buffer. On the
// other hand, the MP can indicate more than the lookahead size, so we
// might bypass the lookahead buffer and just use a residual buffer on
// the receive.
//
Adapter->LookaheadBufferSize += HeaderSize;
//
// init the lookahead buffer pool
//
NdisInitializeSListHead( &Adapter->LookaheadSList );
NdisAllocateSpinLock( &Adapter->LookaheadSListLock );
NdisAllocateBufferPool(&Status,
&Adapter->LookaheadPoolHandle,
ConfigData.LookaheadPoolSize);
if ( !NT_SUCCESS( Status )) {
ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
ErrorLogData[ 0 ] = IM_ERROR_LOOKAHEAD_POOL;
ErrorLogData[ 1 ] = Status;
goto ErrorExit;
}
Adapter->ShutdownMask |= SHUTDOWN_DEALLOC_LOOKAHEAD_POOL;
for ( i = 0; i < ConfigData.LookaheadPoolSize; ++i ) {
IMAllocatePoolNoStructTag( SysBuffer, Adapter->LookaheadBufferSize, LookaheadBuffer );
if ( SysBuffer == NULL ) {
ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
ErrorLogData[ 0 ] = IM_ERROR_VM_LOOKAHEAD_BUFFER;
ErrorLogData[ 1 ] = (ULONG)NDIS_STATUS_RESOURCES;
goto ErrorExit;
}
NdisAllocateBuffer(&Status,
&NdisBuffer,
Adapter->LookaheadPoolHandle,
SysBuffer,
Adapter->LookaheadBufferSize);
if ( !NT_SUCCESS( Status )) {
ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
ErrorLogData[ 0 ] = IM_ERROR_LOOKAHEAD_BUFFER;
ErrorLogData[ 1 ] = Status;
goto ErrorExit;
}
//
// use the VM area to store a pointer back to the NDIS buffer and link it
// onto the S List.
//
BufContext = (PIM_BUFFER_CONTEXT)SysBuffer;
BufContext->NdisBuffer = NdisBuffer;
NdisInterlockedPushEntrySList(&Adapter->LookaheadSList,
&BufContext->SListEntry,
&Adapter->LookaheadSListLock);
}
//
// same thing for the residual buffer pool
//
NdisInitializeSListHead( &Adapter->ResidualSList );
NdisAllocateSpinLock( &Adapter->ResidualSListLock );
NdisAllocateBufferPool(&Status,
&Adapter->ResidualPoolHandle,
ConfigData.ResidualPoolSize);
if ( !NT_SUCCESS( Status )) {
ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
ErrorLogData[ 0 ] = IM_ERROR_RESIDUAL_POOL;
ErrorLogData[ 1 ] = Status;
goto ErrorExit;
}
Adapter->ShutdownMask |= SHUTDOWN_DEALLOC_RESIDUAL_POOL;
for ( i = 0; i < ConfigData.ResidualPoolSize; ++i ) {
IMAllocatePoolNoStructTag( SysBuffer, Adapter->TotalSize, ResidualBuffer );
if ( SysBuffer == NULL ) {
ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
ErrorLogData[ 0 ] = IM_ERROR_VM_RESIDUAL_BUFFER;
ErrorLogData[ 1 ] = (ULONG)NDIS_STATUS_RESOURCES;
goto ErrorExit;
}
NdisAllocateBuffer(&Status,
&NdisBuffer,
Adapter->ResidualPoolHandle,
SysBuffer,
Adapter->TotalSize);
if ( !NT_SUCCESS( Status )) {
ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
ErrorLogData[ 0 ] = IM_ERROR_RESIDUAL_BUFFER;
ErrorLogData[ 1 ] = Status;
goto ErrorExit;
}
//
// use the VM area to store a pointer back to the NDIS buffer and link it
// onto the S List.
//
BufContext = (PIM_BUFFER_CONTEXT)SysBuffer;
BufContext->NdisBuffer = NdisBuffer;
NdisInterlockedPushEntrySList(&Adapter->ResidualSList,
&BufContext->SListEntry,
&Adapter->ResidualSListLock);
}
return Status;
//
// when things go awry
//
ErrorExit:
NdisWriteErrorLogEntry( Adapter->LowerMPHandle, ErrorCode, 2, ErrorLogData );
return Status;
} // AllocateReceiveBufferPool
NDIS_STATUS
MPInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE WrapperConfigurationContext
)
/*++
Routine Description:
Imsample's device initialization routine. The list of media types is
checked to be sure it is one that we support. If so, match up the name of
the device being opened with one of the adapters to which we've bound.
Arguments:
See the DDK...
Return Values:
None
--*/
{
NDIS_HANDLE ConfigHandle;
NDIS_STATUS Status;
NDIS_STRING IMInstanceNumberKey = NDIS_STRING_CONST( "InstanceNumber" );
PNDIS_CONFIGURATION_PARAMETER ConfigParam;
ULONG IMInstanceNumber;
PLIST_ENTRY NextAdapter;
PADAPTER AdapterInList;
ULONG ErrorLogData[2];
ImDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPInitialize: Enter\n"));
//
// open registry and look at keys in the MP device instance. we need to figure out
// which instance we're initializing. The setup junk put in InstanceNumber so we
// can figure this out at this time. We pick up other instance specific info at
// this time. We have to do this locally, since we don't have a pointer to the
// adapter context struct that is associated with this initialization
//
NdisOpenConfiguration( &Status, &ConfigHandle, WrapperConfigurationContext );
if ( !NT_SUCCESS( Status )) {
return Status;
}
// Read the instance number. For example, if we are initializing ImSampMP4, then this should return
// the number stores in CurrentControlSet/Services/ImSampMP4/Parameters/InstanceNumber, which should be a 4
NdisReadConfiguration(&Status,
&ConfigParam,
ConfigHandle,
&IMInstanceNumberKey,
NdisParameterInteger);
if ( !NT_SUCCESS( Status )) {
ImDbgOut(DBG_FAILURE, DBG_MINIPORT | DBG_INIT,
("MPInitialize: Missing InstanceNumber key\n"));
ErrorLogData[ 0 ] = IM_ERROR_BAD_REGISTRY_DATA;
ErrorLogData[ 1 ] = IM_ERROR_MISSING_IMSAMP_MP_INSTANCE_KEY;
NdisWriteErrorLogEntry(MiniportAdapterHandle,
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
2,
ErrorLogData);
NdisCloseConfiguration( ConfigHandle );
return NDIS_STATUS_FAILURE;
}
IMInstanceNumber = ConfigParam->ParameterData.IntegerData;
NdisCloseConfiguration( ConfigHandle );
// We now know which adapter we are initializing (say ImSampMP4, for example)
// look through our adapter list and match based on device instance
// The adapter list is created when the protocol section opens the existing adapters below us.
NdisAcquireSpinLock( &AdapterListLock );
NextAdapter = AdapterList.Flink;
while ( NextAdapter != &AdapterList ) {
AdapterInList = CONTAINING_RECORD( NextAdapter, ADAPTER, Linkage );
if ( AdapterInList->DevInstance == IMInstanceNumber ) {
break;
}
NextAdapter = NextAdapter->Flink;
}
NdisReleaseSpinLock( &AdapterListLock );
//
// check that we really found a matching adapter
//
if ( NextAdapter == &AdapterList ) {
// This means we have an IM MP entry that does not match up with an actual adapter. This is bad.
ImDbgOut(DBG_FAILURE, DBG_MINIPORT | DBG_INIT, ("Can't find adapter for MP dev # %d\n",
IMInstanceNumber));
ErrorLogData[ 0 ] = IM_ERROR_BAD_REGISTRY_DATA;
ErrorLogData[ 1 ] = IM_ERROR_INVALID_IMSAMP_MP_INSTANCE;
NdisWriteErrorLogEntry(MiniportAdapterHandle,
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
2,
ErrorLogData);
return NDIS_STATUS_FAILURE;
}
//
// lookup our media type in the supplied media array
//
for (--MediumArraySize ; MediumArraySize > 0; ) {
if ( MediumArray[ MediumArraySize ] == AdapterInList->MediaType ) {
break;
}
if ( MediumArraySize == 0 ) {
break;
}
--MediumArraySize;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -