1 WinCE网络介绍<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
在WinCE中,网络架构和windows系统差不多。通过NDIS,WinCE系统和网卡及网络协议进行交互。NDIS提供了一个完全的网络驱动的抽象层,目前WinCE支持NDIS5.1,其中包括对RNDIS,NDISWAN,Token Ring等的支持。在WinCE中,整个网络架构体系如图:
WinSock是提供给应用层的接口,一般开发网络应用都会用Winsock接口来开发。往下就是协议层,IrDA和TCP/IP都基于NDIS层以上,通过NDIS封装层和底层的驱动进行交互。NDIS包含了网卡的驱动,就是图中的Miniport Driver。实际的网卡驱动就是指Miniport Driver,它向上为NDIS提供了Miniport相关的接口函数,向下则通过NDIS的接口来访问硬件网卡。
2 WinCE网络驱动架构
在WinCE中,开发网卡驱动就是写一个Miniport Driver,导出相应的Miniport接口函数,调用NDIS的接口访问底层硬件。驱动架构如图:
从图中清楚地看到Miniport driver所处的位置。在WinCE中支持三种类型的网络驱动:Miniport driver,Intermediate driver和Protocol driver。这里,只介绍针对硬件网卡的驱动,也就是Miniport driver。Miniport driver直接管理硬件网卡,它使用NDIS Library中的接口函数读写硬件网卡,同时对上层导出Miniport接口函数,这样上层通过该接口可以配置网卡,发送和接收网络数据包。
开发一个Miniport driver首先需要注册一个NDIS_MINIPORT_CHARACTERISTICS结构,该结构定义如下:
typedef struct _NDIS_MINIPORT_CHARACTERISTICS
{
UCHAR MajorNdisVersion;
UCHAR MinorNdisVersion;
UINT Reserved;
W_CHECK_FOR_HANG_HANDLER CheckForHangHandler;
W_DISABLE_INTERRUPT_HANDLER DisableInterruptHandler;
W_ENABLE_INTERRUPT_HANDLER EnableInterruptHandler;
W_HALT_HANDLER HaltHandler;
W_HANDLE_INTERRUPT_HANDLER HandleInterruptHandler;
W_INITIALIZE_HANDLER InitializeHandler;
W_ISR_HANDLER ISRHandler;
W_QUERY_INFORMATION_HANDLER QueryInformationHandler;
W_RECONFIGURE_HANDLER ReconfigureHandler;
W_RESET_HANDLER ResetHandler;
W_SEND_HANDLER SendHandler;
W_SET_INFORMATION_HANDLER SetInformationHandler;
W_TRANSFER_DATA_HANDLER TransferDataHandler;
W_RETURN_PACKET_HANDLER ReturnPacketHandler;
W_SEND_PACKETS_HANDLER SendPacketsHandler;
W_ALLOCATE_COMPLETE_HANDLER AllocateCompleteHandler;
W_CANCEL_SEND_PACKETS_HANDLER CancelSendPacketsHandler;
W_MINIPORT_SHUTDOWN_HANDLER AdapterShutdownHandler;
} NDIS_MINIPORT_CHARACTERISTICS, *PNDIS_MINIPORT_CHARACTERISTICS;
上面的结构中定义了NDIS的版本号,以及要导出Minioprt的相应的接口函数的函数指针。该结构会在DriverEntry函数中被设置,并进行注册。下面将对导出的Miniport接口函数进行介绍。
3 Miniport相关接口
3.1 NDIS_STATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
初始化一个Miniport Driver,该函数会被第一个调用来注册一个Miniport driver。
DriverObject:指向一个由系统创建的驱动对象
PUNICODE_STRING:指向注册表中该驱动参数的路径
该函数中首先调用NdisMInitializeWrapper函数来通知NDIS Library要注册一个Miniport。然后会初始化NDIS_MINIPORT_CHARACTERISTICS结构,所有的Miniport的相关接口函数都会赋值到NDIS_MINIPORT_CHARACTERISTICS结构中,最后调用NdisMRegisterMiniport来注册Miniport。
3.2 NDIS_STATUS MiniportInitialize(PNDIS_STATUS OpenErrorStatus, PUINT SelectedMediumIndex, PNDIS_MEDIUM MediumArray, UINT MediumArraySize,
NDIS_HANDLE MiniportAdapterHandle, NDIS_HANDLE WrapperConfigurationContext)
该函数用于初始化网卡。
OpenErrorStatus:额外的状态信息,一般不会被使用
SelectedMediumIndex:被选中的媒介类型的索引号,以太网一般是NdisMedium802_3
MediumArray:媒介类型数组,包含了不同类型的网络媒介
MediumArraySize:媒介类型数组大小
MiniportAdapterHandle:Miniport适配器句柄,该参数要被保存,以后调用Ndisxxx函数时会被用到。
WrapperConfigurationContext:一个封装配置句柄,会被NdisOpenConfiguration函数用到。
3.3 BOOLEAN MiniportCheckForHang(NDIS_HANDLE MiniportAdapterContext)
该函数检查硬件网卡的状态,该函数为Optional,也可以不去实现。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
3.4 VOID MiniportDisableInterrupt(NDIS_HANDLE MiniportAdapterContext)
该函数禁用网卡中断。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
3.5 VOID MiniportEnableInterrupt(NDIS_HANDLE MiniportAdapterContext)
该函数使能网卡中断。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
3.6 VOID MiniportHalt(NDIS_HANDLE MiniportAdapterContext)
该函数删除一个已被初始化的网卡。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
3.7 VOID MiniportHandleInterrupt(NDIS_HANDLE MiniportAdapterContext)
该函数为网卡的中断处理函数。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
3.8 VOID MiniportISR( PBOOLEAN InterruptRecognized, PBOOLEAN QueueMiniportHandleInterrupt, NDIS_HANDLE MiniportAdapterContext)
该函数为网卡的ISR函数,该函数中应做尽可能少的工作,大部分工作应该交给MiniportHandleInterrupt函数来完成。
InterruptRecognized:中断确认。如果确实是一个网卡中断,返回TURE。
QueueMiniportHandleInterrupt:如果需要MiniportHandleInterrupt函数处理,返回TRUE。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
3.9 NDIS_STATUS MiniportQueryInformation( NDIS_HANDLE MiniportAdapterContext, NDIS_OID Oid, PVOID InformationBuffer, ULONG InformationBufferLength, PULONG BytesWritten, PULONG BytesNeeded)
该函数为网卡信息查询函数,返回网卡状态等信息。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
Oid:网卡的OID信息码。
InformationBuffer:指向一个网卡信息Buffer,用于存放查询结构
InformationBufferLength:网卡信息Buffer的大小
BytesWritten:实际写入网卡信息buffer的字节数
BytesNeeded:如果网卡信息buffer不够大,返回还需要多大buffer长度
3.10 NDIS_STATUS MiniportReconfigure( PNDIS_STATUS OpenErrorStatus, NDIS_HANDLE MiniportAdapterContext, NDIS_HANDLE WrapperConfigurationContext)
该函数未被使用,不需要实现。
3.11 NDIS_STATUS MiniportReset(PBOOLEAN AddressingReset, NDIS_HANDLE MiniportAdapterContext)
该函数复位硬件网卡。
AddressingReset:返回TRUE表示需要重新设置地址信息,NDIS Library会调用MiniportSetInformation进行设置。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
3.12 VOID MiniportReturnPacket(NDIS_HANDLE MiniportAdapterContext, PNDIS_PACKET Packet)
该函数用于返回数据包描述符。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
Packet:指向一个数据包描述符
3.13 NDIS_STATUS MiniportSend(NDIS_HANDLE MiniportAdapterContext, PNDIS_PACKET Packet, UINT Flags)
该函数用于发送一个数据包。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
Packet:指向一个包描述符,该包描述符用于描述被发送的数据包
Flags:发送标记
3.14 VOID MiniportSendPackets(NDIS_HANDLE MiniportAdapterContext, PPNDIS_PACKET PacketArray, UINT NumberOfPackets)
该函数用于发送一组数据包
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
PacketArray:指向一组包描述符
NumberOfPackets:数据包的大小
3.15 NDIS_STATUS MiniportSetInformation(NDIS_HANDLE MiniportAdapterContext, NDIS_OID Oid, PVOID InformationBuffer, ULONG InformationBufferLength, PULONG BytesRead, PULONG BytesNeeded)
该函数用于设置网卡的信息
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
Oid:网卡的OID信息码
InformationBuffer:指向一个网卡信息Buffer
InformationBufferLength:网卡信息Buffer的大小
BytesRead:从信息Buffer中读了多少字节
BytesNeeded:还需要多少字节的Buffer
3.16 VOID MiniportShutdown(PVOID ShutdownContext)
该函数用于恢复硬件网卡为最初的状态。该函是为Optional,可以不实现。该函数不能调用NdisXXX函数。
ShutdownContext:指向一个区域,由NdisMRegisterAdapterShutdownHandler函数注册MiniportShutdown函数的时候提供。
3.17 NDIS_STATUS MiniportTransferData(PNDIS_PACKET Packet, PUINT BytesTransferred, NDIS_HANDLE MiniportAdapterContext, NDIS_HANDLE MiniportReceiveContext, UINT ByteOffset, UINT BytesToTransfer)
该函数用于拷贝接收到的数据包到指定的Buffer中
Packet:指向一个带有数据包描述符的数据Buffer
BytesTransferred:拷贝了多少个Bytes
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
MiniportReceiveContext:一个需要接收数据的网卡结构的句柄,描述哪块网卡的数据包要被接收
ByteOffset:要被拷贝数据在Buffer中的偏移量
BytesToTransfer:拷贝多少个Bytes
3.18 NDIS_STATUS MiniportWanSend(NDIS_HANDLE MiniportAdapterContext, NDIS_HANDLE NdisLinkHandle, PNDIS_WAN_PACKET WanPacket)
该函数用于在WAN卡上发送数据,如果硬件网卡是一块WAN卡,则不需要实现MiniportSend函数,而要实现该函数。
MiniportAdapterContext:一个指向网卡结构的句柄,该网卡结构在MiniportInitialize函数中被创建。
NdisLinkHandle:一个NDIS连接的句柄
WanPacket:指向一个NDIS_WAN_PACKET结构,该架构描述了要被传输的数据
以上是Miniport相关的接口函数,这里也只是做个简单的介绍,能让大家有个初步的了解。如果想了解更多,可以看一下微软提供的网卡驱动的源代码,如下:
” \WINCE600\PUBLIC\COMMON\OAK\DRIVERS\NETCARD\NE2000”