📄 init.c
字号:
//
// Allocate a buffer pool for recv buffers.
//
NdisAllocateBufferPool(
&Status,
&Adapter->RecvBufferPoolHandle,
NIC_MAX_BUSY_RECVS);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(MP_ERROR, ("NdisAllocateBufferPool for recv buffer failed\n"));
break;
}
//
// Allocate packet pool for receive indications
//
NdisAllocatePacketPool(
&Status,
&Adapter->RecvPacketPoolHandle,
NIC_MAX_BUSY_RECVS,
PROTOCOL_RESERVED_SIZE_IN_PACKET);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(MP_ERROR, ("NdisAllocatePacketPool failed\n"));
break;
}
//
// Divide the RCBMem blob into RCBs and create a buffer
// descriptor for the Data portion of the RCBs.
//
for(index=0; index < NIC_MAX_BUSY_RECVS; index++)
{
PRCB pRCB = (PRCB) pRCBMem;
//
// Create a buffer descriptor for the Data portion of the RCBs.
// Buffer descriptors are nothing but MDLs on NT systems.
//
NdisAllocateBuffer(
&Status,
&Buffer,
Adapter->RecvBufferPoolHandle,
(PVOID)&pRCB->Data[0],
NIC_BUFFER_SIZE);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(MP_ERROR, ("NdisAllocateBuffer for Recv failed\n"));
break;
}
//
// Initialize the RCB structure.
//
pRCB->Buffer = Buffer;
pRCB->pData = (PUCHAR) &pRCB->Data[0];
pRCB->Adapter = Adapter;
//
// Preallocate all the IRPs required. Do not charge quota
// to the current process for this IRP.
//
ASSERT(Adapter->TargetDeviceObject);
if(!Adapter->TargetDeviceObject) {
Status = NDIS_STATUS_FAILURE;
break;
}
pRCB->Irp = IoAllocateIrp(Adapter->TargetDeviceObject->StackSize,
FALSE );
if (NULL == pRCB->Irp) {
Status = NDIS_STATUS_RESOURCES;
break;
}
pRCB->IrpLock = IRPLOCK_COMPLETED;
//
// Initialize receive packets.
// Allocate a packet descriptor for receive packets
// from a preallocated pool.
//
NdisAllocatePacket(
&Status,
&Packet,
Adapter->RecvPacketPoolHandle);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(MP_ERROR, ("NdisAllocatePacket failed\n"));
break;
}
pRCB->Packet = Packet;
NDIS_SET_PACKET_HEADER_SIZE(Packet, ETH_HEADER_SIZE);
NdisInterlockedInsertTailList(
&Adapter->RecvFreeList,
&pRCB->List,
&Adapter->RecvLock);
pRCBMem = pRCBMem + sizeof(RCB);
}
}while(FALSE);
DEBUGP(MP_TRACE, ("--> NICAllocRecvResources %x\n", Status));
return Status;
}
VOID
NICFreeRecvResources(
PMP_ADAPTER Adapter)
/*++
Routine Description:
Free resources allocated for receive operation
Arguments:
Adapter - Pointer to our adapter
Should be called at IRQL = PASSIVE_LEVEL.
Return Value:
--*/
{
NDIS_STATUS Status;
PRCB pRCB;
DEBUGP(MP_TRACE, ("--> NICFreeRecvResources\n"));
PAGED_CODE();
//
// Free all the resources we allocated for receive.
//
if(!MP_TEST_FLAG(Adapter, fMP_RECV_SIDE_RESOURCE_ALLOCATED)){
return;
}
while(!IsListEmpty(&Adapter->RecvFreeList))
{
pRCB = (PRCB) NdisInterlockedRemoveHeadList(
&Adapter->RecvFreeList,
&Adapter->RecvLock);
if(!pRCB){
break;
}
if(pRCB->Buffer){
NdisFreeBuffer(pRCB->Buffer);
}
if(pRCB->Packet) {
NdisFreePacket(pRCB->Packet);
}
if(pRCB->Irp){
IoFreeIrp(pRCB->Irp);
}
}
if(Adapter->RecvPacketPoolHandle)
{
NdisFreePacketPool(Adapter->RecvPacketPoolHandle);
Adapter->RecvPacketPoolHandle = NULL;
}
if(Adapter->RecvBufferPoolHandle)
{
NdisFreeBufferPool(Adapter->RecvBufferPoolHandle);
Adapter->RecvBufferPoolHandle = NULL;
}
if(Adapter->RCBMem)
{
NdisFreeMemory(Adapter->RCBMem, sizeof(RCB) * NIC_MAX_BUSY_RECVS, 0);
}
ASSERT(IsListEmpty(&Adapter->RecvFreeList));
ASSERT(IsListEmpty(&Adapter->RecvBusyList));
NdisFreeSpinLock(&Adapter->RecvLock);
MP_CLEAR_FLAG(Adapter, fMP_RECV_SIDE_RESOURCE_ALLOCATED);
return;
}
VOID
NICAttachAdapter(
PMP_ADAPTER Adapter)
/*++
Routine Description:
Attach this adapter to the global list of adapters controlled by this
driver.
Arguments:
Adapter - Pointer to our adapter
Should be called at IRQL = PASSIVE_LEVEL.
Return Value:
--*/
{
DEBUGP(MP_TRACE, ("--> NICAttachAdapter\n"));
NdisInterlockedInsertTailList(
&GlobalData.AdapterList,
&Adapter->List,
&GlobalData.Lock);
DEBUGP(MP_TRACE, ("<-- NICAttachAdapter\n"));
}
VOID NICDetachAdapter(
PMP_ADAPTER Adapter)
/*++
Routine Description:
Detach this adapter from the global list of adapters controlled by this
driver.
Arguments:
Adapter - Pointer to our adapter
Should be called at IRQL = PASSIVE_LEVEL.
Return Value:
--*/
{
DEBUGP(MP_TRACE, ("--> NICDetachAdapter\n"));
NdisAcquireSpinLock(&GlobalData.Lock);
RemoveEntryList(&Adapter->List);
NdisReleaseSpinLock(&GlobalData.Lock);
DEBUGP(MP_TRACE, ("<-- NICDetachAdapter\n"));
}
NDIS_STATUS
NICReadRegParameters(
PMP_ADAPTER Adapter,
NDIS_HANDLE WrapperConfigurationContext)
/*++
Routine Description:
Read device configuration parameters from the registry
Arguments:
Adapter Pointer to our adapter
WrapperConfigurationContext For use by NdisOpenConfiguration
Should be called at IRQL = PASSIVE_LEVEL.
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_FAILURE
NDIS_STATUS_RESOURCES
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_HANDLE ConfigurationHandle;
PUCHAR NetworkAddress;
UINT Length;
PUCHAR pAddr;
PNDIS_CONFIGURATION_PARAMETER pParameterValue;
NDIS_STRING strMiniportName = NDIS_STRING_CONST("MiniportName");
NDIS_STRING strFilterName = NDIS_STRING_CONST("Promiscuous");
DEBUGP(MP_TRACE, ("--> NICReadRegParameters\n"));
PAGED_CODE();
//
// Open the registry for this adapter to read advanced
// configuration parameters stored by the INF file.
//
NdisOpenConfiguration(
&Status,
&ConfigurationHandle,
WrapperConfigurationContext);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(MP_ERROR, ("NdisOpenConfiguration failed\n"));
return NDIS_STATUS_FAILURE;
}
do
{
//
// Read the Miniport Name.
// This feature is available only XP and above.
//
NdisReadConfiguration(&Status,
&pParameterValue,
ConfigurationHandle,
&strMiniportName,
NdisParameterString);
if (Status != NDIS_STATUS_SUCCESS) {
DEBUGP(MP_ERROR, ("NdisReadConfiguration for miniport name failed\n"));
} else {
Length = min(NIC_ADAPTER_NAME_SIZE-1,
pParameterValue->ParameterData.StringData.Length/sizeof(WCHAR));
RtlStringCchCopyW(Adapter->AdapterName, Length+1,
(PWCHAR)pParameterValue->ParameterData.StringData.Buffer);
}
//
// Read the Promiscuous filter value.
//
NdisReadConfiguration(&Status,
&pParameterValue,
ConfigurationHandle,
&strFilterName,
NdisParameterInteger);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(MP_ERROR, ("NdisReadConfiguration for promiscuous key failed\n"));
break;
}
Adapter->Promiscuous = (BOOLEAN)pParameterValue->ParameterData.IntegerData;
}while (FALSE);
//
// Just for testing purposes, let us make up a dummy mac address.
// In order to avoid conflicts with MAC addresses, it is usually a good
// idea to check the IEEE OUI list (e.g. at
// http://standards.ieee.org/regauth/oui/oui.txt). According to that
// list 00-50-F2 is owned by Microsoft.
//
// An important rule to "generating" MAC addresses is to have the
// "locally administered bit" set in the address, which is bit 0x02 for
// LSB-type networks like Ethernet. Also make sure to never set the
// multicast bit in any MAC address: bit 0x01 in LSB networks.
//
pAddr = (PUCHAR) &g_ulAddress;
++g_ulAddress;
Adapter->PermanentAddress[0] = 0x02;
Adapter->PermanentAddress[1] = 0x50;
Adapter->PermanentAddress[2] = 0xF2;
Adapter->PermanentAddress[3] = 0x00;
Adapter->PermanentAddress[4] = 0x01;
Adapter->PermanentAddress[5] = 0x80|pAddr[0];
ETH_COPY_NETWORK_ADDRESS(
Adapter->CurrentAddress,
Adapter->PermanentAddress);
//
// Read NetworkAddress registry value and use it as the current address
// if there is a software configurable NetworkAddress specified in
// the registry.
//
NdisReadNetworkAddress(
&Status,
&NetworkAddress,
&Length,
ConfigurationHandle);
if((Status == NDIS_STATUS_SUCCESS) && (Length == ETH_LENGTH_OF_ADDRESS))
{
if ((ETH_IS_MULTICAST(NetworkAddress)
|| ETH_IS_BROADCAST(NetworkAddress))
|| !ETH_IS_LOCALLY_ADMINISTERED (NetworkAddress))
{
DEBUGP(MP_ERROR,
("Overriding NetworkAddress is invalid - %02x-%02x-%02x-%02x-%02x-%02x\n",
NetworkAddress[0], NetworkAddress[1], NetworkAddress[2],
NetworkAddress[3], NetworkAddress[4], NetworkAddress[5]));
}
else
{
ETH_COPY_NETWORK_ADDRESS(Adapter->CurrentAddress, NetworkAddress);
}
}
DEBUGP(MP_WARNING, ("Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
Adapter->PermanentAddress[0],
Adapter->PermanentAddress[1],
Adapter->PermanentAddress[2],
Adapter->PermanentAddress[3],
Adapter->PermanentAddress[4],
Adapter->PermanentAddress[5]));
DEBUGP(MP_WARNING, ("Current Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
Adapter->CurrentAddress[0],
Adapter->CurrentAddress[1],
Adapter->CurrentAddress[2],
Adapter->CurrentAddress[3],
Adapter->CurrentAddress[4],
Adapter->CurrentAddress[5]));
Adapter->ulLinkSpeed = NIC_LINK_SPEED;
//
// Close the configuration registry
//
NdisCloseConfiguration(ConfigurationHandle);
DEBUGP(MP_TRACE, ("<-- NICReadRegParameters\n"));
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS
NICInitializeAdapter(
IN PMP_ADAPTER Adapter,
IN NDIS_HANDLE WrapperConfigurationContext
)
/*++
Routine Description:
Initialize the adapter.
Arguments:
Adapter Pointer to our adapter
WrapperConfigurationContext - Pointer to the configuration context
only valid during MiniportInitialize.
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_ADAPTER_NOT_FOUND
--*/
{
UCHAR resBuf[NIC_RESOURCE_BUF_SIZE];
PNDIS_RESOURCE_LIST resList = (PNDIS_RESOURCE_LIST)resBuf;
UINT bufSize = NIC_RESOURCE_BUF_SIZE;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NTSTATUS ntStatus;
DEBUGP(MP_TRACE, ("---> InitializeAdapter\n"));
PAGED_CODE();
//
// Get the resources assigned by the PNP manager. NDIS gets
// these resources in IRP_MN_START_DEVICE request.
//
NdisMQueryAdapterResources(
&Status,
WrapperConfigurationContext,
resList,
&bufSize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -