WindowsSocketWord下载.docx
《WindowsSocketWord下载.docx》由会员分享,可在线阅读,更多相关《WindowsSocketWord下载.docx(56页珍藏版)》请在冰豆网上搜索。
PacketDriver"
);
ULONGDevicesCreated=0;
PWSTRBindString;
PWSTRExportString;
PWSTRBindStringSave;
PWSTRExportStringSave;
WCHAR*bindT;
PKEY_VALUE_PARTIAL_INFORMATIONtcpBindingsP;
UNICODE_STRINGmacName;
//
//OldregistrybasedWinPcapnames
//
//UINTRegStrLen;
ULONGOsMajorVersion,OsMinorVersion;
TRACE_ENTER();
#ifndef__NPF_NT4__
TRACE_MESSAGE(PACKET_DEBUG_INIT,"
DriverEntry--NT4"
//
//GetOSversionandstoreitinaglobalvariable.
//ForthemomentweusethedeprecatedPsGetVersion()becausethesuggested
//RtlGetVersion()doesn'
tseemtoexistinWindows2000,andwedon'
twant
//tohavetwoseparateddriversjustforthiscall.
//Morever,theNT4versionofthedriverjustexcludesthis,sincethoseflags
//arenotavailable.
//Note:
bothRtlGetVersion()andPsGetVersion()aredocumentedtoalwaysreturnsuccess.
//OsVersion.dwOSVersionInfoSize=sizeof(OsVersion);
//RtlGetVersion(&
OsVersion);
PsGetVersion(&
OsMajorVersion,&
OsMinorVersion,NULL,NULL);
TRACE_MESSAGE2(PACKET_DEBUG_INIT,"
OSVersion:
%d.%d\n"
OsMajorVersion,OsMinorVersion);
//Definethecorrectflagtoskiptheloopbackpackets,accordingtotheOS
if((OsMajorVersion==5)&
&
(OsMinorVersion==0))
{
//Windows2000wantsbothNDIS_FLAGS_DONT_LOOPBACKandNDIS_FLAGS_SKIP_LOOPBACK
g_SendPacketFlags=NDIS_FLAGS_DONT_LOOPBACK|NDIS_FLAGS_SKIP_LOOPBACK_W2K;
}
else
//WindowsXP,2003andfollwingwantonlyNDIS_FLAGS_DONT_LOOPBACK
g_SendPacketFlags=NDIS_FLAGS_DONT_LOOPBACK;
#endif//__NPF_NT4__
//Settimestampgatheringmethodgettingitfromtheregistry
ReadTimeStampModeFromRegistry(RegistryPath);
TRACE_MESSAGE1(PACKET_DEBUG_INIT,"
%ws"
RegistryPath->
Buffer);
////
////Getthedevicenamesprefixfromtheregistry
//RegStrLen=sizeof(g_NPF_PrefixBuffer)/sizeof(g_NPF_PrefixBuffer[0]);
//NPF_QueryWinpcapRegistryString(NPF_DEVICES_PREFIX_REG_KEY_WC,
//g_NPF_PrefixBuffer,
//RegStrLen,
//NPF_DEVICE_NAMES_PREFIX_WIDECHAR);
NdisInitUnicodeString(&
g_NPF_Prefix,g_NPF_PrefixBuffer);
//GetnumberofCPUsandsaveit
g_NCpu=NdisSystemProcessorCount();
RtlZeroMemory(&
ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
//RegisterasaprotocolwithNDIS
#ifdefNDIS50
ProtocolChar.MajorNdisVersion=5;
#else
ProtocolChar.MajorNdisVersion=3;
#endif
ProtocolChar.MinorNdisVersion=0;
ProtocolChar.Reserved=0;
ProtocolChar.OpenAdapterCompleteHandler=NPF_OpenAdapterComplete;
ProtocolChar.CloseAdapterCompleteHandler=NPF_CloseAdapterComplete;
ProtocolChar.SendCompleteHandler=NPF_SendComplete;
ProtocolChar.TransferDataCompleteHandler=NPF_TransferDataComplete;
ProtocolChar.ResetCompleteHandler=NPF_ResetComplete;
ProtocolChar.RequestCompleteHandler=NPF_RequestComplete;
ProtocolChar.ReceiveHandler=NPF_tap;
ProtocolChar.ReceiveCompleteHandler=NPF_ReceiveComplete;
ProtocolChar.StatusHandler=NPF_Status;
ProtocolChar.StatusCompleteHandler=NPF_StatusComplete;
ProtocolChar.BindAdapterHandler=NPF_BindAdapter;
ProtocolChar.UnbindAdapterHandler=NPF_UnbindAdapter;
ProtocolChar.PnPEventHandler=NPF_PowerChange;
ProtocolChar.ReceivePacketHandler=NULL;
ProtocolChar.Name=ProtoName;
NdisRegisterProtocol(
&
Status,
g_NdisProtocolHandle,
ProtocolChar,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
if(Status!
=NDIS_STATUS_SUCCESS){
TRACE_MESSAGE(PACKET_DEBUG_INIT,"
FailedtoregisterprotocolwithNDIS"
TRACE_EXIT();
returnStatus;
//
//Standarddevicedriverentrypointsstuff.
DriverObject->
MajorFunction[IRP_MJ_CREATE]=NPF_Open;
MajorFunction[IRP_MJ_CLOSE]=NPF_Close;
MajorFunction[IRP_MJ_CLEANUP]=NPF_Cleanup;
MajorFunction[IRP_MJ_READ]=NPF_Read;
MajorFunction[IRP_MJ_WRITE]=NPF_Write;
MajorFunction[IRP_MJ_DEVICE_CONTROL]=NPF_IoControl;
DriverUnload=NPF_Unload;
bindP=getAdaptersList();
if(bindP==NULL)
TRACE_MESSAGE(PACKET_DEBUG_INIT,"
Adaptersnotfoundintheregistry,trytocopythebindingsofTCP-IP."
tcpBindingsP=getTcpBindings();
if(tcpBindingsP==NULL)
{
TRACE_MESSAGE(PACKET_DEBUG_INIT,"
TCP-IPnotfound,quitting."
gotoRegistryError;
}
bindP=(WCHAR*)tcpBindingsP;
bindT=(WCHAR*)(tcpBindingsP->
Data);
else
bindT=bindP;
for(;
*bindT!
=UNICODE_NULL;
bindT+=(macName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR))
RtlInitUnicodeString(&
macName,bindT);
NPF_CreateDevice(DriverObject,&
macName);
TRACE_EXIT();
returnSTATUS_SUCCESS;
RegistryError:
NdisDeregisterProtocol(
g_NdisProtocolHandle
);
Status=STATUS_UNSUCCESSFUL;
return(Status);
}
看NDIS的某个功能函数的实现
VOID
NPF_SendComplete(
INNDIS_HANDLEProtocolBindingContext,
INPNDIS_PACKETpPacket,
INNDIS_STATUSStatus
)
POPEN_INSTANCEOpen;
PMDLTmpMdl;
Open=(POPEN_INSTANCE)ProtocolBindingContext;
if(RESERVED(pPacket)->
FreeBufAfterWrite)
//
//PacketsentbyNPF_BufferedWrite()
//FreetheMDLassociatedwiththepacket
NdisUnchainBufferAtFront(pPacket,&
TmpMdl);
IoFreeMdl(TmpMdl);
//recylethepacket
//NdisReinitializePacket(pPacket);
NdisFreePacket(pPacket);
//Incrementthenumberofpendingsends
InterlockedDecrement(&
Open->
Multiple_Write_Counter);
NdisSetEvent(&
WriteEvent);
return;
//PacketsentbyNPF_Write()
ULONGstillPendingPackets=InterlockedDecrement(&
TransmitPendingPackets);
//Putthepacketbackonthefreelist
//ifthenumberofpacketssubmittedtoNdisSendandnotacknoledgedislessthanhalfthe
//packetsintheTXpool,wakeupanytransmitterwaitingforavailablepacketsintheTX
//packetpool
if(stillPendingPackets<
TRANSMIT_PACKETS/2)
NdisSetEvent(&
else
//
//otherwise,resettheevent,sothatwearesurethattheNPF_Writewilleventuallyblockto
//waitgforavailabilityofpacketsintheTXpacketpool
NdisResetEvent(&
if(stillPendingPackets==0)
NdisWriteCompleteEvent);
看看WINDOWSSOCKET功能如何堆叠出来的
miniport网卡对象
ndis用一个叫做逻辑网卡的软件对象来描述系统中的每块网卡,而逻辑网卡与windowsnt设备对象的通信由i/o子系统来管理,描述网卡的设备对象包括相关的网络信息如名字、网络地址和网卡内存基地址等,它还包含与硬件相关的驱动程序状态数据(捆绑数目,捆绑句柄,包过滤数据库等)。
ndis分配一个句柄到miniportinitialize这个上边缘函数的一个结构中,然后miniport网卡驱动程序将在以后提供这个句柄来给ndis调用,这个结构一直被ndis保持,并且对miniport驱动程序不透明。
当miniport网卡驱动程序初始化一块网卡时,它创立自己的内部数据结构来描述网卡,记录需要它管理的与设备相关的状态信息。
当miniport网卡驱动程序调用ndismsetatttibutes或ndismsetattributesex两ndis库函数时,它传递一个句柄给这数据结构。
这样,当调用miniport驱动程序入口点时,它就传递这个句柄来验证驱动程序所对应的网卡的正确性。
这个数据结构为miniport网卡驱动程序所拥有并维护。
网络对象标识符
miniportnic驱动程序还需要维护一组对象,这些对象是系统定义的对象标识符(objectidetifier:
oid)来标识,以描述驱动程序的性能和当前状态信息。
为查询这些信息,上层驱动程序调用ndisrequest向ndis接口库指示oid。
oid表示了调用所需的信息类型,如miniport驱动程序所支持的lookahead缓冲区大小等。
ndis接到上层驱动程序的查询请求,将oid传递给上边缘函数miniportqueryinformation实现对oid的查询,如果上层驱动程序请求改变状态信息则调用miniportsetinformation实现对oid的设置。
miniport网卡驱动程序代码
典型的miniportnic驱动程序必须有一些函数来通过ndis接口实现上层驱动程序与硬件的通信。
这些函数称为上边缘服务函数。
这些上边缘服务函数由驱动程序的开发者根据驱动程序面向的特定低层网络类型和硬件以及相应环境,可以有选择地实现,但必须保证驱动程序最基本的功能,这些基本功能包括初始化、发送、中断处理、重置、参数查询与设置和报文接收。
miniportinitialize:
操作系统根据系统配置信息,检测出网卡已安装时,由ndis接口在初始化时调用,主要完成低层网络类型确定,对应于物理网卡的逻辑网卡初始化,中断信息注册,网卡与主机通讯方式的确认。
i/o端口的申请与注册,内存映像,mib的初始化,物理网卡的验证与初始化等。
miniportreconfigure:
支持网卡参数动态变化,和miniportinitilize一样由ndis接口以初始化级别调度执行(不能屏蔽中断,必须由驱动程序承认并清除在此期间产生的中断),支持即插即用和软配置的网卡在动态改变参数时,必须提供此函数。
miniportqueryinformation:
查询网卡的状态以及网卡驱动程序的操作或统计参数,如是否支持组通讯、网卡的物理速率是否支持回环、是否支持直接拷贝等,这些参数以oid方式统一管理。
miniportsetinformation:
ndis接口或协议驱动程序通过调用此接口改变驱动程序维护的oid库,一些操作参数的改变也将同时改变驱动程序状态,例如组地址的设置。
miniportreset:
包括网卡硬件重置和驱动程序软件重置,软件重置包括驱动程序状态重置,以及一些相关的参数重置,还需考虑有些参数的恢复,重置时不必完成所有正在活跃的外部请求,但必须释放已占用的外部资源。
miniporthalt:
挂起网卡并释放该网卡驱动程序占用的所有资源,在此期间不屏蔽中断。
miniportisr:
高优先级的中断处理程序,进行的工作包括初始中断处理类型,决定是否进行中断转交,对卡上中断进行处理等,该服务类型只在以下情况被调用:
ndis接口调用miniportinitialize和miniporthalt两函数时。
.中断处理类型设为每此中断处理过程都调用时。
为使系统能及时响应所有硬件中断,高优先级的硬件中断处理程序应尽可能的减少运行时间,防止长时间的屏蔽低优先级中断,避免造程中断丢失。
miniporthandleinterrupt:
由中断延时处理程序在中断延时处理时进行调用。
ndis排队所有的延时处理,该服务主要处理发送完成、报文接收、描述符用尽、溢出、网卡异常等中断。
miniportsend:
ndis收到上层发送请求时经过若干协议处理再向下调用此服务过程,发送的packet已含有llc和mac头,该服务过程进行边界对齐、packet约束重整、描述符映射和报文发送、以及发送资源和packet缓冲队列管理。
miniporttransferdata:
多个已和网卡捆绑的协议驱动程序在接收到报文到达指示后,向网卡驱动程序发出传送请求以拷贝各自所需的报文数据部分,网卡驱动程序根据各协议驱动程序对单个packet是否进行多次拷贝,以决定是否暂存只允许单次拷贝的packet等。
miniportcheckhandle:
ndis每秒调用此服务函数一次,驱动程序发现网卡异常时报告给ndis由ndis调用miniportreset进行硬件重恢复。
miniportenableintrrupt:
中断使能。
miniportdisableinterrupt:
中断屏蔽。
另外,每个网卡驱动程序必须有一个初始化入口点,由driverentry函数实现,它和系统相关,由操作系统在装入驱动程序时调用,主要完成初始化ndiswrapper,再由wrapper初始生成驱