开发网络小端口驱动(ndis 6.0)时,需要指示当前的网卡连接状态。当初始化小端口时(MPInitializeEx),可以调用NdisMSetMiniportAttributes设置结构体NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES的MediaConnectState成员。若在运行中要通知连接状态的变化,可以调用NdisMIndicateStatusEx向上层提示。
#define DELAY_ONE_MILLISECOND -10000
void ThreadChangeStatus(PVOID StartContext)
{
PMP_ADAPTER Adapter = (PMP_ADAPTER)StartContext;
KEVENT Event;
LONG bConnected = 0;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
while (TRUE)
{
NTSTATUS Status;
LARGE_INTEGER li;
li.QuadPart = DELAY_ONE_MILLISECOND;
li.QuadPart *= 30000;
Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &li);
if (Status == STATUS_TIMEOUT)
{
NDIS_STATUS_INDICATION Status;
NDIS_LINK_STATE LinkState;
NdisZeroMemory(&Status, sizeof(Status));
NdisZeroMemory(&LinkState, sizeof(LinkState));
LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1;
LinkState.Header.Size = NDIS_SIZEOF_LINK_STATE_REVISION_1;
LinkState.MediaConnectState = bConnected % 3;
LinkState.MediaDuplexState = MediaDuplexStateFull;
LinkState.PauseFunctions = NdisPauseFunctionsUnsupported;
LinkState.RcvLinkSpeed = Adapter->ulLinkRecvSpeed;
LinkState.XmitLinkSpeed = Adapter->ulLinkSendSpeed;
Status.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;
Status.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;
Status.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1;
Status.StatusCode = NDIS_STATUS_LINK_STATE;
Status.StatusBuffer = &LinkState;
Status.StatusBufferSize = LinkState.Header.Size;
NdisMIndicateStatusEx(
Adapter->AdapterHandle,
&Status);
bConnected++;
}
}
}
有的同学可能可能担心若是上层发下OID请求查询网络连接状态,与之前Indicate的状态不一致怎么办。在NDIS 6.0及以后,OID_GEN_MEDIA_CONNECT_STATUS(_EX)码不要求实现的。wdk文档中对此有说明
Windows Vista
Supported.
NDIS 6.0 miniport drivers
Not requested.
NDIS 5.1 miniport drivers
Mandatory.
Windows XP
Supported.
NDIS 5.1 miniport drivers
Mandatory.
NDIS handles this OID for NDIS 6.0 miniport drivers.
也就是说,此OID必须在ndis5.1中实现,而ndis6.0不需要,因为NDIS库会为ndis6.0小端口驱动处理这个OID,我猜就是NDIS会保留NdisMIndicateStatusEx指示的状态。
另外在调用NdisMIndicateStatus(Ex)时,协议驱动的ProtocolStatus(Ex)会被调用,可以处理一些额外的工作。例如网卡状态有断开转换的连接状态时,网卡适配器提示正在识别...,我猜这就是tcp/ip协议在ProtocolStatus(Ex)进行的网络识别。